SpellGrid capstone: Part I's card engine and Part II's grid engine joined at three seams (rules -> aura data, hazard victims -> one destroy Sequence, Sequence end -> write text, remove the dead, reparse). Three levels with scripted solutions, a naive-timing test via a harness-only hook that reverses the END_OF_PHASE list, CLIs in both tracks, the BATTLECRY IS DOUBLE Expansion Drop, SpellGrid cards and words in course/cards and the catalog, level schema cards/hand, and tools staging/copying of module levels. Co-Authored-By: Claude Opus 5.5 <[email protected]>
2.8 KiB
2.8 KiB
Module 10 reference engine (Rust)
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/andlevels/(at the crate root; not in this directory): copies ofcourse/cards/andcourse/10-spellgrid/levels/, staged bytools/verify-references.mjs.src/engine/spellgrid.rs(new): the only module that uses both engines.SpellGridkeeps aWorldand apuzzle::Levelin step through the three seams:rule_auras(rules in force → auras),CardSide::destroy(hazard victims → oneDestroySequence → the Death Creation Step), andCardSide::sequence(after each Sequence: writeTextSpawnedtext, 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/, outsidepuzzle/):queue.rs:END_OF_PHASE([DeathCreation, AuraUpdate]) is the list of steps at the end of the outermost Phase, read from the world.Action::SpawnTextrecords aTextSpawnedevent.world.rs:set_rule_auras/rule_auras(auras that no minion carries),set_end_of_phase/end_of_phase,entity_count.aura.rs: an Aura Update adds the rule auras for both players;activationsapplies anAura::TriggerCap.card.rs:Aura::TriggerCap(not in the card format: only SpellGrid makes it), andCardDef::noun.effect.rs:spawnTextis an action, not a panic.event.rs:TextSpawned.
- Part II (
src/engine/puzzle/):level.rs:Destroyandremove_all.step_withandmove_you_withtake a destroy function, which movement, conversion (X IS NOT X) and hazards hand their victims to;stepandmove_youpassremove_all.reparseandboard_mutare public.grid.rs:Board::reserve_id, andcards/handinLevelDef(read only by SpellGrid), withLevelCard.
src/content/seams.jsonandseams()(new): which nouns name a trigger (DEATHRATTLE) and which properties multiply one (DOUBLE, twice,stacking: "max").words.jsonadds the SpellGrid nouns,DEATHRATTLEandDOUBLE.src/harness.rs: Module 10 addsnew_spell_gridandSpellGrid, including the test hookwith_naive_aura_timing(), which reversesEND_OF_PHASEfor one game.src/cli.rsandsrc/bin/spellgrid.rs(new): the command line,cargo run --bin spellgrid -- levels/l1-double-tap.jsonfrom a staged workspace (it needscards/andlevels/).w a s dmove,c <card> [x y]casts a spell (at the minion on that tile) or plays a minion (onto that empty tile),qquits.tests/cli.rsplays 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.