Files
systemic-game-design-course/course/06-parser/reference/rust
Lucas WintherandClaude Fable 5.2 429137a6ef fix(reference): Death Events remember a right-hand neighbour, not a board index
A Deathrattle summon used the dying minion's board index from before the
Death Creation Step removed anything. That index is stale when a minion to
its left dies in the same step, so the token landed one place too far right.

Each Death Event now records `before`: the nearest minion to the right that
is not dying in the same step. The position handed to the effect context is
resolved when the trigger resolves: the current index of `before`, or the
right end. Applied to the Rust and TS references of Modules 3-10.

Module 3 gains two tests, documented in scenarios.md:
test_03_summon_position_after_simultaneous_deaths (fails before the fix) and
test_03_simultaneous_summons_keep_board_order.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 09:15:48 +01:00
..
2026-10-29 03:33:53 +01:00
2026-10-29 03:33:53 +01:00
2026-10-29 03:33:53 +01:00
2026-10-29 03:33:53 +01:00

Module 6 reference engine (Rust)

The course's own engine as of the end of Module 6, the first module of Part II. Part I's card engine is unchanged, and all of its tests still pass. Beside it, in src/engine/puzzle/, is a second engine for Baba Is You: a grid of objects and text, a lexer and a parser. Module 5's reference was the starting point, so a diff between the two shows what this module adds.

  • cards/ (at the crate root; not in this directory): Part I's card data, a copy of course/cards/ staged by tools/verify-references.mjs. Part II doesn't read it.
  • src/engine/puzzle/: the Part II engine. It names no noun: the engine's own words are the operators IS, AND, NOT, the meta-noun TEXT and the property PUSH of the base rule TEXT IS PUSH.
    • grid.rs: the level format (LevelDef, course/schema/level.schema.json), object kinds ("<noun>" or "text:<WORD>") and the board: objects on tiles, several per tile allowed.
    • word.rs: the lexicon (every word the parser can read, with its role: noun, property or operator) and the lexer, which turns the text on the board into words by tile. Text whose word isn't in the lexicon spells nothing.
    • parse.rs: the parser. From every IS, in a row and in a column, it collects the AND-joined subjects before it and the AND-joined complements after it, and emits one rule per pair. Stacked words each count. Base rules come first.
    • level.rs: a level in play. Every change to the board recompiles the rules from scratch.
    • mod.rs: the module's exports.
  • The rest of src/engine/: Part I, unchanged from Module 5 except for the pub mod puzzle; line.
  • src/content/words.json: the nouns and properties the parser knows, as data ({ "name", "role" }). src/content/mod.rs reads it with include_str! as words(). A new word is a new entry here.
  • src/harness.rs: the adapter the course tests call. Module 6 adds new_baba, Baba::place and Baba::rules. rules() sorts the rules' normalised strings and keeps each distinct rule once; the engine itself keeps a rule spelled twice twice.

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