Downhill screens no longer shake on screen (t106)
This commit is contained in:
+8
-4
@@ -98,6 +98,10 @@ Details and numbers live in the code and in `docs/systems/`.
|
|||||||
|
|
||||||
## Decisions
|
## Decisions
|
||||||
|
|
||||||
|
- **Screen frames stay still (t106, 2026-10-30).** Removed visual shake from loaded
|
||||||
|
downhill screens in both looks: the owner dislikes it and wants consistency with flat
|
||||||
|
filters. Screens no longer shake visually; grain movement and sorting are unchanged.
|
||||||
|
|
||||||
- **Transport matches the t45 belt (t105, 2026-10-30).** The owner approved the flat belt
|
- **Transport matches the t45 belt (t105, 2026-10-30).** The owner approved the flat belt
|
||||||
and asked for the other transport pieces to keep the same pace and flow through mixed lines.
|
and asked for the other transport pieces to keep the same pace and flow through mixed lines.
|
||||||
The flat belt stays unchanged: 30 cells/s, 30 grains/s with one layer and 90 grains/s with a
|
The flat belt stays unchanged: 30 cells/s, 30 grains/s with one layer and 90 grains/s with a
|
||||||
@@ -434,8 +438,8 @@ above, including:
|
|||||||
- **Conveyor drawing and sleep follow-up (t42/t43, 2026-10-26).** The owner wants visible
|
- **Conveyor drawing and sleep follow-up (t42/t43, 2026-10-26).** The owner wants visible
|
||||||
rubber ribs on the actual cleat raster, filled corrugated far walls behind the load, and
|
rubber ribs on the actual cleat raster, filled corrugated far walls behind the load, and
|
||||||
smooth continuous mesh with rails for inclined screens. Walls stop at the slope ends;
|
smooth continuous mesh with rails for inclined screens. Walls stop at the slope ends;
|
||||||
only loaded screens shake. Empty moving cleats must let chunks sleep. Keep pocket transport,
|
screens no longer shake visually (t106). Empty moving cleats must let chunks sleep. Keep
|
||||||
uphill throughput near 71 grains/s and exact sorting unchanged.
|
pocket transport, uphill throughput near 71 grains/s and exact sorting unchanged.
|
||||||
|
|
||||||
- **Sidewall belts with moving cleats (t42, 2026-10-26; physics replaced by the entry below).** 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
|
grip, use moving barrier lines rather than material cells: the barrier mask blocks normal
|
||||||
@@ -455,8 +459,8 @@ above, including:
|
|||||||
with one mesh-contact nudge every 4 ticks (15 downhill steps/s plus gravity). Unselected
|
with one mesh-contact nudge every 4 ticks (15 downhill steps/s plus gravity). Unselected
|
||||||
bars step on that same cadence; selected bars fall through. Flat filters retain their
|
bars step on that same cadence; selected bars fall through. Flat filters retain their
|
||||||
linear transport. Sorting both slope shapes in either mode conserves the complete mix.
|
linear transport. Sorting both slope shapes in either mode conserves the complete mix.
|
||||||
Both looks use a sturdy mesh frame with a small tick-based shake only while loaded;
|
Both looks use a sturdy mesh frame that no longer shakes visually (t106);
|
||||||
idle mesh has no running belt animation. No old uphill-save migration was added.
|
mesh has no running belt animation. No old uphill-save migration was added.
|
||||||
|
|
||||||
- **Screw conveyors stay, in every direction (2026-10-26).** The owner asked whether screw
|
- **Screw conveyors stay, in every direction (2026-10-26).** The owner asked whether screw
|
||||||
conveyors are still needed now that belts climb 45°, whether they're realistic, and what a
|
conveyors are still needed now that belts climb 45°, whether they're realistic, and what a
|
||||||
|
|||||||
+3
-3
@@ -412,9 +412,9 @@ Drawing (src/render/): browser only. This file: the renderer state R, colour tab
|
|||||||
- functions: glowIndex, thermIdx, pipeCellColor, pipeBodyCell, thinPipeColor, buildSky, initRender, resizeRender, viewCells, updateCamera, snapCamera, screenToWorld, worldToScreenPx, renderMonoFont
|
- functions: glowIndex, thermIdx, pipeCellColor, pipeBodyCell, thinPipeColor, buildSky, initRender, resizeRender, viewCells, updateCamera, snapCamera, screenToWorld, worldToScreenPx, renderMonoFont
|
||||||
- variables: R, GLOW_W, GLOW_R, GLOW_G, GLOW_B, THERM, PC, TREE_R, TREE_G, TREE_B, BG, SKY_R, SKY_G, SKY_B
|
- variables: R, GLOW_W, GLOW_R, GLOW_G, GLOW_B, THERM, PC, TREE_R, TREE_G, TREE_B, BG, SKY_R, SKY_G, SKY_B
|
||||||
|
|
||||||
### src/render/slope-belts.js (167 lines)
|
### src/render/slope-belts.js (158 lines)
|
||||||
Drawing only: the face stays on its simulation cells; the band hangs below it.
|
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
|
- functions: slopeBeltConnections, flatBeltCaps, prepareSlopeBelts, slopeBeltSegment, slopeBeltCorner, slopeBeltShape, slopeBeltAt, slopeBeltColor, slopeWallShape, slopeWallAt, slopeDetailAt, slopePreviewCleat
|
||||||
- variables: slopeBeltJoins, slopeBeltHalo, beltCaps, slopeAcross, slopeAlong, slopeDistance, slopeWallOwner
|
- variables: slopeBeltJoins, slopeBeltHalo, beltCaps, slopeAcross, slopeAlong, slopeDistance, slopeWallOwner
|
||||||
|
|
||||||
### src/render/diagonal-screws.js (79 lines)
|
### src/render/diagonal-screws.js (79 lines)
|
||||||
@@ -449,7 +449,7 @@ GPU sources retain the CPU roof and transmission rules; directional relaxation f
|
|||||||
- functions: gpuLightGrid, gpuLightBindings, gpuLight
|
- functions: gpuLightGrid, gpuLightBindings, gpuLight
|
||||||
- variables: GPU_LIGHT, GPU_LIGHT_SPREAD, GPU_LIGHT_PACK
|
- variables: GPU_LIGHT, GPU_LIGHT_SPREAD, GPU_LIGHT_PACK
|
||||||
|
|
||||||
### src/render/gpu/smooth-slope.js (107 lines)
|
### src/render/gpu/smooth-slope.js (106 lines)
|
||||||
Smooth slope geometry and cleats, ported from slope-belt-shader.js.
|
Smooth slope geometry and cleats, ported from slope-belt-shader.js.
|
||||||
- variables: GPU_SMOOTH_SLOPE_HELPERS, GPU_SMOOTH_SLOPE_DRAW
|
- variables: GPU_SMOOTH_SLOPE_HELPERS, GPU_SMOOTH_SLOPE_DRAW
|
||||||
|
|
||||||
|
|||||||
@@ -354,3 +354,6 @@ chain's output, conservation and per-join load counts. It uses `test/fixtures/t1
|
|||||||
`t_threads.js` also compares that chain with 0/1/2/8 real workers. To photograph the same chain,
|
`t_threads.js` also compares that chain with 0/1/2/8 real workers. To photograph the same chain,
|
||||||
pass the fixture followed by `tools/scenes/t105-chain.js` together as `tools/shot.py --js`
|
pass the fixture followed by `tools/scenes/t105-chain.js` together as `tools/shot.py --js`
|
||||||
(they must share one setup scope); use zoom 5, no lighting and a 1280×760 viewport. Check both looks when changing cleat geometry.
|
(they must share one setup scope); use zoom 5, no lighting and a 1280×760 viewport. Check both looks when changing cleat geometry.
|
||||||
|
|
||||||
|
`t106`: `t_slope_belt_art.js` checks that a loaded screen keeps the empty frame at ticks 2
|
||||||
|
and 4. Screens no longer shake visually in either look; grain movement is unchanged.
|
||||||
|
|||||||
@@ -4,6 +4,21 @@ 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-30: t106 downhill screen frames stay still (Codex)
|
||||||
|
|
||||||
|
- Removed the loaded-screen shake flag, pixel/smooth drawing offsets and unused
|
||||||
|
`screenLoaded` helper. No simulation files changed; all src/sim JavaScript hashes match.
|
||||||
|
- Replaced the two shake checks with stable-frame equality at ticks 2 and 4; the new check
|
||||||
|
fails before the fix and passes after. Recorded the owner decision; regenerated the map.
|
||||||
|
- Files: render/{slope-belts,gpu/smooth-slope}, test/t_slope_belt_art.js,
|
||||||
|
docs/{DESIGN,TESTING,PROJECT_MAP,agent-log}, task t106.
|
||||||
|
- All 44 headless suites pass. Before/after raw output differs only in the replaced art checks
|
||||||
|
(saved under /tmp/t106-{before,after}). Build and map check pass.
|
||||||
|
- Browser golden fails at GPU.ok; smooth times out waiting for GAME.running. No workaround
|
||||||
|
attempted. Full `run_all.py --browser`: all headless pass, 12 browser suites fail,
|
||||||
|
Firefox smoke passes. Browser diagnostics report webgpu=false and SwiftShader; log at
|
||||||
|
/tmp/t106-browser.log. Screenshots and owner visual check remain. Task in Review; no commit.
|
||||||
|
|
||||||
## 2026-10-30: t105 transport matches the t45 belt (Codex)
|
## 2026-10-30: t105 transport matches the t45 belt (Codex)
|
||||||
|
|
||||||
- Shared diagonal cadence, six-grain vertical slope beds, taller cleat pockets and four-lane
|
- Shared diagonal cadence, six-grain vertical slope beds, taller cleat pockets and four-lane
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ fn slopeCorner(p: vec2f, a: vec2f, origin: f32) -> vec3f {
|
|||||||
var d: vec2f = p - a; var radius: f32 = length(d);
|
var d: vec2f = p - a; var radius: f32 = length(d);
|
||||||
return vec3f(radius - 1.85, origin + d.x, 2.0 + d.y);
|
return vec3f(radius - 1.85, origin + d.x, 2.0 + d.y);
|
||||||
}
|
}
|
||||||
fn slopeShape(inputP: vec2f, worldOrigin: vec2f, grade: f32, joins: i32) -> vec3f { var p=inputP;
|
fn slopeShape(inputP: vec2f, worldOrigin: vec2f, grade: f32, joins: i32) -> vec3f { let p=inputP;
|
||||||
if ((joins & 64) != 0) { p.y -= 0.45; }
|
|
||||||
var sy: f32 = select( 0.0, 4.0 , grade < 0.0 );
|
var sy: f32 = select( 0.0, 4.0 , grade < 0.0 );
|
||||||
var a: vec2f = vec2f(-grade * 1.30814755, sy + 1.30814755); var b: vec2f = vec2f(4.0 - grade * 1.30814755, 4.0 - sy + 1.30814755);
|
var a: vec2f = vec2f(-grade * 1.30814755, sy + 1.30814755); var b: vec2f = vec2f(4.0 - grade * 1.30814755, 4.0 - sy + 1.30814755);
|
||||||
if ((joins & 1) != 0) { a.y = sy + 2.0; a.x = (a.y - sy - 2.61629509) / grade; }
|
if ((joins & 1) != 0) { a.y = sy + 2.0; a.x = (a.y - sy - 2.61629509) / grade; }
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ function prepareSlopeBelts(x0, y0, x1, y1) {
|
|||||||
if (c === BP_BELT || c === BP_FILTER) beltCaps[b] = flatBeltCaps(b);
|
if (c === BP_BELT || c === BP_FILTER) beltCaps[b] = flatBeltCaps(b);
|
||||||
if (!isSlopeBelt(c)) continue;
|
if (!isSlopeBelt(c)) continue;
|
||||||
const face = beltFaceY(c, bx, by, bx * BS) * W + bx * BS;
|
const face = beltFaceY(c, bx, by, bx * BS) * W + bx * BS;
|
||||||
slopeBeltJoins[b] = slopeBeltConnections(bx, by, c) | (netSat(face) > 0 ? 16 : 0) | (filterCfg.get(b)?.inv ? 32 : 0) | (isFilter(c) && netSat(face) > 0 && screenLoaded(b) && !transportStalled(b) && (tick & 2) ? 64 : 0);
|
slopeBeltJoins[b] = slopeBeltConnections(bx, by, c) | (netSat(face) > 0 ? 16 : 0) | (filterCfg.get(b)?.inv ? 32 : 0);
|
||||||
for (let yy = Math.max(0, by - 2); yy <= Math.min(BH - 1, by + 1); yy++)
|
for (let yy = Math.max(0, by - 2); yy <= Math.min(BH - 1, by + 1); yy++)
|
||||||
for (let xx = Math.max(0, bx - 1); xx <= Math.min(BW - 1, bx + 1); xx++) slopeBeltHalo[yy * BW + xx] = 1;
|
for (let xx = Math.max(0, bx - 1); xx <= Math.min(BW - 1, bx + 1); xx++) slopeBeltHalo[yy * BW + xx] = 1;
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,6 @@ function slopeBeltCorner(x, y, ax, ay, origin) {
|
|||||||
function slopeBeltShape(x, y, b, joins = slopeBeltJoins[b], code = blockP[b]) {
|
function slopeBeltShape(x, y, b, joins = slopeBeltJoins[b], code = blockP[b]) {
|
||||||
const grade = beltGrade(code), ox = (b % BW) * BS, oy = ((b / BW) | 0) * BS;
|
const grade = beltGrade(code), ox = (b % BW) * BS, oy = ((b / BW) | 0) * BS;
|
||||||
x -= ox; y -= oy;
|
x -= ox; y -= oy;
|
||||||
if (isFilter(code) && (joins & 64)) y -= 0.45;
|
|
||||||
const offset = 1.85 * Math.SQRT2, sy = grade < 0 ? 4 : 0;
|
const offset = 1.85 * Math.SQRT2, sy = grade < 0 ? 4 : 0;
|
||||||
const normal = 1.85 * Math.SQRT1_2;
|
const normal = 1.85 * Math.SQRT1_2;
|
||||||
let ax = -grade * normal, ay = sy + normal, bx = 4 - grade * normal, by = 4 - sy + normal;
|
let ax = -grade * normal, ay = sy + normal, bx = 4 - grade * normal, by = 4 - sy + normal;
|
||||||
@@ -118,14 +117,6 @@ function slopeBeltColor(b, x, y, anim, br, bg, bb) {
|
|||||||
return (r | 0) | ((g | 0) << 8) | ((blue | 0) << 16);
|
return (r | 0) | ((g | 0) << 8) | ((blue | 0) << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
function screenLoaded(b) {
|
|
||||||
const bx = b % BW, by = (b / BW) | 0, c = blockP[b];
|
|
||||||
for (let x = bx * BS; x < bx * BS + BS; x++) {
|
|
||||||
const i = (beltFaceY(c, bx, by, x) - 1) * W + x;
|
|
||||||
if (i >= 0 && (PH[mat[i]] === PH_POWDER || occ[i])) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Filled far wall, in belt coordinates. Project onto the face so ends stop at the slope ends.
|
// Filled far wall, in belt coordinates. Project onto the face so ends stop at the slope ends.
|
||||||
let slopeWallOwner = -1;
|
let slopeWallOwner = -1;
|
||||||
function slopeWallShape(x, y, b, code = blockP[b]) {
|
function slopeWallShape(x, y, b, code = blockP[b]) {
|
||||||
|
|||||||
@@ -113,10 +113,13 @@ for (const grade of [-1,1]) {
|
|||||||
flatWorld(run,160,120,112);
|
flatWorld(run,160,120,112);
|
||||||
run('placeBlock(BP_FILTER_DOWN,128,12,12,true);tick=0;prepareSlopeBelts(0,0,W,H);var idleJoins=slopeBeltJoins[12*BW+12];tick=2;prepareSlopeBelts(0,0,W,H);');
|
run('placeBlock(BP_FILTER_DOWN,128,12,12,true);tick=0;prepareSlopeBelts(0,0,W,H);var idleJoins=slopeBeltJoins[12*BW+12];tick=2;prepareSlopeBelts(0,0,W,H);');
|
||||||
check('empty screen has a stable frame',run('slopeBeltJoins[12*BW+12]===idleJoins'));
|
check('empty screen has a stable frame',run('slopeBeltJoins[12*BW+12]===idleJoins'));
|
||||||
run('setCell(47*W+48,SAND,20,0);prepareSlopeBelts(0,0,W,H);');
|
check('loaded screen keeps the empty frame at ticks 2 and 4',run(`(() => {
|
||||||
check('loaded screen shakes the frame with the simulation tick',run('(slopeBeltJoins[12*BW+12]&64)!==0'));
|
for (const t of [2,4]) {
|
||||||
run('tick=4;prepareSlopeBelts(0,0,W,H);');
|
tick=t;setCell(47*W+48,SAND,20,0);prepareSlopeBelts(0,0,W,H);
|
||||||
check('loaded frame returns on the next shake beat',run('(slopeBeltJoins[12*BW+12]&64)===0'));
|
if (slopeBeltJoins[12*BW+12]!==idleJoins) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})()`));
|
||||||
flatWorld(run,160,120,112);
|
flatWorld(run,160,120,112);
|
||||||
run('for(let k=0;k<6;k++)placeBlock(BP_BELT_UP,1,12+k,20-k,true);rebuildPower();slopeCleatsTick(false);');
|
run('for(let k=0;k<6;k++)placeBlock(BP_BELT_UP,1,12+k,20-k,true);rebuildPower();slopeCleatsTick(false);');
|
||||||
check('wall reaches the belt and cleat height, and clips its free ends',run(`(()=>{
|
check('wall reaches the belt and cleat height, and clips its free ends',run(`(()=>{
|
||||||
|
|||||||
Reference in New Issue
Block a user