Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .opencode/skills/zil-implementation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,14 @@ On this substrate, untouched objects with `FDESC` are printed directly by `PRINT
Missing `>` is the most common and hardest-to-spot bug.

### 3. Define `ROUTINE GO ()` in actions.zil
The game entry point must exist. Set up HERE, LIT, WINNER, PLAYER, call V-LOOK, call MAIN-LOOP.
The game entry point must exist. Set up HERE, `<SETG VERBOSE T>`, LIT, WINNER, PLAYER, call V-LOOK, call MAIN-LOOP.
VERBOSE is not optional. The substrate starts in Infocom's BRIEF mode, where a
revisited room prints only its name. Readers show that name as a heading, so
returning to a room shows no text at all. `make lint-zil` fails without it.

Deaths use `JIGS-UP`, which ends the story through `FINISH` (score, then
RESTART/RESTORE/QUIT). Never advertise a death that no command can reach; test
each one and expect the FINISH prompt.

### 4. Custom SYNTAX uses `= V-ROUTINE`
Only add syntax for verbs absent from the substrate. Search `infocom/zork1/syntax.zil` first.
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ Start with [ARCHITECTURE.md](ARCHITECTURE.md). It is the canonical high-level su
4. For content or gameplay issues, inspect the relevant adventure folder under [infocom](infocom) or [books](books) before changing engine code.
5. When debugging ZIL-related failures, prefer adding temporary `TELL`/print commands directly in the relevant ZIL routines to expose values, branch choices, and object locations while narrowing the problem. Remove or clearly quarantine this instrumentation before finishing unless it is intentionally part of a test.
6. Validate with the smallest relevant target from [Makefile](Makefile); for broad gameplay regressions, use `make test-pure-zil`.
7. Story prose withholds what must be examined and links what can be acted on. Follow "Prose Links" and "Withholding What Must Be Examined" in [docs/WRITING_ADVENTURES.md](docs/WRITING_ADVENTURES.md), and run `make lint-zil`, which checks vocabulary, link words, and every link target through the parser.
7. Story prose withholds what must be examined and links what can be acted on. Follow "Prose Links" and "Withholding What Must Be Examined" in [docs/WRITING_ADVENTURES.md](docs/WRITING_ADVENTURES.md), and run `make lint-zil`, which checks vocabulary, link words, and every link target through the parser, and plays common verbs on every object to catch commands that print nothing.
8. Books start VERBOSE, so a revisited room never prints only its name, and every death ends the story through `FINISH`. See "The GO Routine" in [docs/WRITING_ADVENTURES.md](docs/WRITING_ADVENTURES.md).

## Playing Games

Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ help:
@echo " test-llm - Run LLM persistence tests"
@echo " test-limehouse-walkthrough - Run Limehouse golden-path LLM test"
@echo " test-wondertown-descriptions - Run Wondertown rendered description regressions"
@echo " lint-zil - Check printed object names against parser vocabulary"
@echo " lint-zil - Check vocabulary, prose links, and that every command answers"
@echo ""
@echo "Horror game tests:"
@echo " test-horror-helpers - Run horror test helpers"
Expand Down Expand Up @@ -201,6 +201,7 @@ test-horror-playtest-regressions:
@lua5.4 run-zil-test.lua books/blackwood-horror/test/test-playtest-lore
@lua5.4 run-zil-test.lua books/blackwood-horror/test/test-playtest-systems
@lua5.4 run-zil-test.lua books/blackwood-horror/test/test-prose-reveal
@lua5.4 run-zil-test.lua books/blackwood-horror/test/test-playtest-navigation

test-horror-all: test-horror-helpers test-horror-partial test-horror-failures test-horror-playtest-regressions test-horror
@echo "All horror tests completed!"
Expand Down Expand Up @@ -237,6 +238,8 @@ lint-zil:
@lua5.4 scripts/check-links.lua books/limehouse-killings books/blackwood-horror books/wondertown
@echo "Examining every prose link through the parser..."
@lua5.4 scripts/check-link-targets.lua books/limehouse-killings books/blackwood-horror books/wondertown
@echo "Playing common verbs on every object..."
@lua5.4 scripts/check-responses.lua books/limehouse-killings books/blackwood-horror books/wondertown

zip:
@if [ -z "$(filter-out zip,$(MAKECMDGOALS))" ]; then echo "Usage: make zip <gamename>"; echo "Example: make zip limehouse-killings"; exit 1; fi
Expand Down
56 changes: 22 additions & 34 deletions books/blackwood-horror/actions.zil
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

<ROUTINE NEST-PSEUDO ()
<COND (<VERB? EXAMINE>
<TELL "An old bird's nest tucked into the fireplace grate. Long abandoned -- like everything else here." CR>)>
<RTRUE>>
<TELL "An old bird's nest tucked into the fireplace grate. Long abandoned -- like everything else here." CR>)>>

<ROUTINE ASHES-PSEUDO ()
<COND (<VERB? EXAMINE>
<TELL "Cold grey ashes. Nothing of value." CR>)
(<VERB? SEARCH>
<TELL "You sift through the ashes. Just soot and old char." CR>)>
<RTRUE>>
<TELL "You sift through the ashes. Just soot and old char." CR>)>>

; === DISCOVERY ===

Expand Down Expand Up @@ -63,10 +61,10 @@ searched, as Zork I hides the grating under the leaves."

<ROUTINE BASEMENT-CORRIDOR-FCN (RARG)
<COND (<EQUAL? .RARG ,M-LOOK>
<TELL "The basement corridor is pitch black, stretching into shadow. Stone stairs climb [[upward->up]] into darkness.">
<TELL "The basement corridor is dim, stretching into shadow. Stone stairs climb [[upward->up]] toward the entrance hall.">
<COND (,VALVE-TURNED-FLAG
<TELL " Steam hisses from the pipes overhead, filling the corridor with an acrid mist.">)>
<TELL " To the [[east]], a passage leads toward the sound of dripping water. [[West->west]] lies what might have been storage. [[North->north]], another corridor descends toward deeper chambers." CR>)>>
<TELL " To the [[east]], a passage smells of coal and old smoke. [[West->west]] lies what might have been storage. [[North->north]], another corridor descends into total darkness, toward the sound of dripping water." CR>)>>

<ROUTINE BOILER-ROOM-FCN (RARG)
<COND (<EQUAL? .RARG ,M-LOOK>
Expand Down Expand Up @@ -518,10 +516,7 @@ ajar, so examining it swings the door wide, as opening it does."
<TELL "The machine has various dials and switches. Labels indicate voltage levels up to dangerous levels. The electrodes are stained dark." CR>
<RTRUE>)
(<VERB? TURN SWITCH-ON>
<COND (<IN? ,WINNER ,SHOCK-CHAIR>
<JIGS-UP "The switch closes with a hard ceramic snap. White fire crosses the electrodes, and the room vanishes before you can scream.">)
(T
<TELL "You throw the switch. A blue arc cracks between the empty electrodes, filling the room with the smell of scorched dust. You shut it off before the ancient wiring can do worse." CR>)>
<TELL "You throw the switch. A blue arc cracks between the empty electrodes, filling the room with the smell of scorched dust. You shut it off before the ancient wiring can do worse." CR>
<RTRUE>)
(<VERB? RUB>
<TELL "You touch one of the electrodes. It's cold and stained with something dark. You feel a faint tingle and quickly pull your hand away." CR>
Expand Down Expand Up @@ -775,11 +770,11 @@ moved: its frame sits proud of the paneling, and it swings on a hinge."
<TELL "The green light in its eyes gutters. Patient 189 shudders, mouth opening in a soundless cry. The green flames around the chapel gutter and die." CR>
<TELL "Then it speaks, in a voice like someone remembering how: 'I remember... who I was.'" CR>
<COND (<G? ,PATIENT-LORE 4>
<TELL " It looks into you, and the missing years return鈥攏ot as a story you learned, but as your own memory: the straps, Mordecai's voice, the name Patient 189 replacing yours. The figure is not your double. It is the pain they cut away from you and locked here. When you take its hand, it folds into your shadow, and for the first time since 1947 you are whole." CR>)
<TELL "It looks into you, and the missing years return鈥攏ot as a story you learned, but as your own memory: the straps, Mordecai's voice, the name Patient 189 replacing yours. The figure is not your double. It is the pain they cut away from you and locked here. When you take its hand, it folds into your shadow, and for the first time since 1947 you are whole." CR>)
(<G? ,PATIENT-LORE 2>
<TELL " It looks at you with recognition鈥攏ot as a stranger, but as someone who understands what it endured." CR>)
<TELL "It looks at you with recognition鈥攏ot as a stranger, but as someone who understands what it endured." CR>)
(T
<TELL " Its eyes pass over you without recognition. You freed it, but it never knew you." CR>)>
<TELL "Its eyes pass over you without recognition. You freed it, but it never knew you." CR>)>
<TELL "It crumbles to ash. The candles go out. The air suddenly smells like rain and grass鈥攐rdinary, living air. You're free." CR>
<SETG GAME-WON T>
<SETG PATIENT-STATE 3>
Expand Down Expand Up @@ -862,7 +857,7 @@ moved: its frame sits proud of the paneling, and it swings on a hinge."
<ROUTINE V-INJECT ()
<COND (<NOT <EQUAL? ,PRSI ,SYRINGE>>
<TELL "That is not suitable for an injection." CR>)
(<EQUAL? ,PRSO ,WINNER>
(<EQUAL? ,PRSO ,WINNER ,ME>
<JIGS-UP "The serum enters your vein like ice. For one lucid instant you remember the chapel from inside its locked door; then a green light opens behind your eyes and never closes.">)
(<NOT <EQUAL? ,PRSO ,PATIENT-189>>
<TELL "You have no reason to inject " THE ,PRSO "." CR>)
Expand Down Expand Up @@ -955,7 +950,7 @@ moved: its frame sits proud of the paneling, and it swings on a hinge."

<ROUTINE PEWS-F ()
<COND (<VERB? EXAMINE>
<TELL "The PEWS are ancient and rotting. Strange symbols are carved into the wood鈥攕ymbols that hurt to look at." CR>
<TELL "The pews are ancient and rotting. Strange symbols are carved into the wood鈥攕ymbols that hurt to look at." CR>
<RTRUE>)
(<VERB? BOARD SIT>
<TELL "You sit on one of the pews. The wood is cold and uncomfortable. The symbols carved into it seem to pulse beneath your hands, and you quickly stand back up." CR>
Expand All @@ -979,7 +974,7 @@ moved: its frame sits proud of the paneling, and it swings on a hinge."
<TELL "The candles will never burn again." CR>
<RTRUE>)>)
(<VERB? EXAMINE>
<TELL "The CANDLES burn with green flames that give off no heat. The light makes everything look diseased." CR>
<TELL "The candles burn with green flames that give off no heat. The light makes everything look diseased." CR>
<RTRUE>)
(<VERB? LAMP-OFF>
<TELL "You try to extinguish the candles, but the green flames resist. No amount of blowing can put them out. They burn with an unnatural persistence." CR>
Expand Down Expand Up @@ -1320,23 +1315,19 @@ moved: its frame sits proud of the paneling, and it swings on a hinge."

<ROUTINE INSTRUMENTS-PSEUDO ()
<COND (<VERB? EXAMINE>
<TELL "Rusty forceps and clamps lie scattered across trays. Long abandoned, like everything else here." CR>)>
<RTRUE>>
<TELL "Rusty forceps and clamps lie scattered across trays. Long abandoned, like everything else here." CR>)>>

<ROUTINE TRAYS-PSEUDO ()
<COND (<VERB? EXAMINE>
<TELL "Cold metal instrument trays sit on carts, their contents rusted and useless." CR>)>
<RTRUE>>
<TELL "Cold metal instrument trays sit on carts, their contents rusted and useless." CR>)>>

<ROUTINE BENCHES-PSEUDO ()
<COND (<VERB? EXAMINE SIT>
<TELL "Tiers of wooden benches circle the operating theater, where students once observed procedures. The wood is dark with age and moisture." CR>)>
<RTRUE>>
<TELL "Tiers of wooden benches circle the operating theater, where students once observed procedures. The wood is dark with age and moisture." CR>)>>

<ROUTINE GARDEN-BENCHES-F ()
<COND (<VERB? EXAMINE SIT>
<TELL "Broken stone benches, half-consumed by ivy and moss. Whatever respite this garden once offered ended decades ago." CR>)>
<RTRUE>>
<TELL "Broken stone benches, half-consumed by ivy and moss. Whatever respite this garden once offered ended decades ago." CR>)>>

; === LOCAL-GLOBALS ACTION HANDLERS ===

Expand Down Expand Up @@ -1365,27 +1356,23 @@ moved: its frame sits proud of the paneling, and it swings on a hinge."
(<VERB? OPEN>
<TELL "The gates are already open." CR>)
(<VERB? CLOSE>
<TELL "The hinges resist your weight. You leave the gates as you found them." CR>)>
<RTRUE>>
<TELL "The hinges resist your weight. You leave the gates as you found them." CR>)>>

<ROUTINE GRAND-STAIRCASE-F ()
<COND (<VERB? EXAMINE CLIMB>
<TELL "The grand staircase climbs toward a collapsed landing. The safe routes through the sanitarium lie east, west, north, and down." CR>)>
<RTRUE>>
<COND (<VERB? EXAMINE CLIMB-FOO CLIMB-UP>
<TELL "The grand staircase climbs toward a collapsed landing. The safe routes through the sanitarium lie east, west, north, and down." CR>)>>

<ROUTINE WALLPAPER-F ()
<COND (<VERB? EXAMINE>
<TELL "Victorian-era wallpaper depicting pastoral scenes, now grotesquely warped by moisture and black mold." CR>)
(<VERB? READ>
<TELL "Victorian-era wallpaper depicting pastoral scenes, now grotesquely warped by moisture and black mold." CR>)>
<RTRUE>>
<TELL "Victorian-era wallpaper depicting pastoral scenes, now grotesquely warped by moisture and black mold." CR>)>>

<ROUTINE COAL-DUST-F ()
<COND (<VERB? EXAMINE RUB>
<TELL "Fine coal dust coats the brick and leaves a black crescent on your fingertip." CR>)
(<VERB? TAKE>
<TELL "The damp dust is useless as fuel; the coal bin may hold something better." CR>)>
<RTRUE>>
<TELL "The damp dust is useless as fuel; the coal bin may hold something better." CR>)>>

; === CLOCK-DRIVEN ATMOSPHERIC ROUTINES ===

Expand Down Expand Up @@ -1499,13 +1486,14 @@ moved: its frame sits proud of the paneling, and it swings on a hinge."
<TELL "Score: " N ,SCORE " of " N ,SCORE-MAX " points, in " N ,MOVES>
<COND (<1? ,MOVES> <TELL " move.">) (T <TELL " moves.">)>
<CRLF>
<TELL "Rank: " <GET ,RANKINGS </ ,SCORE 20>> "." CR>
<TELL "Rank: " <GET ,RANKINGS <+ </ ,SCORE 20> 1>> "." CR>
,SCORE>

; === ENTRY POINT ===

<ROUTINE GO ()
<SETG HERE ,SANITARIUM-GATE>
<SETG VERBOSE T>
<THIS-IS-IT ,BRASS-PLAQUE>
<SETG LIT T>
<SETG WINNER ,ADVENTURER>
Expand Down
Loading
Loading