Files
systemic-game-design-course/course/10-spellgrid/reference/ts
Lucas WintherandClaude Opus 5.5 4eaf24eed2 feat: summoned minions enter the grid in Module 10 (a fourth seam; Clay Golem, Clay Shard)
Summoned records its summoner (the minion whose trigger is resolving) inside
the engine; the harness log is unchanged. When a Sequence ends, SpellGrid
writes spawned text, places each summoned minion with a noun on its
summoner's tile, removes the dead, reparses and syncs rule auras.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:35:59 +01:00
..
2026-10-29 05:01:27 +01:00
2026-10-29 05:01:27 +01:00
2026-10-29 05:01:27 +01:00
2026-10-29 05:01:27 +01:00
2026-10-29 05:01:27 +01:00
2026-10-29 05:01:27 +01:00

Module 10 reference engine (TypeScript)

The course's own engine as of the end of Module 10: Part I's card engine and Part II's grid engine, joined by SpellGrid. Every test from Modules 1–9 still passes. Module 9's reference was the starting point, so a diff between the two shows what this module adds.

  • cards/ and levels/ (at the package root; not in this directory): copies of course/cards/ plus course/10-spellgrid/cards/ (SpellGrid's own cards, which only Module 10 on receives), and of course/10-spellgrid/levels/, staged by tools/verify-references.mjs (and by tools/play-spellgrid.mjs, to play the command line).
  • src/engine/spellgrid.ts (new): the only file that imports both engines. SpellGrid keeps a World and a puzzle.Level in step through the four seams: ruleAuras (rules in force → auras), the destroy function (hazard victims → one destroy Sequence → the Death Creation Step), and sequence (after each Sequence: write TextSpawned text, put summoned minions that have a noun on their summoner's tile, take dead minions off the grid, reparse). It also keeps one id space: a minion's id is its grid object's id.
  • Part I (src/engine/, outside puzzle/):
    • queue.ts: END_OF_PHASE (["deathCreation", "auraUpdate"]) is the list of steps at the end of the outermost Phase, read from the world. The spawnText action records a TextSpawned event.
    • world.ts: setRuleAuras/ruleAuras (auras that no minion carries), setEndOfPhase/endOfPhase, entityCount; Summoned records its summoner, by (the minion whose trigger is resolving).
    • aura.ts: an Aura Update adds the rule auras for both players; activations applies a triggerCap.
    • card.ts: the triggerCap aura (not in the card format: only SpellGrid makes it).
    • effect.ts: spawnText is an action, not an error. event.ts: TextSpawned, and Summoned.by.
  • Part II (src/engine/puzzle/):
    • level.ts: Destroy and removeAll. step and moveYou take an optional Destroy, which movement, conversion (X IS NOT X) and hazards hand their victims to. reparse is public.
    • grid.ts: Board.reserveId, and cards/hand in LevelDef (read only by SpellGrid).
  • src/content/seams.json and seams() (new): which nouns name a trigger (DEATHRATTLE) and which properties multiply one (DOUBLE, twice, stacking: "max"). words.json adds the SpellGrid nouns, DEATHRATTLE and DOUBLE. index.ts now reads cards/ with node:fs, so the command line, which runs without Vite, reads the same cards.
  • src/harness.ts: Module 10 adds newSpellGrid and the SpellGrid interface, including the test hook withNaiveAuraTiming(), which reverses END_OF_PHASE for one game. Its undo throws not supported: Part I has state the level's snapshot doesn't cover.
  • src/cli.ts (new): the command line, npx tsx src/cli.ts levels/l1-double-tap.json run from a staged directory (it needs cards/ and levels/): node tools/play-spellgrid.mjs ts l1 from the course repository stages one in a temporary directory and starts it. w a s d move, c <card> [x y] casts a spell (at the minion on that tile) or plays a minion (onto that empty tile), q quits. tests/cli.test.ts plays it from a script; it is the reference's own check, not a course test.

Run it with the module's tests: node tools/verify-references.mjs 10 from the course repository.