Shared join module for transport pieces; belt drawing uses it (t67 phase 1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 13:00:43 -04:00
co-authored by Claude Opus 5.5
parent 787721ad35
commit 65338b2b27
11 changed files with 274 additions and 38 deletions
+10 -5
View File
@@ -486,11 +486,16 @@ above, including:
on warns first that the save will be marked, and the mark stays with the world; any future
achievements won't unlock in a marked world. Besides money, items and upgrades it may have
game speed and other things just for fun.
- **Screw conveyors only join a diagonal on the same row (t62, 2026-10-27).** A straight screw
joins a diagonal when it sits right beside the diagonal's end block, and that join is drawn
as an elbow. When the diagonal instead starts one block lower or higher, so the two only touch
corner to corner, they stay two separate ends and nothing passes between them. The owner tried
a corner join and found it looked odd, and building it that way is unusual anyway.
- **One join rule for every transport piece (2026-10-27, replaces the t62 same-row rule).** The
owner wants all pieces to place and join the same way, so players know what to expect when
building. At a diagonal piece's end, call E the block diagonally past its last block (the
block its end points into). Another diagonal of the same slope continues in E. A horizontal
piece (flat belt, flat filter, horizontal screw) joins on the same row at the high end, and
in E, one block lower, at the low end: the rule sloped belts already had. A vertical screw
joins in E at either end. Straight pieces join the next block along their axis. Any other
placement is two separate ends and nothing passes between them. The owner found the old
screw rule, which needed the horizontal placed over the diagonal's last block at the low
end, inconsistent with every other piece.
## Ideas not built yet
+15 -2
View File
@@ -118,6 +118,13 @@ dist/, shots/ build output and screenshots (not committed)
- kind `mold`.
`hidden` pieces are not in the menu. The menu's tabs and order are `BUILD_CATS` in
`src/ui/build-menu.js`.
- **Transport geometry:** `joins.js` owns geometric ends and joins for belts, filters and screws.
`pieceEnds(code, v)` returns precomputed left/right ends (vertical screws: up/down).
`endJoin(bx, by, endIndex, planned = null)` returns `neighbourBlock * 2 + neighbourEnd`,
or -1; `pieceJoins(bx, by, planned = null)` returns bits 0/1 for the joined ends.
Plans override world blocks, including the queried block. Continuing diagonals take priority
over elbows; a join is returned only when both ends choose each other. Belt drawing uses
this module; screw drawing and movement still use their existing rules.
- **Placing and removing:**
- `placeBlock` / `removeBlock` (`blocks.js`);
- `placeMachineAt` / `addMachine` / `removeMachine` (`actions.js`, `machines.js`);
@@ -265,6 +272,11 @@ Pipes, pumps and outlets: each joined line holds one liquid as a count, not as g
Per-tick machine work: steam engines, fans, belts, filters, screw conveyors (machinesTick).
- functions: engineIntake, fanBlow, machinesTick
### src/sim/joins.js (71 lines)
Geometric transport ends. Tables are built once; querying a world or plan allocates nothing. Ends are left/right, except vertical screws (up/down). Travel direction is irrelevant.
- functions: pieceEnds, joinCandidate, endJoin, pieceJoins
- variables: JOIN_ENDS
### src/sim/conveyors.js (198 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
@@ -362,7 +374,7 @@ Drawing (src/render/): browser only. This file: the renderer state R, colour tab
Propagated coloured light from glowing and burning cells.
- functions: builtForLight, looseForLight, computeLight
### src/render/slope-belts.js (176 lines)
### src/render/slope-belts.js (157 lines)
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
@@ -372,7 +384,7 @@ Screw casing geometry shared by both looks, ghosts and placement previews. smoot
- functions: diagonalScrewJoins, diagonalScrewShape, diagonalScrewBlock
- variables: SCREW_CLASS, diagonalJoins, diagonalAcross, diagonalAlong, diagonalCap
### src/render/world.js (402 lines)
### src/render/world.js (403 lines)
Scale colour without changing the smooth-look class.
- functions: fogColor, drawWorld
@@ -530,6 +542,7 @@ The frame loop and boot.
- `test/t_econ.js`: Economy: the dock (instant sale), orders, prices, the market dip, money for machines, alloys.
- `test/t_fog.js`: Fog: surface, sight, range, saves and simulation independence.
- `test/t_furnace_repeat.js`: The starter furnaces keep working when fired again and again without cleaning, however the charge goes in: mixed, ore first with coal on top, or blown in through the vent. Each case plays furnace_play.js, which builds the design and fires it like a player.
- `test/t_joins.js`: The oracle states the geometric rule independently of the precomputed neighbour tables.
- `test/t_light.js`: Run the renderer's lighting against real simulation data, with only canvas storage stubbed.
- `test/t_load.js`: Reload wakes nearby areas first, without losing distant water, fire or saved state.
- `test/t_molds.js`: Molds and furnaces stay usable: ingots drop below and keep their stubs, plugs over molds are cleared, spoiled castings can be knocked out, grains never drop through a grate by teleporting, and slag lets the fire breathe.
+16
View File
@@ -4,6 +4,22 @@ 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-27: t67 phase 1, shared join module (Claude Code + Codex)
- Owner decision (DESIGN.md, replaces the t62 same-row rule): one join rule for every transport
piece. New DOM-free `src/sim/joins.js`: `pieceEnds`, `endJoin`, `pieceJoins`; rule tables are
compiled once and joins must be mutual. Belt drawing now uses it: `slopeBeltConnections`,
`flatBeltCaps` (now also for ghosts), and the pixel filter frame (`beltLike(b, end)`). Sloped
belt drag previews now pass a planned map.
- Deliberate drawing changes where the old belt rules disagreed: flat belt caps no longer
treat any same-row diagonal screw as joined, and filter frames open only at a real join.
- Files: `src/sim/joins.js`, `src/manifest.json`, `src/render/slope-belts.js`,
`src/render/setup.js`, `src/render/world.js`, `src/ui/previews.js`, `test/t_joins.js`,
`test/t_slope_belt_art.js`, `docs/PROJECT_MAP.md`, `docs/DESIGN.md`.
- Tests: `python3 test/run_all.py --browser` all passed; t_joins checks 4,232 placements,
symmetry, planned maps, and that belt sand flow agrees with the rule. Sim output unchanged.
- Open: screws still use their old rules until phase 2.
## 2026-10-27: t62 corner placements stay separate (Claude Code + Codex)
- Owner tried the corner join and found the jog odd; decision (recorded in DESIGN.md): only