Resting faces steeper than the angle of repose topple: blown sand towers collapse (t93)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 23:07:30 -04:00
co-authored by Claude Opus 5.5
parent 84dd8b8d0a
commit bd22e453ca
10 changed files with 264 additions and 24 deletions
+15
View File
@@ -570,6 +570,21 @@ above, including:
Resting heaps do not enter this path; world generation keeps its recorded settling rules
and seed layouts.
- **Nozzle-built sand towers topple from rest (t93 round 3, 2026-10-28).** The owner
reproduced vertical sand towers by continuously blowing straight up. Landing places grains
at or above impact; supported face grains need to release before the outer falling column
clears. A tall body now spills from a supported exposed face as well as a falling one.
Apply this to free-flowing powders (STICK=1); cohesive grains retain their stickier release
and do not inherit the outward motion. Require an open side and a steep drop, backed eight grains inward by a continuous column
at least 32 grains high (look at most 24 rows each way). This leaves short feeds and the
deliberately steeper small clay heaps on their existing settling rules. The spill is still
bounded to eight grains horizontally and vertically, checking every crossed cell.
Two cell flag bits retain the collapse direction while the released grain falls: up to two
grains outward and eight down per tick. Removing support passes that direction to the grain
immediately above, so the falling layer drains promptly. Contact below cancels this motion;
ordinary repose rules take over. Keep stamped moves, barriers, burning-bed protection and
worker independence. The existing worldgen POWDER_FAN switch disables new face releases.
## Ideas not built yet
- **Concrete**, as a stronger wall material from rubble.
+7 -4
View File
@@ -225,9 +225,9 @@ Material definitions: ids, properties and metal families. ids, and drill/tank ti
- functions: def, metalFamily
- variables: EMPTY, GRASS, DIRT, LDIRT, SAND, GRAVEL, CLAY, STONE, GRANITE, BASALT, NMAT, MD, FIRETO
### src/sim/material-tables.js (54 lines)
### src/sim/material-tables.js (55 lines)
Material tables: typed properties, casting groups, flags, parts and tool tiers. Typed property tables
- variables: PH, DENS, KC, ICAP, CASTMETAL, METAL_TIER, SOLIDMETAL, F_NAT, F_CAST, F_BURN, P_NONE, P_SCREW_U, P_SCREW_D, P_SCREW_L, P_SCREW_R, P_GRATE, P_GOPEN, P_WHEEL, P_INTAKE, P_FILTER, P_PIPE, P_SCREW_UR, P_SCREW_DR, P_SCREW_DL, P_SCREW_UL, SCREW_PARTS, SCREW_DIRS, IS_SCREW, SCREW_DX, SCREW_DY, BIT_TIERS, TANK_TIERS, REACH
- variables: PH, DENS, KC, ICAP, CASTMETAL, METAL_TIER, SOLIDMETAL, F_NAT, F_CAST, F_BURN, F_AVALANCHE, F_AVALANCHE_R, P_NONE, P_SCREW_U, P_SCREW_D, P_SCREW_L, P_SCREW_R, P_GRATE, P_GOPEN, P_WHEEL, P_INTAKE, P_FILTER, P_PIPE, P_SCREW_UR, P_SCREW_DR, P_SCREW_DL, P_SCREW_UL, SCREW_PARTS, SCREW_DIRS, IS_SCREW, SCREW_DX, SCREW_DY, BIT_TIERS, TANK_TIERS, REACH
### src/sim/pieces.js (179 lines)
Everything the player can build (PIECES): blocks, machines and molds, with costs and descriptions; filter settings; wall materials and their cost.
@@ -254,9 +254,9 @@ Exploration only: never changes grains or the random stream.
- functions: fogAlloc, fogMark, fogSeen, fogInit, fogLook, fogRevealAround, fogRevealAll
- variables: FOG, FOG_SENSE, FOG_SENSE_FADE, fog, FW, FH
### src/sim/cells.js (272 lines)
### src/sim/cells.js (321 lines)
Cell helpers (setCell, move, enter) and the falling-sand movement of powders, liquids and gases (simMove).
- functions: setCell, swapCells, swapCellData, move, enter, enterFree, powder, passable, liquid, liquidSearch, gas, wakeBotPowder, simMove, moveChunk
- functions: setCell, swapCells, swapCellData, move, enter, enterFree, powderSpill, avalancheMove, powder, passable, liquid, liquidSearch, gas, wakeBotPowder, simMove, moveChunk
- variables: SORTP, SORTP_FUEL, LSTEP, LFILM, CORNER_SEAL, POWDER_FAN
### src/sim/heat.js (266 lines)
@@ -630,11 +630,14 @@ The frame loop and boot.
- `test/harness.js`: Loads the simulation (the src/sim/ files listed in src/manifest.json, joined in order into one script, the same way build.py joins them) so scenarios can drive it headlessly in Node. Errors point at the real file and line (sim/pipes.js:42), not at the joined script.
- `test/light-cases.js`: Lighting behaviour checks executed by the GPU browser harness.
- `test/light-readback.js`: Read float source channels, including transmittance, from the WGSL light pass.
- `test/pile-blow.js`: Shared reproduction: continuously blow plain bagged sand straight above a stationary bot.
- `test/pile-cut.js`: Shared Node/browser reproduction: vacuum the foot of settled 60-grain heaps, one stroke per tick.
- `test/play.py`: Play-test in a real browser: mouse, keyboard and a mocked gamepad drive the game; save and continue. Screenshots go to shots/play/ (or the folder given as the first argument). Pixel look unless the second argument is 'smooth'.
- `test/run_all.py`: Run the test suites and report.
- `test/t_bar_stacking.js`: Resting bars snap into pairs of grains and tip off narrow supports.
- `test/t_basics.js`: Basics: drilling to rubble, the vacuum and blowing, walls, the ingot mold and bars, belts, blueprints, save/load.
- `test/t_blow_collapse.js`: Owner's upward nozzle recipe, inline and with real shared-memory helpers.
- `test/t_blow_collapse.py`: Straight-up bagged sand nozzle in the real pixel frame loop.
- `test/t_build.js`: Building: undo (Ctrl+Z), cut, replace a machine with Ctrl, pasting ghosts, and the fan heat warning.
- `test/t_caps.py`: Capability detection, title notices and the required-WebGPU startup gate.
- `test/t_conveyors.js`: Screw conveyors that never carry liquid (it flows through), screw and belt throughput, filters.
+7
View File
@@ -86,6 +86,13 @@ checks waking within eight ticks separately from the probabilistic consumption o
bot-near/far, grain conservation, equal material bytes and forced-awake resting stability.
It also checks a broad 120-grain wall within 600 ticks and a spill stopped by cleats
across chunk edges, where the source chunk's one-grain barrier flag is clear.
- `test/t_blow_collapse.py` continuously blows bagged sand straight above a stationary bot
at nozzle radius 6 for 1200 real frame-loop ticks, then checks the pile after 480 idle
ticks with actual helper dispatch. Pixel captures are `shots/t93c-before.png` and
`shots/t93c-after.png`. `test/t_blow_collapse.js` repeats the recipe inline and with
1/2/8 Node helpers, compares material and motion flags, conserves all bag/flying/landed
sand, and forces visits to check resting stability. It also directly checks a supported
face releasing immediately and a spill stopped by a cleat across a chunk boundary.
- `test/t_smooth.py` checks WebGPU smooth shapes, seams, joins, fog and the thermal lens.
- `test/t_gpu_golden.py` compares 28 cropped frozen reference PNGs (384x288, under
`test/fixtures/golden/`) against WebGPU: renderer, joins, sky and four light scenes,
+45
View File
@@ -6,6 +6,51 @@ open or not verified. Keep each entry short; the git history has the details.
## 2026-10-28: t93 round 3, nozzle-built resting sand faces (Codex)
- Reproduced the owner's continuous straight-up radius-6 sand nozzle recipe, not a
vacuum cut: 1200 toolBlow ticks under open sky. Matching original-code Node and real
pixel frame-loop browser controls fail the new regression. Browser, NVIDIA RTX 5070,
two active helpers: 79-grain cliff at blow end, still 61 after 480 idle ticks. Active
chunks remain; neither sticky rolls (sand already has STICK=1) nor missing wakes explain it.
- Cause: landFlyer/depositNear stack grains at or above impact, while supported exposed
grains only slide a single diagonal cell. The earlier fan rule requires empty space below
and misses the resting face. Simply extending the initial spill leaves the falling layer
blocking further release. Tall bodies now release from rest and carry a bounded outward
fall through the newly unsupported column; contact below cancels that motion. Cohesive
grains retain their existing release and do not inherit it. A continuous 32-grain backing
column eight grains inward distinguishes towers from short feeds. Read reach <=24,
write reach <=8, no per-grain allocation, existing worldgen switch retained.
- New shared nozzle fixture and headless/browser regressions cover the actual tool, direct
supported-face release, cross-chunk cleats, conservation, 0/1/2/8 helpers, exact material
and motion-flag bytes, and forced-awake stability. Larger equal-mass clay/sand check:
7200 grains, final heights 90/75. Rejected broad release and persistent motion on contact
experiments after they changed small heaps, clay or transport checks; no old test weakened.
- Final headless suite passes. Served pixel browser nozzle check passes at exactly 480 idle
ticks: cliff 32 -> 1, all 40000 grains retained in bag/flight/pile, final pile sleeps.
Saved and inspected shots/t93c-before.png and shots/t93c-after.png; matching old-rule
captures are shots/t93c-control-{before,after}.png. Final full
python3 test/run_all.py --browser: ALL PASSED, 35 headless and 10 browser suites,
including nozzle 25, collapse 17, vacuum 44, threads 12, gameplay 361, both browser
collapse regressions, original worldgen hashes and liquids. Log: /tmp/t93c-all-browser.log.
Ticked round-3 feedback with a report and moved t93 to Review. Owner playtesting
remains open. No commit.
- Isolated real-GPU requested profile, no concurrent tests: original-code control -> final
total ms/tick: settled 1.9359 -> 1.9413 (+0.3%), heat 2.6679 -> 2.7080 (+1.5%).
Versus historical tools/perf-after-t88.json: +7.5%/+3.2%; the control already measures
+7.2%/+1.7%. Awake counts match (425/494). Movement ms/tick 0.9520 -> 0.9570 and
1.3460 -> 1.3850; unchanged heat work 0.9060 -> 0.9067 and 1.2425 -> 1.2424.
Logs/JSON: /tmp/t93c-perf-{control,final}.{log,json}. Some real-loop frame-tail timings
are noisier and exceed the profiler's 10% marker; the requested isolated simulation
tick averages are within a few percent of the matching control.
- Files: src/sim/cells.js, src/sim/material-tables.js, test/pile-blow.js,
test/t_blow_collapse.{js,py}, test/run_all.py, docs/DESIGN.md, docs/TESTING.md,
regenerated docs/PROJECT_MAP.md, t93 task and this log. Further evidence:
/tmp/t93c-red.log, /tmp/t93c-browser-red.log, /tmp/t93c-browser-final.log,
/tmp/t93c-final-headless2.log.
## 2026-10-28: t93 reopened, vacuum-cut faces drain in columns (Codex)
- Read AGENTS, the t93 task/log and 807217b; inspected both new owner screenshots.