Adds course/11-conditions: lesson, scenarios, nine test_11 tests in both tracks, the cumulative reference (Module 10's plus conditions) and the NEAR drop. The engine learns a condition role, rules carry conditions, and Level.hasProperty and conversion evaluate content's condition checks against the board whenever a rule is used. Resolution pairs only rules with the same conditions. Catalog, harness contract, research notes and the diff-tracks generator follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Module 11 Expansion Drop: NEAR
The lesson's Expansion Drop beat explains the task. This file holds the scenario, the test locations and the check.
- Word:
NEAR, a condition. From the Baba Is You Wiki's NEAR page (recorded indocs/research/baba-is-you.md§7): "NEAR is an infix condition that makes a rule apply when an object is on a target or in one of the eight spaces around it". The page doesn't mention float levels; the reference ignores them, asONdoes (the course's choice). - Tests:
tests/rust/test_11x.rsandtests/ts/test_11x.test.ts. Copy the one for your track into your workspace'stests/. - Reference answer, one change in data and one in content code:
solution/words.json, one file for both tracks: the Module 11 reference'ssrc/content/words.jsonwith one entry added,{ "name": "NEAR", "role": "condition" }.solution/rust/src/content/conditions.rsandsolution/ts/src/content/conditions.ts: the Module 11 reference's condition checks with one check added,near, registered underNEAR. It looks at the other objects on the object's tile and the eight around it, and needs a different one for each listed noun, asondoes on one tile.- Nothing under
src/engine/changes, and neither does the harness.
- 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 undersrc/engine/changed.
Scenario
test_11x_near
- Setup:
newBabawith an empty level 5 wide and 5 high. PlaceKEY (0,0) NEAR (1,0) ROCK (2,0) IS (3,0) WIN (4,0). Place an objectrockat (2,3). Place an objectkeyat (2,3) (onIt, on the rock's tile), one at (3,3) (beside), one at (1,2) (diagonal) and one at (0,4) (far, two columns away). - Assertions:
rules()is exactly["KEY NEAR ROCK IS WIN", "TEXT IS PUSH"].hasProperty(onIt, "WIN"),hasProperty(beside, "WIN")andhasProperty(diagonal, "WIN")are true: the rock is on the key's tile or on one of the eight around it.hasProperty(far, "WIN")is false.
Before the drop the lexicon doesn't know NEAR, so the parser never sees it. The words before IS are then just ROCK, and the sentence spells ROCK IS WIN: the first assertion fails.