Files
systemic-game-design-course/course/08-push-chains/expansion/README.md
T
Lucas WintherandClaude Fable 5.2 8467c7929e fix(puzzle): an object steps once per movement phase; negated conversion is settled per object
Bug 1 (modules 08-10): a YOU object pulled by an earlier mover took a second step of its own. Level movement now keeps the ids that stepped in a committed plan this phase; such a YOU object starts no move, and Planner try_move answers no for it. Regression: test_08x_pulled_you_moves_once (Module 8 Expansion Drop).

Bug 2 (modules 09-10): convert honoured negation only per rule, so ALL IS ROCK beat BABA IS NOT ROCK. A target Y is now skipped for an object if any active negated rule IS NOT Y names it. Module 9 and 10 references (and their drop solutions) now carry ALL, the Module 7 Expansion Drop. Regression: test_09_negated_conversion_beats_group.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 09:18:00 +01:00

32 lines
3.2 KiB
Markdown

# Module 8 Expansion Drop: PULL
The lesson's [Expansion Drop](../lesson.md#expansion-drop) beat explains the task. This file holds the scenario, the test locations and the check.
- Word: PULL, a property. From the Baba Is You Wiki's PULL page (recorded in `docs/research/baba-is-you.md` §5): "PULL is a Property that makes an object pullable by any moving object. PULL also makes the object "solid" for collision checks like STOP does.", and "If something directly adjacent from a PULL object moves away from it, the PULL object will try to move in the same direction."
- Tests: `tests/rust/test_08x.rs` and `tests/ts/test_08x.test.ts`. Copy the one for your track into your workspace's `tests/`.
- Reference answer, one change in data and one in content code:
- `solution/words.json`, one file for both tracks: the Module 8 reference's `src/content/words.json` with one entry added, `{ "name": "PULL", "role": "property" }`.
- `solution/rust/src/content/movement.rs` and `solution/ts/src/content/movement.ts`: the Module 8 reference's movement responses with one response added, `pull`, listed after `push`.
- Nothing under `src/engine/` changes, and neither does the harness. PULL is a new behaviour, so it is new code, but it is a response the engine's planner runs like any other: the planner already lets a response look at any tile and ask for any object to move.
- Check: commit your workspace before you start, then run `node tools/expansion-check.mjs <your-workspace> <that-commit>` from the course repository. It fails if any file under `src/engine/` changed.
The reference lets a PULL object that can't follow stay behind without stopping the mover. The PULL page doesn't say what happens then, and this test doesn't check it.
## Scenario
### test_08x_pull_follows
- Setup: `newBaba` with an empty level 5 wide and 3 high. Place `BABA (0,0) IS (1,0) YOU (2,0)` and `ROCK (0,1) IS (1,1) PULL (2,1)`. Place an object `rock` at (0,2) (the far rock), an object `rock` at (1,2) (the near rock) and an object `baba` at (2,2).
- Action 1: `move("right")`.
- Assertions 1: `posOf(baba)` is (3,2), the near rock is at (2,2) and the far rock at (1,2). Baba moved away from the near rock, so it followed; the near rock moved away from the far rock, so that one followed too.
- Action 2: `move("left")`.
- Assertions 2: nothing moved: Baba is still at (3,2), the near rock at (2,2) and the far rock at (1,2). A PULL object is solid: Baba can't step onto it, and PULL doesn't push.
Before the drop the lexicon doesn't know `PULL`, so `ROCK IS PULL` spells nothing: Baba walks away from the rocks, and in the second move walks back onto the near rock's tile.
### test_08x_pulled_you_moves_once
- Setup: `newBaba` with an empty level 5 wide and 4 high. Place `BABA (0,0) IS (1,0) YOU (2,0)` and `KEY (0,1) IS (1,1) YOU (2,1) AND (3,1) PULL (4,1)`. Place an object `key` at (1,3) and an object `baba` at (2,3).
- Action: `move("right")`.
- Assertions: `posOf(baba)` is (3,3) and `posOf(key)` is (2,3). Baba is furthest ahead, so it moves first, and the key behind it follows. The key is `YOU` as well, but it has already stepped in this move, and an object steps at most once per move: it doesn't take a second step of its own onto Baba's tile.