Deepgrain Foundry: move from a claude.ai artifact to a local repository

The game as of artifact version 24, ready for local development with
coding agents.

- Source split from three large files into 52 small ones under src/sim,
  src/render and src/ui, joined in the order in src/manifest.json by
  build.py. The joined code is unchanged apart from comments; every
  headless suite gives the same output, and screenshots in both looks
  are pixel-identical to before.
- Light tidying with no change in behaviour: one movement scan loop,
  shared hazard-stripe and belt shader helpers, unused code removed, a
  shared check helper for the test suites.
- World files can be exported as an ordinary download outside claude.ai.
- Tests: broken old scripts removed, experiments moved to tools/,
  test/run_all.py added. Tools: shot.py (repeatable screenshots),
  where.py, map.py.
- Docs: AGENTS.md, CLAUDE.md, NOTES.md (the owner's to-do inbox),
  docs/PROJECT_MAP.md, DESIGN.md, TESTING.md, systems notes, the
  owner's requests and an agent log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K9kLmYADKSEjuwUN3rFxDA
This commit is contained in:
2026-10-23 16:05:31 -04:00
co-authored by Claude Opus 5.5
commit 3f971a94c2
100 changed files with 11928 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
// Block-sized bit mold sunk into the ground with a stone furnace built over its funnel.
const { load, flatWorld, rect, ticks, dump } = require('../../test/harness');
const { run } = load();
const C = n => run(n);
const kind = process.argv[2] || 'bit', wallName = process.argv[3] || 'STONE';
flatWorld(run, 220, 160, 100);
run('bot.x = 90; bot.y = 60;');
// pit for the mold: x 80..103, y 100..111
run(`for (let y=100;y<=111;y++) for (let x=80;x<=103;x++) setCell(y*W+x, EMPTY, AMB[y], 0)`);
run(`bag[R${wallName === 'STONE' ? 'STONE' : 'BRICK'}] = 500; bagTotal = 500;`);
console.log('mold', JSON.stringify(run(`placeMoldAt('${kind}', 21, 25, ${wallName === 'STONE' ? 'RSTONE' : 'RBRICK'})`)));
const W_ = C(wallName);
rect(run, 80, 100, 83, 111, W_); rect(run, 100, 100, 103, 111, W_); rect(run, 80, 108, 103, 111, W_);
if (process.env.GRATE) { run('bag[LCLAY] = 100; bagTotal += 100;'); console.log('grate', JSON.stringify(run('placeBlocks(BP_GRATE, 0, blockLine(21, 24, 24, 24))'))); }
// furnace walls above, floor at ground level except over the mold
rect(run, 74, 74, 75, 99, W_); rect(run, 108, 74, 109, 99, W_); rect(run, 74, 74, 109, 75, W_);
run(`for (let y=74;y<76;y++) for (let x=91;x<93;x++) setCell(y*W+x, EMPTY, AMB[y], 0)`);
run(`{ let r=mulberry32(9); for (let y=80;y<=99;y++) for (let x=76;x<=107;x++) { const i=y*W+x; if (mat[i]===EMPTY && !part[i]) setCell(i, r()<0.32 ? CUORE : COAL, AMB[y], 0); } }`);
run(`for (let k=0;k<40;k++){ toolIgnite(80,79); toolIgnite(103,79); simTick(); }`);
for (const t of [1200, 1200, 1200, 1800]) {
ticks(run, t);
console.log('--- +' + t, run(`JSON.stringify(molds.map(m=>({state:m.state, fill:+m.fill.toFixed(2), ready: m.ready.length, flaw:m.flaw})))`));
}
if (process.argv[4]) dump(run, 72, 70, 112, 112, true);