One rule for a piece's direction variant: remove pieceV (t81)

This commit is contained in:
2026-10-29 21:53:56 -04:00
parent daeb3b2238
commit 78eeb86171
4 changed files with 49 additions and 4 deletions
+1
View File
@@ -671,6 +671,7 @@ The frame loop and boot.
- `test/t_nozzle.js`: Blowing aims within the nozzle's reach, with room for the brush and settling.
- `test/t_perf.js`: Profiling fixtures start in the same state after previous scenes and warm-up ticks.
- `test/t_physics.js`: Sand and other powders, molten metal and gases: heaps, sorting, sinking, setting, rising and fading. Water has its own suite (t_water.js). Tall worlds keep geothermal heat out of the way.
- `test/t_piece_variants.js`: The build plan and direct variant queries share one direction/material rule.
- `test/t_pile_collapse.js`: Tall loose faces release together; supported heaps stop moving, including when revisited.
- `test/t_pipes.js`: Pipes, pumps and outlets move liquids; the Grinder grinds waste rock for trace ore.
- `test/t_racks.js`: Rack intake, FIFO storage, gate, removal and saved-state validation.
+11
View File
@@ -4,6 +4,17 @@ 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-29: t81 shared piece direction variants (Codex)
- `pieceV` accepts a direction and resolved code; `dragPlan` calls it for previews and
placement. Default queries keep the selected direction. No world generation changes.
- Files: src/ui/selection.js, test/t_piece_variants.js, docs/PROJECT_MAP.md, tasks/t81*.
- New checks: 29 failures before, all 72 pass after. All 41 headless suites pass;
all 40 existing suite outputs match before/after, ignoring timing lines (empty
/tmp/t81-determinism.diff). Pixel test/play.py passes with no console errors; inspected
shots/t81-play/04-{blocks,diagonal-screws}.png. Sandbox WebGPU was unavailable;
host GPU rerun passed. Nothing left open; t81 ready for owner review.
## 2026-10-29: t96 rebuilt: lakes are bowls filled to their spill level (Claude)
- Owner: the round-4 bank was a flat, unnatural ramp; fix lake generation properly instead of
+4 -4
View File
@@ -82,16 +82,16 @@ function setBrush(d) {
}
// The block variant a piece is placed with: wall material, or direction (a filter's
// materials and mode travel separately, as GAME.filterCfg)
function pieceV(P) {
function pieceV(P, dir = GAME.pieceDir[P.id] || 0, code = pieceCode(P)) {
if (isWall(P.code)) return GAME.wallMat;
if (P.filter) return filterVariant(pieceCode(P), (GAME.pieceDir[P.id] || 0) << 7);
return GAME.pieceDir[P.id] || 0;
if (P.filter) return filterVariant(code, dir << 7);
return dir;
}
// One drag for the build tool and its preview: code, direction, variant, blocks, and the planned
// blocks the join rule sees. A line that joins one block up or down snaps there (joinSnap).
function dragPlan(P, a, b, shift) {
const code = pieceCode(P, b), dd = a ? dragDirFor(P, a, b) : -1, dir = dd >= 0 ? dd : (GAME.pieceDir[P.id] || 0);
const v = isWall(P.code) ? GAME.wallMat : P.filter ? filterVariant(code, dir << 7) : dir;
const v = pieceV(P, dir, code);
let cells = !a ? [[b.bx, b.by]] : shift && !lineOnly(code) ? blockRect(a.bx, a.by, b.bx, b.by)
: blockLine(a.bx, a.by, b.bx, b.by, isWall(code) || isSlopeBelt(code) || code === BP_SCREW);
const snap = lineOnly(code) ? joinSnap(code, v, cells) : 0;
+33
View File
@@ -0,0 +1,33 @@
// The build plan and direct variant queries share one direction/material rule.
const { load, suite, flatWorld } = require('./harness');
const fs = require('fs');
const { run } = load(), { check, done } = suite();
flatWorld(run, 256, 224, 208);
run(fs.readFileSync('src/ui/selection.js', 'utf8'));
run(fs.readFileSync('src/ui/actions.js', 'utf8'));
run(`globalThis.GAME = { pieceDir: {}, pieceShape: {}, wallMat: RSTONE };
globalThis.aimBlock = () => ({ bx: 20, by: 20 });`);
for (const id of ['wall', 'belt', 'filter', 'screw', 'gate', 'pump']) {
const dirs = run(`PIECE_BY_ID.${id}.dirs?.length || 1`);
for (let dir = 0; dir < dirs; dir++) {
run(`GAME.pieceDir.${id} = ${(dir + 1) % dirs};`);
const expected = id === 'wall' ? run('RSTONE') : id === 'filter' ? dir << 7 : dir;
check(`${id} explicit direction ${dir} gives its stored variant`,
run(`pieceV(PIECE_BY_ID.${id}, ${dir})`) === expected);
}
}
for (const id of ['wall', 'belt', 'filter', 'screw', 'gate', 'pump']) {
for (const [dx, dy] of [[0, 0], [4, 0], [-4, 0], [0, 4], [0, -4], [4, -4], [4, 4], [-4, 4], [-4, -4]]) {
run(`GAME.pieceDir.${id} = 0; GAME.drag = { bx: 20, by: 20 };`);
// The endpoint intentionally differs from aimBlock(), including opposite filter slopes.
check(`${id} plan ${dx},${dy} keeps the direction and variant rule`, run(`(() => {
const P = PIECE_BY_ID.${id}, b = { bx: ${20 + dx}, by: ${20 + dy} };
const plan = dragPlan(P, GAME.drag, b, false);
const code = pieceCode(P, b), dd = dragDirFor(P, GAME.drag, b), dir = dd >= 0 ? dd : 0;
const expected = isWall(P.code) ? GAME.wallMat : P.filter ? filterVariant(code, dir << 7) : dir;
return plan.code === code && plan.dir === dir && plan.v === expected &&
pieceV(P, dir, code) === expected && [...plan.planned.values()].every(([c, v]) => c === code && v === expected);
})()`));
}
}
done();