Cleats really hold and push their pockets (t42 feedback)

Nothing carries the load on a slope but the ribs: each belt step every
rib moves one face cell and pushes the grains in its way, the layer on
the belt is only dragged by friction that gravity beats on 45 degrees,
and heaped grains roll back. Ribs never pass through grains or into
machines; a run that can't push stalls. The foot of an uphill run
scoops the feed into pockets. Ribs drawn as rubber bars in both looks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 20:56:51 -04:00
co-authored by Claude Opus 5.5
parent 3ee85429fd
commit 8cdc47fd33
12 changed files with 276 additions and 52 deletions
+14 -1
View File
@@ -417,7 +417,7 @@ above, including:
only loaded screens shake. Empty moving cleats must let chunks sleep. Keep pocket transport,
uphill throughput near 71 grains/s and exact sorting unchanged.
- **Sidewall belts with moving cleats (t42, 2026-10-26).** To replace the old full-column
- **Sidewall belts with moving cleats (t42, 2026-10-26; physics replaced by the entry below).** To replace the old full-column
grip, use moving barrier lines rather than material cells: the barrier mask blocks normal
powder movement without overwriting grains, terrain or parts. Cleats stand perpendicular
to the face, spaced 8 horizontal face cells apart and 6 grains tall (integer normal reach
@@ -449,6 +449,19 @@ above, including:
belt and the animation stopped on everything affected, and belts limited to a realistic
load depth instead of carrying 96-grain stacks. Not built yet.
- **Cleats really push their pockets (t42 feedback, 2026-10-26).** The owner found the first
cleats passed through heavy loads while the material climbed as before, and wants cleats that
hold the material and drag it up. Now nothing carries the load on a slope but the ribs and a
friction drag on the layer touching the belt (which gravity beats on 45°, so loose grains slide
back until a rib holds them). Each belt step every rib moves one face cell and pushes the
grains in its way ahead of it; whatever is heaped above the rib is left to roll back. A rib
never moves into a grain, never crosses a machine, and stops short of anything built. If any
rib of a run can't push its way, the whole run stalls that step and every move is undone (the
stall t45 will show). At the foot of an uphill run, each rib coming up around the end roller
scoops what lies on the feeding belt behind it into its pocket, like a real boot section.
Measured: about 80-86 grains/s uphill under a heavy feed (flat 90); downhill about 38, since
the top only feeds a layer two grains deep onto the face.
## Ideas not built yet
- **Concrete**, as a stronger wall material from rubble.
+9 -8
View File
@@ -260,19 +260,19 @@ Pipes, pumps and outlets: each joined line holds one liquid as a count, not as g
- functions: sideOf, pipeClosedSide, pipeJoins, rebuildPipes, pipeNetOf, pipeTakeShare, faceCell, pumpDraw, outletPour, pipesTick
- variables: PIPE_CAP, PUMP_RATE, OUTLET_RATE, PUMP_MAX_T, SIDE_V, PUMP_V, OUTLET_V, pipeNets, pipeNetAt, pipesDirty
### src/sim/machine-tick.js (155 lines)
### src/sim/machine-tick.js (156 lines)
Per-tick machine work: steam engines, fans, belts, filters, screw conveyors (machinesTick).
- functions: engineIntake, fanBlow, machinesTick
### src/sim/conveyors.js (197 lines)
### src/sim/conveyors.js (193 lines)
How belts, filters and screw conveyors move what is on or in them. What rests on a belt or filter rides along: the whole stack standing on the carrying surface steps one cell toward d together (belts run front of the line first, so the way ahead is clear). If a powder grain is blocked, the load above it stands still and the belt slips underneath. A filter's own material drops through it instead, unless it is already full.
- functions: conveyorStep, carryColumn, beltDrain, launchGrain, rebuildFilters, filterCarry, carryBeltsAndFilters, setFilter, filterRun, roomFor, screwSpread, screwIntake, diagonalScrewNext
- variables: CARRY_DEPTH, filterR, filterL, filtersDirty
### src/sim/slope-conveyors.js (66 lines)
Cleats are moving barriers, not material cells. A cleat supports a finite pocket; the bare face never holds grains.
- functions: cleatFoot, pocketDepth, slopeCleatsTick, screenNudge, wakeCleatLoad
- variables: CLEAT_SPACING, CLEAT_HEIGHT, CLEAT_REACH, SCREEN_NUDGE_TICKS, cleatCarrying, cleatChunks, cleatMask, cleatCells, slopePhase
### src/sim/slope-conveyors.js (220 lines)
Cleats are rubber ribs standing up from a sloped belt's face, one every CLEAT_SPACING face cells. Loose grains treat them as solid (cleatMask). Nothing grips the bare face: grains slide down it until a cleat stops them. Each belt step moves every cleat one face cell along the belt, and the rib pushes whatever is in its way ahead of it, so the pocket in front rides along while anything heaped above the rib is left to roll back. If a rib can't push its way, its whole run stalls.
- functions: ribMove, cleatFoot, ribCells, slopeFaceAt, pushRow, scoop, pocketRoom, advanceCleat, slopeRunKey, slopeCleatsTick, rebuildCleatMask, expelFromRib, screenNudge, wakeCleatLoad
- variables: CLEAT_SPACING, CLEAT_HEIGHT, CLEAT_REACH, SCREEN_NUDGE_TICKS, cleatChunks, cleatMask, cleatCells, slopePhase, ribLog
### src/sim/blocks.js (219 lines)
Building blocks: placing, integrity, removing, lines and rectangles of blocks.
@@ -366,7 +366,7 @@ Drawing only: the face stays on its simulation cells; the band hangs below it.
- functions: slopeBeltConnections, flatBeltCaps, prepareSlopeBelts, slopeBeltSegment, slopeBeltCorner, slopeBeltShape, slopeBeltAt, slopeBeltColor, screenLoaded, slopeWallShape, slopeWallAt, slopeDetailAt, slopePreviewCleat
- variables: slopeBeltJoins, slopeBeltHalo, beltCaps, slopeAcross, slopeAlong, slopeDistance, slopeWallOwner
### src/render/world.js (456 lines)
### src/render/world.js (458 lines)
Scale colour without changing the smooth-look class.
- functions: fogColor, diagonalScrewJoins, diagonalScrewShape, diagonalScrewBlock, drawWorld
- variables: SCREW_CLASS, diagonalJoins, diagonalAcross, diagonalAlong, diagonalCap
@@ -384,7 +384,7 @@ Smooth look: WebGL setup, texture uploads, drawing and adaptive resolution.
- functions: smCompile, smoothAvailable, smUpload, smoothDraw, smoothPace
- variables: SM, smBytes
### src/render/slope-belt-shader.js (99 lines)
### src/render/slope-belt-shader.js (109 lines)
Smooth slope shading, kept beside the shared CPU geometry in slope-belts.js.
- variables: SM_SLOPE_HELPERS, SM_SLOPE_DRAW
@@ -566,6 +566,7 @@ The frame loop and boot.
- `tools/scenes/silo.js`: Run after clear-sky.js; leave paused so the open gate keeps its demonstration charge.
- `tools/scenes/slope-conveyors.js`: Loaded sidewall conveyor and screen. Use --js 'slopeScene(false)' (belt) or 'slopeScene(true)' (screen).
- `tools/scenes/stone-uses.js`: The stone and sand machines: a half-full silo with its gate open over a belt, a stone cutter fed with rubble, and cut stone and glass brick walls. Run clear-sky.js first, e.g. python3 tools/shot.py /tmp/stone.png --setup tools/scenes/clear-sky.js --js "$(cat tools/scenes/stone-uses.js)" --ticks 240 --zoom 7
- `tools/scenes/t-screen-joint.js`: Downhill screen whose outlet belt sits level with its last block (the jam the owner saw).
- `tools/scenes/t33-ground.js`: Paused dug pocket: copper ore, rubble and dirt against stone, granite and dirt. Use --js "..." to set daylight or R.lens after this setup; CAM frames the pocket.
- `tools/scenes/t35-diagonal.js`: Run after clear-sky.js: a belt takes sand from a pile, up a diagonal screw to an upper belt.
- `tools/scenes/t35-joins.js`: Run after clear-sky.js. Paused, empty pipes make casing, flights and mouths easy to inspect.
+18
View File
@@ -4,6 +4,24 @@ What agents have done, newest first. Add an entry for every piece of work: the d
note or request it was for, what changed, the files touched, the tests run, and anything left
open or not verified. Keep each entry short; the git history has the details.
## 2026-10-26: t42 feedback: cleats that really hold and push their load (Claude Code)
- The owner saw ribs pass through heavy loads and the load climb as before. Rewrote the slope
physics in `src/sim/slope-conveyors.js`: no column carry on slopes; each step every rib moves
one face cell and pushes the rows of grains in its way (`pushRow`, front first, never between
two rib cells or into a machine); a contact-layer friction drag that gravity beats on 45°;
a boot-section scoop at the foot of uphill runs; a run stalls (all its moves undone) if a rib
can't push; grains under a newly placed rib are lifted out. Ribs stop short of built cells.
Slopes now step before flat belts (`machine-tick.js`), so a feeding belt finds the room.
- Drawing: ribs drawn by the smooth wall shader at the simulation phase (rubber bars with a
light cap); pixel ribs lighter with a cap; far wall a little lighter (`render/world.js`,
`slope-belt-shader.js`, `slope-belts.js`).
- Rates: uphill 78.7 (suite) to 86 grains/s (heavy probe), downhill 38, flat 90. Perf: 576
loaded slopes 1.03 ms/tick; 50 slopes in a generated world 2.19 vs 1.83 ms/tick without.
- Tests: `t_slope_belts.js` adds "no grain ever inside a rib under heavy feed", "a grain on the
bare face slides back to a rib, then rides up with it"; downhill rate floor lowered to 30.
`python3 test/run_all.py --browser`: ALL PASSED. Open: downhill rate; t58 (low-end joins).
## 2026-10-26: t42/t43 drawing and performance follow-up (Codex)
- Filled the far sidewall down to the belt, behind grains, with two-tone pixel corrugation