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 .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ jobs:

- name: Run unit tests
run: lua5.4 tests/run_all.lua

- name: Run new book regressions and numeric reader routes
run: make test-new-books

- name: Run Zork1 walkthrough tests
run: lua5.4 run-zil-test.lua infocom/zork1/test/zork1-walkthrough
Expand Down
32 changes: 26 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ test-unit:
@echo "Running unit tests..."
lua tests/run_all.lua

test-integration: test-zork1 test-zork2 test-game-startup test-parser test-horror-all test-limehouse-walkthrough test-wondertown-descriptions
test-integration: test-new-books test-zork1 test-zork2 test-game-startup test-parser test-horror-all test-limehouse-walkthrough test-wondertown-descriptions test-book-playtests
@echo "All integration tests completed!"

test-zork1:
Expand Down Expand Up @@ -206,7 +206,16 @@ test-horror-playtest-regressions:
test-horror-all: test-horror-helpers test-horror-partial test-horror-failures test-horror-playtest-regressions test-horror
@echo "All horror tests completed!"

test-pure-zil:
.PHONY: test-book-playtests
test-book-playtests:
@set -e; for test in books/*/test/test-round*.zil; do \
lua5.4 run-zil-test.lua "$${test%.zil}"; \
done
@set -e; for test in books/*/test/test_round*_links.lua; do \
lua5.4 "$$test"; \
done

test-pure-zil: test-new-books test-book-playtests
@echo "Running pure ZIL tests..."
@lua5.4 run-zil-test.lua zil/test-simple-new
@lua5.4 run-zil-test.lua zil/test-insert-file
Expand All @@ -233,13 +242,13 @@ 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
@lua5.4 scripts/check-vocab.lua $(wildcard books/*/dungeon.zil)
@echo "Checking prose links in book adventures..."
@lua5.4 scripts/check-links.lua books/limehouse-killings books/blackwood-horror books/wondertown
@lua5.4 scripts/check-links.lua $(patsubst %/dungeon.zil,%,$(wildcard books/*/dungeon.zil))
@echo "Examining every prose link through the parser..."
@lua5.4 scripts/check-link-targets.lua books/limehouse-killings books/blackwood-horror books/wondertown
@lua5.4 scripts/check-link-targets.lua $(patsubst %/dungeon.zil,%,$(wildcard books/*/dungeon.zil))
@echo "Playing common verbs on every object..."
@lua5.4 scripts/check-responses.lua books/limehouse-killings books/blackwood-horror books/wondertown
@lua5.4 scripts/check-responses.lua $(patsubst %/dungeon.zil,%,$(wildcard books/*/dungeon.zil))

zip:
@if [ -z "$(filter-out zip,$(MAKECMDGOALS))" ]; then echo "Usage: make zip <gamename>"; echo "Example: make zip limehouse-killings"; exit 1; fi
Expand All @@ -262,3 +271,14 @@ zip:
limehouse-killings blackwood-horror wondertown:
@true


.PHONY: test-new-books
test-new-books:
@set -e; for book in pocket-weather silent-vector last-broadcast; do \
for test in books/$$book/test/test-*.zil; do \
lua5.4 run-zil-test.lua "$${test%.zil}"; \
done; \
for test in books/$$book/test/test_*.lua; do \
lua5.4 "$$test"; \
done; \
done
74 changes: 73 additions & 1 deletion PLAYING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,48 @@ This document explains how agents (or scripts) can play ZIL games to evaluate pl

## Overview

Use `llm.lua` to interact with games one command at a time. Each invocation loads a save, executes a command, captures the response, and saves state. This works across separate process invocations — no persistent Lua state needed.
Use `llm.lua` to interact with games one action at a time. For blind testing,
use the reader's prose links and numbered menus, not invented parser commands.
The same `Session.parseLinks` and `Session:linkActions` methods power Adventure
Arena and this interface.

## Blind Link Play

Run from this repository's directory:

```bash
lua5.4 llm.lua --new-game --links --game wondertown --save /tmp/play.sav --seed 97
lua5.4 llm.lua --links --game wondertown --save /tmp/play.sav
lua5.4 llm.lua --choose 4 --game wondertown --save /tmp/play.sav
```

Output is JSON: `{output, room, running, actions}`. Each action is an array
`[label, command, linkTarget]`; `--choose N` selects its **1-based position in
the current list**. Read the result before choosing again. `--links` alone
observes menus without advancing a turn or rewriting the save. Look, inventory
and wait are explicit reader controls; inventory and native container lists
expose links to their real objects. Object menus use actual parser syntax,
including second objects and conversation topics introduced in prose. No
hidden-room inspection, source-derived hints or companion walkthrough is
added. Missing links or missing object actions are bugs to report.

Every chosen action writes the full world-memory image and scalar VM globals,
including the private random-generator state and reader presentation records.
Next invocation restores these directly, without replay. The save is required;
there is no history fallback in link mode. Lua coroutine stacks are not
serialized: play resumes at the ordinary input boundary, and `FINISH` is
recorded as terminal so a completed/dead story cannot resume normal play.
Start a fresh game after story/format changes; there are no save migrations.
`<save>.transcript` records actual commands and raw prose-link output.

