Multi-core simulation: grain movement and heat across a worker pool (t88 phase 3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 03:23:43 -04:00
co-authored by Claude Opus 5.5
parent 20963c776e
commit 7468d00efb
35 changed files with 578 additions and 113 deletions
+15 -3
View File
@@ -49,7 +49,7 @@ done(); // prints ALL PASS or N FAILED, sets the
- A new suite named `test/t_<topic>.js` is picked up by `run_all.py` automatically.
**Determinism.** The simulation's randomness comes from seeded generators. The same code and the
same test give the same output every run, apart from lines with timings in ms. To prove a
same test give outputs identical across thread counts and between runs, apart from lines with timings in ms. To prove a
refactor changed nothing, save every suite's output before and after, and diff them:
```sh
@@ -58,6 +58,17 @@ for t in test/t_*.js; do node $t > /tmp/after/$(basename $t).txt; done # afte
diff -r /tmp/before /tmp/after
```
`test/t_threads.js` runs the real shared-memory scheduler inline and with 1, 2 and 8
Node workers, including repeats, comparing all mutable cell/chunk bytes and JS side effects.
The browser creates up to `min(16, hardwareConcurrency - 2, CPU workers setting)` helpers.
Small passes run inline; larger passes use batches to amortize dispatch. Wakes and heat flags
merge after each pass; long liquid searches are deferred until that merge. Global machine and
weather randomness remains separate from the chunk streams. World generation uses the same
inline schedule while settling. The t88 re-baseline changes worldgen material hashes and the
seeded sand pile bounds in `t_corner_seal.js`; the heat oracle now supports pass outputs.
The conveyor fixture uses a wider feed pile, the screen fixture warms longer, and `t_load.js`
checks waking within eight ticks separately from the probabilistic consumption of fuel.
## Browser tests
- They need the `.venv` from README.md → Develop; plain `python3` switches to it on its own.
@@ -73,7 +84,8 @@ diff -r /tmp/before /tmp/after
both looks at zoom 12 and 2. ImageMagick decodes RGB; the per-channel tolerance is 8,
mean RGB error must stay below 0.5/255 and fewer than 0.3% of pixels may exceed 8
(smooth AO/edge rounding). These are frozen pre-removal legacy images, not generated
from the new renderer. Inspect the matching `shots/golden-*.png` after visible changes.
from the new renderer. The compressed `golden-world-640x*.json.gz` fixtures retain the
Phase 2 world bytes that produced them, isolating renderer checks from worldgen RNG changes. Inspect the matching `shots/golden-*.png` after visible changes.
- `test/t_gpu.py` checks default limits (four storage textures per stage), dirty-upload
readback after 240 busy ticks with scrolling and both looks, exact dirty/full image equality
with a frozen clock, world replacement, transparent overlays, drill contours, shader compilation timing, successful device recreation and failed recovery with
@@ -98,7 +110,7 @@ diff -r /tmp/before /tmp/after
- `python3 tools/caps.py` prints isolation, actual WebGPU adapter info and the GL renderer for
Chromium and installed Firefox. Real mode requires a hardware Chromium adapter.
- `test/t_caps.py` checks absent, null, rejected and insufficient-limit adapters, notices and
the mandatory WebGPU startup gate. Threads remain optional until Phase 3. Firefox smoke
the mandatory WebGPU startup gate. Cross-origin isolation is required for threads. Firefox smoke
checks that a browser without WebGPU shows the notice and cannot start a world.
- Install Firefox with `.venv/bin/python -m playwright install firefox`.
`python3 test/firefox_smoke.py` checks isolation and the WebGPU notice, starts a pixel world