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
3 changes: 3 additions & 0 deletions .opencode/agents/companion-author.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ Only selecting a card may execute its parser command and change game state.
- Reveal a specific solution only after the intended clue, item, or experiment
justifies it.
- Distinguish world truth from player knowledge.
- Never offer `TAKE` or `READ` for an object that is still `INVISIBLE` or
inside a closed container; offer the search of its hiding place instead
("Search the papers heaped on the desk"), and the `TAKE` once it is found.

### Validate commands empirically

Expand Down
2 changes: 2 additions & 0 deletions .opencode/agents/game-writer.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Stages 1-8 build the adventure. Stages 9-10 harden it through four independent r
6. **Define `ROUTINE GO ()` in actions.zil** — it is the game entry point.
7. **Every concrete noun in prose must resolve to a parser-accessible object** — if prose says "door", there must be an object with `SYNONYM DOOR`.
8. **Never freeze mutable state into LDESC** — use ACTION routines with M-LOOK for dynamic rooms.
9. **A glance shows only what is in plain sight** — anything hidden among, under, behind or inside something starts `INVISIBLE` (or in a container without `OPENBIT`) and is revealed by examining its hiding place; no description quotes writing or states a conclusion. See "Withholding What Must Be Examined" in `docs/WRITING_ADVENTURES.md`.
10. **Link the prose** — every actionable noun and named exit in room and object text is a `[[label]]` or `[[label->target]]` link whose target parses; `make lint-zil` must pass. See "Prose Links" in `docs/WRITING_ADVENTURES.md`.

## File Structure

Expand Down
8 changes: 7 additions & 1 deletion .opencode/agents/tester.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,13 @@ For every `A --direction--> B` edge:
- Never write `<ASSERT "..." <CO-RESUME ...> <state-check>>` — coroutine success proves nothing about state
- Use `<ASSERT-TEXT>` for output, then separate `<ASSERT>` for state transitions

#### F. Duplicate Object Audit
#### F. Discovery and Prose-Link Audit
- For every room, `LOOK` on first entry and list each object named. Anything hidden among, under, behind or inside something, anything whose writing is quoted, and any stated conclusion is a **High-severity** "revealed at a glance" defect.
- Take and drop each portable object; its `LDESC` must be a presence line, not its examine text.
- Verify every actionable noun and named exit in room and object prose is a `[[link]]`, and run `make lint-zil` (link words and each link target examined through the parser).
- Confirm suggestions and companion choices never offer an object before it is found.

#### G. Duplicate Object Audit
For each portable item type, verify exactly one interactive instance exists. Flag duplicates unless explicitly differentiated.

---
Expand Down
6 changes: 6 additions & 0 deletions .opencode/skills/bug-fixing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ Before trusting a green ZIL regression, audit its oracle: run the player command
| Missing `SEARCHBIT` | Add if container should be searchable (LOOK IN / SEARCH) |
| Object `ACTION` ends in unconditional `<RTRUE>` | Remove the catch-all true return; return true only in handled branches so OPEN/CLOSE/LOOK-IN and other defaults can run |

### Discovery / Prose Reveal

**Bug symptoms:** A room or object description names a thing that should be found by examining ("A small brass key lies among the scattered papers"). A closed or cluttered container lists its contents at a glance. A description quotes a label or states a conclusion. A moved object's `LDESC` repeats its examine text. Suggestions or companion choices offer `TAKE` for something not yet found.

**Fix:** Apply "Withholding What Must Be Examined" in `docs/WRITING_ADVENTURES.md`: `INVISIBLE` plus a reveal in the hiding place's `ACTION`, or no `OPENBIT` until the container is examined; move quoted text and deductions into `EXAMINE`/`READ`; shorten the `LDESC` to presence. Then **audit every other object in every book** for the same pattern (search the `.zil` for *among*, *under*, *beneath*, *behind*, *inside*, *tucked*, *glints*, *reads*, *label*) — one found case means the pattern was not checked. Regression: `LOOK` does not name it, `TAKE` fails before discovery, the reveal names it, `LOOK` then does.

### Action Dispatch / Silent Commands

**Bug symptoms:** A valid command produces no text and no state change, while the same object has a custom EXAMINE or puzzle handler.
Expand Down
20 changes: 20 additions & 0 deletions .opencode/skills/content-writing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ Write player-facing text and interactions that teach play and maintain tone.
Optional areas and alternate endings receive the same editorial standard as
the golden path.

