Belts built after a tick reset join the network; pin tick in golden renders

A world started after a long session kept the old nextPowerBuild, so new
belts were never added until a reload. Treat a wait longer than 6 ticks as
stale. The golden test pins tick now that t45 animates belts from it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cj2RPXdPykKMEz5BXXczsj
This commit is contained in:
2026-10-29 23:50:09 -04:00
co-authored by Claude Opus 5.5
parent af411d5b21
commit e605953661
4 changed files with 22 additions and 2 deletions
+12
View File
@@ -4,6 +4,18 @@ 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 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. open or not verified. Keep each entry short; the git history has the details.
## 2026-10-29: new belts stood still until reload; golden test after t45 (Claude)
- Owner bug: in a world started after a long session, belts built after loading never moved
(save and reload fixed them). The 6-tick power rebuild throttle (`nextPowerBuild`) survived
the tick reset of a new or loaded world, so rebuilds waited for the old tick count. Now a wait
longer than 6 ticks counts as stale. Not caused by t45; tests had hidden it with `nextPowerBuild=0`.
- t45 animates belts from the tick (`transportClock`), so `t_gpu_golden.py` now pins `tick`
(1000 for pixel = old R.frame, 300 for smooth = old 5 s clock); all goldens match exactly again.
- Files: sim/machine-tick, test/{t_basics.js,t_gpu_golden.py}, this log.
- Tests: new t_basics check failed before the fix; all headless suites, t_stalls.py,
t_gpu_golden.py and play.py pass.
## 2026-10-29: t103 blow carried liquids without the Flask (Codex) ## 2026-10-29: t103 blow carried liquids without the Flask (Codex)
- Removed only blow-side Flask gates, including Shift's HUD list; corrected the Flask hint. - Removed only blow-side Flask gates, including Shift's HUD list; corrected the Flask hint.
+2 -1
View File
@@ -47,7 +47,8 @@ function fanBlow(mm, sat) {
function machinesTick() { function machinesTick() {
procBlocksTick(); procBlocksTick();
rackTick(); rackTick();
if (powerDirty && tick >= nextPowerBuild) { rebuildPower(); nextPowerBuild = tick + 6; } // A new or loaded world restarts the tick count, so a wait longer than 6 ticks is stale.
if (powerDirty && (tick >= nextPowerBuild || nextPowerBuild > tick + 6)) { rebuildPower(); nextPowerBuild = tick + 6; }
if (brokenMachines.length) { if (brokenMachines.length) {
const ids = brokenMachines; brokenMachines = []; const ids = brokenMachines; brokenMachines = [];
for (const id of ids) if (machines[id]) removeMachine(id, false, true); for (const id of ids) if (machines[id]) removeMachine(id, false, true);
+6
View File
@@ -157,4 +157,10 @@ check('a save holding solid rock loads it as rubble with the same total', run(`(
deserializeWorld(s.meta, s.buffers); deserializeWorld(s.meta, s.buffers);
return bag[BASALT] === 0 && bag[RBAS] === 1000 && bag[CLAY] === 0 && bag[LCLAY] === 200 && bag[MSLAG] === 7 && bagTotal === 1207; return bag[BASALT] === 0 && bag[RBAS] === 1000 && bag[CLAY] === 0 && bag[LCLAY] === 200 && bag[MSLAG] === 7 && bagTotal === 1207;
})()`)); })()`));
// A belt built in a new world joins the network even after a long earlier session (owner bug,
// 2026-10-29: new belts stood still until the world was saved and loaded again).
flatWorld(run, 256, 224, 208);
run('RS = 7; nextPowerBuild = 500000; weather.next = 1e15; for (let bx = 12; bx < 40; bx++) placeBlock(BP_BELT, 1, bx, 32, true); setCell(127 * W + 60, SAND, 20, 0);');
ticks(run, 60);
check('a belt built after a tick reset carries its grains', run('mat[127 * W + 60] !== SAND && Array.from({ length: 100 }, (_, k) => mat[127 * W + 61 + k]).includes(SAND)'));
done(); done();
+2 -1
View File
@@ -39,7 +39,8 @@ with launch(viewport={'width': 640, 'height': 480}) as (_, pg, url):
SET.look=look;SET.zoom=zoom;SET.lighting='full';SET.lightEvery=1;SET.glow='low'; SET.look=look;SET.zoom=zoom;SET.lighting='full';SET.lightEvery=1;SET.glow='low';
SM.t0=0; SM.surf=-1; SM.t0=0; SM.surf=-1;
performance.now=()=>5000;resizeRender();bot.x=CAM[0]-bot.w/2;bot.y=CAM[1]-bot.h/2; performance.now=()=>5000;resizeRender();bot.x=CAM[0]-bot.w/2;bot.y=CAM[1]-bot.h/2;
snapCamera();R.frame=1000;drawWorld(); // belts animate from the tick: pixel look by tick (was R.frame), smooth by tick/60 s (was the 5 s clock)
snapCamera();R.frame=1000;tick=look==='smooth'?300:1000;drawWorld();
}""",[look,zoom]) }""",[look,zoom])
raw=pg.evaluate("""() => { raw=pg.evaluate("""() => {
const c=document.createElement('canvas');c.width=384;c.height=288; const c=document.createElement('canvas');c.width=384;c.height=288;