Commit Graph

29 Commits

Author SHA1 Message Date
ejlewis 52fb869976 feat(mystery): add altered rooms and drunk sequence 2026-05-12 20:22:20 -05:00
ejlewis 0755213d6a feat(ui): add confirmations and terminal motion
ci/woodpecker/push/woodpecker Pipeline was successful
2026-05-12 19:44:18 -05:00
ejlewis cc98aa180b feat(world): expand Halfstreet content slices
ci/woodpecker/push/woodpecker Pipeline was successful
2026-05-12 14:48:19 -05:00
ejlewis 26dd91947f feat: add kitchen and glitchtip wiring
ci/woodpecker/push/woodpecker Pipeline was successful
2026-05-10 12:03:12 -05:00
ejlewis 4d9077d586 feat(world): add light timer and indicator
ci/woodpecker/push/woodpecker Pipeline was successful
2026-05-10 10:17:42 -05:00
ejlewis d56c0c8363 Implement match interactions and wait chip
ci/woodpecker/push/woodpecker Pipeline was successful
2026-05-10 07:56:31 -05:00
ejlewis 83e4877852 feat(content): add upper floor slice 2026-05-10 07:34:51 -05:00
ejlewis 33933b00d7 fix(mystery): improve mobile terminal and chips
ci/woodpecker/push/woodpecker Pipeline was successful
2026-05-10 05:53:32 -05:00
ejlewis 2a9b6155ef feat(mystery): add opening and main-floor content 2026-05-09 21:51:12 -05:00
ejlewis 19d1efc586 feat(engine): detect endings on every successful turn
After each state-mutating dispatch, evaluate world.endings in priority
order (true > wrong > bad). The first whose whenFlags are all satisfied
sets state.endedWith and appends a kind:'ending' transcript line. Once
ended, further dispatches return a "story has ended" narration.

Also update test-world fixtures and placeholder ending markdown files
to use whenFlags: { _never: true } instead of {} so that vacuously-true
empty flags don't accidentally fire on every successful turn.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 14:53:07 -05:00
ejlewis 0d9db9bb55 test(engine): self-contained locked-exit fixture replaces the stub
Verifies blocked movement, key-permitted passage, and that the key is
not consumed by passing through.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 14:42:22 -05:00
ejlewis b870d884ef feat(engine): wire verb-target-prep — explicit \light X with Y\ and \use\ routing
light X with Y validates the named instrument and reuses handleLight.
use X / use X on Y route through the encounter dispatcher; if no encounter
consumes it, the dispatcher narrates the fallback. The encounter matcher
also rejects transitions whose required item doesn't match the typed
instrument, so a mistyped instrument fails cleanly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 14:22:03 -05:00
ejlewis 8401e7d281 feat(engine): light/extinguish verbs with implicit lighter selection
\`light X\` finds a lighter (item with lighter:true and remaining state.uses)
in inventory, decrements its charges, and toggles target.state.lit. The
target's litText / extinguishedText / the lighter's lighterEmptyText
provide narration. Refuses politely on each error path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 14:18:54 -05:00
ejlewis dac8487dbe feat(engine): read verb narrates item.readableText
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 14:15:35 -05:00
ejlewis ab8c17fdd5 feat(engine): dispatcher handles ambiguous parses with a disambiguation prompt
Sets pendingDisambiguation on state and emits "Which X — A, or B?" using
each candidate item's short text. The existing disambiguation reply path
then re-issues the original verb against the chosen target.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 13:58:32 -05:00
ejlewis b318747840 feat(parser): emit verb-target-prep on 'with'/'on'/'in'/'to' separators
Enables `light lamp with matches`, `use shears on vines`, and similar
multi-noun forms. Both the target and indirect noun must resolve;
otherwise the command falls back to unknown-noun.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 13:56:19 -05:00
ejlewis 46f851bc3a feat(parser): return ambiguous variant when noun matches multiple aliases
Replaces the previous behavior of returning unknown-noun. The dispatcher
will use this in the next commit to prompt the player to disambiguate.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 13:53:38 -05:00
ejlewis b325f04b02 feat(parser): strip leading stop-words (at, the, a, an) from noun phrase
Allows `look at lamp`, `examine the letter`, `take a key`, `take an oil lamp`.
Stop-words are only removed from the head of the noun phrase, not from
anywhere in the middle.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 13:36:34 -05:00
ejlewis 14a58481b1 refactor(engine): theme is a UI preference; remove it from GameState
Previously, clicking the theme button updated localStorage and the DOM but
not state.theme, so the engine's `theme` meta-verb toggled from stale state.
Theme is now exclusively UI/storage concern. Old saves with the field still
load; the field is silently ignored.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 13:33:57 -05:00
ejlewis 657ed22b48 refactor(engine): drop redundant string[] casts now that RoomState includes arrays
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 13:30:35 -05:00
ejlewis 6cffb87a63 feat(engine): widen state value unions and add 'ending' transcript kind
Drops redundant string[] casts in dispatcher paths and prepares the
TranscriptLine kind for the ending-screen render path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 13:28:14 -05:00
ejlewis 33bc84e30b fix(mystery): wait verb routes to encounters; chip list reflects dynamic items
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:37:45 -05:00
ejlewis 460626aad9 test(mystery): end-to-end playthrough against sample world 2026-05-08 23:32:33 -05:00
ejlewis 49fc5a1015 feat(mystery): encounter phase machine wired into dispatcher 2026-05-08 23:18:22 -05:00
ejlewis 00f44ce817 feat(mystery): dispatcher — go, look, take, drop, examine, inventory
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:56:11 -05:00
ejlewis bd6b421ce9 feat(mystery): save layer — round-trip, schema versioning, transcript cap 2026-05-08 22:50:47 -05:00
ejlewis bf9e210b88 feat(mystery): parser — noun resolution, disambiguation, pronouns 2026-05-08 22:44:43 -05:00
ejlewis b59644270e feat(mystery): parser — verb-only, direction, and meta commands 2026-05-08 22:38:17 -05:00
ejlewis 7ee5cf96f6 feat(mystery): define engine and world type contracts 2026-05-08 22:31:36 -05:00