Files
systemic-game-design-course/course/06-parser/scenarios.md
T
Lucas WintherandClaude Opus 5.5 68fe9834c3 feat: module 06 parser
First Part II module. The cumulative reference adds a second engine
(src/engine/puzzle: grid, lexer, parser) beside Part I's; nouns and
properties are data in src/content/words.json, and the engine names only
IS/AND/NOT/TEXT and the base rule TEXT IS PUSH. Rules are recompiled from
the board on every change; rules() is a sorted set. Adds the M6 scenarios
and tests (rows, columns, shared IS, AND distribution, stacked text, base
rule), the HOT word as a data-only Expansion Drop, the lesson with the
Part II bridge, and the Rust LevelDef shape in harness.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 03:33:53 +01:00

40 lines
3.5 KiB
Markdown

# Module 6 scenarios: Grid, lexer and parser
Each heading is a test name. The Rust test lives in `tests/rust/test_06.rs` and the TypeScript test in `tests/ts/test_06.test.ts`; both state exactly what is written here.
Part II has its own harness object, `Baba`, made by `newBaba(level)` from a level in the format of `course/schema/level.schema.json`: a `width`, a `height` and a list of `objects`, each `{kind, x, y}`. `x` grows right and `y` grows down. A kind is either an object (`"baba"`) or a word of text (`"text:BABA"`). `place(kind, x, y)` adds one more object to the level and returns its id. Several objects may share a tile.
`rules()` returns every rule the board currently spells, as normalised strings such as `"BABA IS YOU"`, sorted, each distinct rule once. The base rule `"TEXT IS PUSH"` is always in it, although no text spells it. Duplicates are a real thing in the game (stacked text "will attempt to produce all possible rules", and a rule spelled twice can duplicate objects, see `docs/research/baba-is-you.md` §e), so the engine may hold the same rule more than once, but `rules()` is the set of distinct rules and no test counts duplicates.
Words used: the nouns `BABA`, `ROCK`, `FLAG`; the properties `YOU`, `WIN`, `PUSH`, `STOP`; the operators `IS` and `AND`; the meta-noun `TEXT` (only through the base rule). Rules read left to right in a row and top to bottom in a column. A test writes a sentence as its words with their tiles: `BABA (0,0) IS (1,0) YOU (2,0)` is three text objects, `text:BABA` at x 0, y 0, and so on.
### test_06_horizontal_rule
- Setup: `newBaba` with a level 5 wide and 3 high whose `objects` are, in this order: `BABA (0,0) IS (1,0) YOU (2,0)`; an object `baba` at (3,2); `YOU (0,2) IS (1,2) FLAG (2,2)`.
- Action: none. The rules come from the level's objects.
- Assertions:
- `rules()` is exactly `["BABA IS YOU", "TEXT IS PUSH"]`.
- Row 2 spells nothing: `YOU IS FLAG` has a property where a noun must start the sentence, and the parser never reads right to left (`FLAG IS YOU`). The `baba` object is not text and plays no part in parsing.
### test_06_crossword_shared_is
- Setup: `newBaba` with an empty level 3 wide and 3 high. Place `BABA (0,1)`, `IS (1,1)`, `YOU (2,1)`, then `FLAG (1,0)`.
- Assertions 1: `rules()` is exactly `["BABA IS YOU", "TEXT IS PUSH"]`. `FLAG` above `IS` is half a sentence.
- Action: place `WIN (1,2)`.
- Assertions 2: `rules()` is exactly `["BABA IS YOU", "FLAG IS WIN", "TEXT IS PUSH"]`. The `IS` at (1,1) is in a row sentence and a column sentence at once, and the rules were recompiled when the board changed.
### test_06_and_distributes
- Setup: `newBaba` with an empty level 7 wide and 1 high. Place `BABA (0,0) AND (1,0) ROCK (2,0) IS (3,0) PUSH (4,0) AND (5,0) STOP (6,0)`.
- Assertions: `rules()` is exactly `["BABA IS PUSH", "BABA IS STOP", "ROCK IS PUSH", "ROCK IS STOP", "TEXT IS PUSH"]`. AND distributes over both sides: two subjects times two complements is four rules.
### test_06_stacked_text_all_combinations
- Setup: `newBaba` with an empty level 3 wide and 1 high. Place `text:BABA` at (0,0), then `text:ROCK` also at (0,0), then `IS (1,0)` and `YOU (2,0)`.
- Assertions: `rules()` is exactly `["BABA IS YOU", "ROCK IS YOU", "TEXT IS PUSH"]`. Both stacked words start a sentence: the parser produces every rule the stack allows.
### test_06_default_text_is_push
- Setup: `newBaba` with a level 3 wide and 3 high whose only object is a `baba` at (1,1).
- Assertions: `rules()` is exactly `["TEXT IS PUSH"]`. No text spells it: it is a base rule of the game.