18. **Withhold what must be examined.** Before writing any room text,
`FDESC`, `LDESC` or `DESCFCN`, ask of each object it names whether a
glance really takes it in. Things hidden among, under, behind or inside
something are not listed: hint at the hiding place ("Something glints
among the [[papers]]") and reveal the thing when the hiding place is
examined or searched. Never quote a note, label, diagram or inscription,
and never state a deduction, outside `READ`/`EXAMINE`. Follow
"Withholding What Must Be Examined" in `docs/WRITING_ADVENTURES.md`.
19. **Keep `LDESC` to presence.** An `LDESC` shows in every `LOOK` once the
object has moved, so it is one short line of where and what; details
live in the `EXAMINE` branch.
20. **Link the prose.** Mark every noun the reader can act on now, and every
exit the text names, with `[[label]]` or `[[label->target]]`; link the
hiding place, never the hidden thing. Targets are parser phrases
(`[[key->chapel key]]`, `[[cast->footprint cast]]`). See "Prose Links"
in `docs/WRITING_ADVENTURES.md`.

## Outputs
- Draft room and object prose set
- NPC topic/reaction matrix
Expand Down Expand Up @@ -98,6 +115,9 @@ Divide your game into thirds. In the first third, the player should encounter at
- Every emphasized clue noun and every noun used in a hint resolves through the parser exactly as written.
- Every visible feature has exactly one coherent description owner on room entry; automatic object lines neither duplicate room prose nor contradict current state.
- Every `FDESC` intended to appear automatically is on an object without `NDESCBIT`.
- No description names a thing hidden among, under, behind or inside something before it is found; no description quotes writing or states a conclusion; no container whose contents are not in plain view starts with `OPENBIT`.
- Every `LDESC` is a one-line presence statement.
- Room and object prose links every actionable noun and named exit, and `make lint-zil` passes (vocabulary, link words, and every link target examined through the parser).
- No room prose introduces a portable item that duplicates an identical item already placed elsewhere in the world; each portable object type is unique or explicitly differentiated.
- Companion labels never reveal source-only knowledge, never overpromise the
parser outcome, and provide understandable progress or recovery across every
Expand Down
17 changes: 17 additions & 0 deletions .opencode/skills/zil-implementation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ Use `PSEUDO` only for trivial one-word scenery where the handler does nothing be

`NDESCBIT` suppresses automatic LDESC listing without hiding the object from the parser. This is the correct pattern for scenery: a parseable noun that does not occupy a room-listing line.

### 0n. Hidden things start INVISIBLE; unseen contents start closed
An object hidden among, under or behind something gets `(FLAGS ... INVISIBLE)`
and stays in the room; the hiding place's `ACTION` clears the flag on
`EXAMINE`/`SEARCH`/`LOOK-INSIDE`/`LOOK-UNDER`/`MOVE` while the object is still
there, calls `THIS-IS-IT`, and prints the find with a link. A container whose
contents a glance would not take in has no `OPENBIT`; examining or searching
it sets `OPENBIT` and `TOUCHBIT` (Blackwood's `UNCOVER`). Guard every hint
("Something glints…") with the same `INVISIBLE`-and-location test. Companion
choices and walkthroughs search before they take. Add the assertions of
`test/test-prose-reveal.zil` for each hidden thing.

### 0o. Prose links are parser commands
`[[label->target]]` sends `EXAMINE target` and the object's verbs to the
parser, so the target must parse in that room. Qualify shared nouns, avoid
words the story also uses as verbs, and remember the dictionary keeps six
letters (`YELLOWED` collides with `YELLOW`). Run `make lint-zil`.

### 0j. Object ACTION routines must fall through for unhandled verbs
An object `ACTION` routine is a selective override, not a blanket handler. Return true only inside a branch that actually handles the current verb. Never put an unconditional trailing `<RTRUE>` after the routine's `<COND>`: it swallows substrate defaults such as TAKE, DROP, OPEN, CLOSE, LOOK-IN, and SEARCH and can produce silent no-ops. Let unmatched verbs return false so the default verb routine runs. After adding or editing an object action, smoke-test at least EXAMINE plus every applicable generic operation (TAKE/DROP for portable objects; OPEN/CLOSE/LOOK-IN for containers).

Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ 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.

## Playing Games

Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,13 @@ test-llm:
test-limehouse-walkthrough:
@echo "Running Limehouse Killings golden-path walkthrough..."
@lua5.4 run-zil-test.lua books/limehouse-killings/test/test-report-regressions
@lua5.4 run-zil-test.lua books/limehouse-killings/test/test-prose-reveal
@lua5.4 tests/test_limehouse_walkthrough.lua

test-wondertown-descriptions:
@echo "Running Wondertown description ownership regressions..."
@lua5.4 run-zil-test.lua books/wondertown/test/test-description-ownership
@lua5.4 run-zil-test.lua books/wondertown/test/test-prose-reveal

test-zilch:
@echo "Running ZILCH feature tests..."
Expand Down Expand Up @@ -230,6 +232,10 @@ test-pure-zil:
lint-zil:
@echo "Checking vocabulary consistency in book adventures..."
@lua5.4 scripts/check-vocab.lua books/limehouse-killings/dungeon.zil books/blackwood-horror/dungeon.zil books/wondertown/dungeon.zil
@echo "Checking prose links in book adventures..."
@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

zip:
@if [ -z "$(filter-out zip,$(MAKECMDGOALS))" ]; then echo "Usage: make zip <gamename>"; echo "Example: make zip limehouse-killings"; exit 1; fi
Expand Down
Loading
Loading