feat(world): add the Lost Twins optional escort side-quest

Two separated brothers, Marlon (conservatory) and Malte (boiler room), can be
reunited as optional content. Carry each twin's marble to the other as proof
he's alive and that twin follows you; lead both to the foyer and they escape
together, granting a Brass Compass keepsake and unlocking a new top-priority
"No One Left Behind" ending. Purely optional — no main win condition depends
on it.

The new EscortEngine drives following and the foyer reunion from flags alone,
so save/load needs no format change (it reconciles follower placement on the
first tick after loading). Adds Room.removeNpc, one tick call in the game loop,
and a follower note appended by LookCommand. descriptionStates swap the twins'
home-room prose once they leave.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 10:31:25 +02:00
parent f8f7eb90f0
commit 41c79c3b96
10 changed files with 379 additions and 5 deletions

View File

@@ -74,11 +74,18 @@
description: |
A glass-roofed room choked with dead ferns. Rusted plumbing lines the
walls, and a heavy iron valve wheel has been left on a potting bench.
A frightened young man cowers among the planters, a blue marble in his fist.
music: manor-theme.ogg
exits:
south: dining_room
items: [valve_wheel]
npcs: []
items: [valve_wheel, marlon_keepsake]
npcs: [marlon]
descriptionStates:
- when: [{ flag: marlon_following }]
text: |
A glass-roofed room choked with dead ferns. Rusted plumbing lines the
walls, and a heavy iron valve wheel has been left on a potting bench.
The corner where the frightened young man crouched is empty now.
- id: grand_staircase
name: Grand Staircase
@@ -135,13 +142,20 @@
name: Boiler Room
description: |
A cramped stone room behind the furnace. A rusty generator squats in the
corner, an empty fuse socket gaping in its housing.
corner, an empty fuse socket gaping in its housing. A shivering young man
huddles against the cold iron, a red marble clenched in his hand.
music: cellar-drone.ogg
dark: true
exits:
east: cellar_stairs
items: [generator]
npcs: []
items: [generator, malte_keepsake]
npcs: [malte]
descriptionStates:
- when: [{ flag: malte_following }]
text: |
A cramped stone room behind the furnace. A rusty generator squats in
the corner, an empty fuse socket gaping in its housing. The cold spot
by the iron where the shivering man huddled is empty now.
# ── Upper floor (reachable only once the power is on) ───────────────────────