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

3.2 KiB

Module 8 Expansion Drop: PULL

The lesson's 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.