From d8c9b440581b6c1439d3007e17074f0fc4b86042 Mon Sep 17 00:00:00 2001 From: Ethan J Lewis Date: Fri, 8 May 2026 23:26:45 -0500 Subject: [PATCH] feat(mystery): sample 3-room world for engine validation --- src/world/encounters.ts | 29 +++++++++++++++++++++++++++ src/world/index.ts | 14 +++++++++++++ src/world/items.ts | 28 ++++++++++++++++++++++++++ src/world/rooms.ts | 44 +++++++++++++++++++++++++++++++++++++++++ src/world/story.ts | 17 ++++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 src/world/encounters.ts create mode 100644 src/world/index.ts create mode 100644 src/world/items.ts create mode 100644 src/world/rooms.ts create mode 100644 src/world/story.ts diff --git a/src/world/encounters.ts b/src/world/encounters.ts new file mode 100644 index 0000000..5d646b7 --- /dev/null +++ b/src/world/encounters.ts @@ -0,0 +1,29 @@ +import type { EncounterDef } from './types' + +export const encounters: Record = { + rat: { + id: 'rat', + startsIn: 'cellar-stair', + initialPhase: 'lurking', + phases: { + lurking: { + description: 'A heavy rat watches you from the third step. Its eyes catch the light.', + transitions: [ + { + verb: 'attack', + target: 'rat', + narration: 'You stamp. The rat squeals and is gone into the dark.', + to: 'resolved', + }, + { + verb: 'wait', + narration: 'The rat does not move. Neither do you.', + to: 'lurking', + }, + ], + }, + }, + onResolved: { setFlags: { ratGone: true } }, + defaultWrongVerbNarration: 'The rat watches.', + }, +} diff --git a/src/world/index.ts b/src/world/index.ts new file mode 100644 index 0000000..a0118ba --- /dev/null +++ b/src/world/index.ts @@ -0,0 +1,14 @@ +import type { World } from './types' +import { rooms } from './rooms' +import { items } from './items' +import { encounters } from './encounters' +import { endings } from './story' + +export const world: World = { + startingRoom: 'foyer', + startingInventory: ['matches'], + rooms, + items, + encounters, + endings, +} diff --git a/src/world/items.ts b/src/world/items.ts new file mode 100644 index 0000000..43b5915 --- /dev/null +++ b/src/world/items.ts @@ -0,0 +1,28 @@ +import type { Item } from './types' + +export const items: Record = { + matches: { + id: 'matches', + names: ['matches', 'safety matches', 'box'], + short: 'a box of safety matches', + long: 'A small cardboard box of safety matches. Half-full.', + initialState: {}, + takeable: true, + }, + lamp: { + id: 'lamp', + names: ['lamp', 'oil lamp', 'torch'], + short: 'an oil lamp', + long: 'An iron oil lamp with a glass chimney. Currently unlit.', + initialState: { lit: false }, + takeable: true, + }, + letter: { + id: 'letter', + names: ['letter', 'folded letter', 'paper'], + short: 'a folded letter', + long: 'A folded letter on yellowed paper. The hand is unfamiliar. It reads: "Come at once. The thing in the cellar is waking."', + initialState: {}, + takeable: true, + }, +} diff --git a/src/world/rooms.ts b/src/world/rooms.ts new file mode 100644 index 0000000..06efd65 --- /dev/null +++ b/src/world/rooms.ts @@ -0,0 +1,44 @@ +import type { Room } from './types' + +export const rooms: Record = { + foyer: { + id: 'foyer', + title: '[ Foyer ]', + descriptions: { + firstVisit: + 'You stand in the foyer of a house you do not remember entering. The door behind you has closed without sound. A folded letter lies on a small table. A hallway leads north.', + revisit: 'The foyer. The door behind you is still closed.', + examined: + 'A foyer with peeling paper. A small table holds nothing but the letter. The air smells of cold stone. A hallway leads north.', + }, + exits: { n: 'hallway' }, + items: ['letter'], + safe: true, + }, + hallway: { + id: 'hallway', + title: '[ Hallway ]', + descriptions: { + firstVisit: + 'A long hallway, lit by nothing. An iron oil lamp sits on a side table. The foyer is south. A stair descends east.', + revisit: 'The long hallway.', + examined: + 'The hallway runs further than the house should be wide. The dust on the floor is undisturbed except where you have walked. The oil lamp is on the side table.', + }, + exits: { s: 'foyer', e: 'cellar-stair' }, + items: ['lamp'], + }, + 'cellar-stair': { + id: 'cellar-stair', + title: '[ Cellar Stair ]', + descriptions: { + firstVisit: + 'The stair drops into wet stone. The hallway is west. Something at the bottom is breathing.', + revisit: 'The stair to the cellar.', + examined: 'The stairs are stone, slick with damp. You can hear water below, and something else.', + }, + exits: { w: 'hallway' }, + items: [], + encounter: 'rat', + }, +} diff --git a/src/world/story.ts b/src/world/story.ts new file mode 100644 index 0000000..5fdcf9e --- /dev/null +++ b/src/world/story.ts @@ -0,0 +1,17 @@ +import type { World } from './types' + +export const endings: World['endings'] = { + true: { + whenFlags: { ratGone: true }, + narration: + 'You stand at the top of the stair. The thing below has settled. The door behind you opens, and outside, finally, is morning.', + }, + wrong: { + whenFlags: {}, + narration: '', // unreachable in sample world + }, + bad: { + whenFlags: {}, + narration: '', // unreachable in sample world + }, +}