docs(mystery): spec for engine prereqs (verbs, disambiguation, ending UI) #1

Merged
ejlewis merged 19 commits from feat/engine-prereqs into main 2026-05-09 15:10:20 -05:00
Showing only changes of commit 0d9db9bb55 - Show all commits
+53 -6
View File
@@ -94,13 +94,60 @@ describe('dispatcher — go', () => {
expect(r.state.location).toBe('hallway') expect(r.state.location).toBe('hallway')
expect(r.appended.some((l) => l.text.includes('locked'))).toBe(true) expect(r.appended.some((l) => l.text.includes('locked'))).toBe(true)
}) })
})
it('opens a locked exit when required item is in inventory', () => { describe('locked exits', () => {
// Locked-exit-with-key happy path is covered by the playthrough integration function makeWorld(): World {
// test in Task 8. The sample world above doesn't have an unlocked path to return {
// pick up the brass key without first traversing the locked door, so this startingRoom: 'antechamber',
// test is intentionally a placeholder. startingInventory: [],
expect(true).toBe(true) rooms: {
antechamber: {
id: 'antechamber',
title: '[ Antechamber ]',
descriptions: { firstVisit: '.', revisit: '.', examined: '.' },
exits: { n: 'vault' },
lockedExits: { n: { requires: 'rusted-key', lockedNarration: 'The door is locked.' } },
items: ['rusted-key'],
},
vault: {
id: 'vault',
title: '[ Vault ]',
descriptions: { firstVisit: 'You are inside.', revisit: '.', examined: '.' },
exits: {},
items: [],
},
},
items: {
'rusted-key': { id: 'rusted-key', names: ['rusted key', 'key'], short: 'a rusted key', long: '.', initialState: {}, takeable: true },
},
encounters: {},
endings: { true: { whenFlags: {}, narration: '' }, wrong: { whenFlags: {}, narration: '' }, bad: { whenFlags: {}, narration: '' } },
}
}
it('blocks movement without the key', () => {
const world = makeWorld()
const state = initialStateFor(world)
const result = dispatch(state, { kind: 'go', direction: 'n' }, world)
expect(result.appended.at(-1)?.text).toBe('The door is locked.')
expect(result.state.location).toBe('antechamber')
})
it('permits movement once the key is in inventory', () => {
const world = makeWorld()
let state = initialStateFor(world)
state = { ...state, inventory: [{ id: 'rusted-key', state: {} }] }
const result = dispatch(state, { kind: 'go', direction: 'n' }, world)
expect(result.state.location).toBe('vault')
})
it('does not consume the key on passage', () => {
const world = makeWorld()
let state = initialStateFor(world)
state = { ...state, inventory: [{ id: 'rusted-key', state: {} }] }
const result = dispatch(state, { kind: 'go', direction: 'n' }, world)
expect(result.state.inventory.find((i) => i.id === 'rusted-key')).toBeDefined()
}) })
}) })