For each QA round, keep the player blind to source, prior reports, maps and
walkthroughs until observations and transcript are frozen. Only then inspect
and fix the book. Label subsequent code-informed verification separately.

## Parser Diagnostics

The free-text interface below remains useful for focused parser regressions.
It is not evidence of a blind link-only completion.

## Quick Start

Expand Down Expand Up @@ -104,6 +145,7 @@ Pass `--game <name>` to play different games:
| planetfall | `infocom.planetfall.planetfall` |
| limehouse-killings | `books.limehouse-killings.limehouse-killings` |
| blackwood-horror | `books.blackwood-horror.blackwood-horror` |
| wondertown | `books.wondertown.wondertown` |

## Command-Line Reference

Expand Down Expand Up @@ -146,6 +188,36 @@ complete room/state-family coverage and validation requirements.

## Evaluating Playability

### Authoring binary reader actions

The portable reader lives in `zilscript/reader/`. Both the standalone CLI and
Adventure Arena use this implementation; running book regressions never requires
a checkout of the application repository beside ZILScript.

The reader uses current VM scope, including carried contents, to resolve a
prose link. A remembered noun alone never grants remote manipulation. Topics
must resolve through the story's current globals or actual accessible objects.
Several prose aliases for the same object produce one secondary action.

An object can constrain its binary menu with an ordinary string property:

```zil
(INTERACTIONS "STEAM:KETTLE,SPOON;SHOW:MICA,CLOUD")
```

Keys are action identifiers, the suffix of the real `V-...` action (`PUT-ON`
differs from `PUT`). Values are declared object names. Missing actions in an
authored property have no binary menu entries; an empty string allows unary
actions only. Actors list the carried exhibits they accept for reversed
SHOW/GIVE menus. These relations filter offered pairs without executing an
action, changing world state, bypassing parser scope, or exposing hidden nouns.
Include meaningful failed experiments as well as correct pairs. Ordinary
parser commands still use the story's own action routines and rejection logic.

Books using the link reader finish with the score/progress record and a native
QUIT signal; the reader does not display unsupported parser restart prompts.
The persisted debug snapshot remains terminal across fresh invocations.

To assess whether an LLM can play and beat a game:

1. Start a new game
Expand Down
17 changes: 17 additions & 0 deletions books/COVER-PROMPTS-2026-10-24.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# New book covers — 24 October 2026

Generated with the built-in imagegen tool. Final PNG files were copied into
`apps/adventure-arena/assets/` and visually inspected at full size. All three
show the correct title and Studio Null credit. No existing cover was replaced.

## pocket-weather.png

Use case: illustration-story. Asset type: finished portrait book cover, 2:3. Title verbatim "THE POCKET WEATHER BUREAU"; small author "STUDIO NULL". A warm, richly painted children's adventure cover: a tiny young apprentice with a raincoat on a rooftop weather bureau, holding a brass weather instrument; a little raincloud floats nearby with a quiet personality and tiny raindrops. Imaginative rooftop town, handmade weather instruments, warm amber windows against a lovely teal sky. Whimsical ink and gouache storybook painting, sophisticated shapes and exquisite atmospheric texture, readable clean typography, visually inviting for ages 8-12. Strong central silhouette reads at thumbnail scale. Not a mockup: flat complete cover art filling frame, no border, no extraneous text, no watermark.

## silent-vector.png

Use case: illustration-story. Asset type: finished portrait science-fiction horror novel cover, 2:3. Title verbatim "THE SILENT VECTOR"; small author "STUDIO NULL". An isolated orbital research station corridor, austere and physically plausible; a single suited technician silhouette, distant observation window with black space, an ominous subtle signal waveform reflected across the window that almost resembles a human profile. Horror of an intelligence altering memory, oppressive isolation, no monsters or gore. Elegant literary sci-fi art, painterly cinematic realism, cold petrol blue and near-black with a restrained red emergency light, strong distinctive composition, beautiful negative space, very readable modern title typography. Flat complete cover filling frame, no 3D book mockup, no watermark, no additional words.

## last-broadcast.png

Use case: historical-scene. Asset type: finished portrait Golden Age mystery novel cover, 2:3. Title verbatim "THE LAST BROADCAST"; small author "STUDIO NULL". An atmospheric 1936 island radio station at night: large period brass-and-chrome broadcast microphone and a lacquer transcription disc in foreground, a narrow illuminated radio studio window and remote lighthouse silhouette beyond stormy dark sea. Elegant painted art deco / screenprinted literary mystery cover, textured navy ink, amber lamplight, muted ivory and rust accents. Suggest a murder hidden in a recorded alibi through sound equipment, no visible violence. Sophisticated graphic storytelling and bold readable period typography; rich scene but strong thumbnail silhouette. Flat complete cover filling frame, no 3D mockup, no watermark, no extra text.
Loading
Loading