One rule for a piece's direction variant: remove pieceV (t81)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
Reference in New Issue
Block a user