← all games
adventure-fable-unknown — GAME.md
# The Bellringer of Graywater — GAME.md
Top-down adventure/mystery vignette. You are the new bellringer of a fog-bound
harbor hamlet whose great fog-bell has gone silent the week the night ferry is
due. Your only tool is a handbell: **everything resonant in the world answers
it** — chimes chime back, hidden things rattle, NPCs react to where and when you
ring. The mystery (who silenced the bell, and why) is solved by listening.
## Central idea
One verb beyond walking/talking: **SPACE rings your handbell**. Every ring emits
a visible ripple; resonant objects inside it answer after a distance-based delay
with their own synthesized timbre and a shimmer. Ringing is sonar, lockpick, and
conversation-starter at once — secrets are found by ringing near them, the
cracked great bell answers with a dead buzz (the mystery made audible), and NPCs
comment on your ringing. Fully graspable in one press.
## Controls
| Action | Keys | Notes |
| --- | --- | --- |
| move-up/down/left/right | WASD + arrows | 8-way, normalized |
| interact | E | talk / inspect / take (via interaction addon; also advances dialogue) |
| ring | Space | handbell; ~0.8s cooldown; disabled during dialogue |
| journal | J | toggles quest journal panel |
| (dialogue) | E advance, W/S select, Space fast-forward | dialogue addon defaults |
## Zones (one continuous scene, camera-follow)
World ~2400×1500 px, 5 named zones, zone-entry title toasts:
1. **The Quay** (SW, spawn) — piers over water, Signe's harbor office, Bo
mending nets, tide pool, moored boats. Loose pier planks hide the clapper.
2. **Market Lane** (center) — shuttered stalls, wind chimes, notice board, Pip.
3. **Bell Tower Square** (N-center) — the tower with the silent great bell.
4. **Maren's Workshop** (E) — forge glow, racks of hanging bells (they chord
when rung near).
5. **The Cliff Path** (NW) — wind, old marker stone (buried cache secret),
gull nests, view to the sea.
## NPCs (all stateful; Maren & Pip most)
- **Signe**, harbormaster — gives the main quest; states: intro → waiting →
reacts to carried clapper → post-restoration gratitude. Annoyed bark if you
ring next to her.
- **Bo**, fisherman — gossip + hints; unlocks "heard someone in the tower that
night" after you inspect the bell; distinct lines when you carry the clapper
and after the finale.
- **Maren**, bell-tuner — the heart of the mystery. Deflects → confronted with
the clapper (engraved with her initials) she confesses and repairs it →
at peace after the finale.
- **Pip**, kid — side quest "Pip's Song Hunt": ring near 3 different voices
(chimes / workshop bells / tide-pool buoy) and tell Pip; counts 0–3; reward:
location of the cliff cache. Delighted bark whenever you ring nearby.
## Quests (quests addon)
- **The Silent Bell** (main): talk to Signe → inspect the great bell (missing
clapper + hairline crack) → ask around (Bo/Maren) → find the clapper (ring on
the quay piers: a rattle answers under loose planks) → confront Maren →
return and ring the great bell (finale: triple toll, fog thins, ferry horn
answers, epilogue lines everywhere).
- **Pip's Song Hunt** (side, optional).
- **Secret:** buried cache at the cliff marker stone — only glints when rung
near; contains sea-glass + an old note.
## Interactive non-quest props (curiosity rewards)
Wind chimes, tide pool (crab scuttles), notice board (3 notices), Bo's net
rack, workshop bell racks (chord), gull perches (scatter), the harbor cat
(pettable, trots toward rings), bobbing boats (inspect).
## Tech / architecture
- Packages: core, renderer, input, physics (walls/bodies; gravity 0,0), ui,
particles, effects, debug + addons dialogue / interaction / quests.
No save, no tilemap, no react. All visuals code-drawn (Graphics + runtime
`registerTexture` bakes); all audio synthesized (own WebAudio layer —
see FRICTION.md #2).
- Scene `harbor` layers: `bg` (water/ground, wave fx), `default` (world,
`ySortBy` foot offset), `fx` (rings, particles, fog below hud), plus
screen-space `ui` (UIPlugin) and `DIALOGUE_LAYERS`.
- Game state: `GameStateKey` DI service (flags, items, songs); bridged into
dialogue via `cells()` storage; quest log = quests addon; toasts/HUD via
`@yagejs/ui` UISurface.
- Src layout: `src/main.ts`, `src/scenes/HarborScene.ts`, `src/world/`
(builder, fog, zones), `src/entities/` (Player, npcs/, props), `src/game/`
(state, quests), `src/audio/` (synth, sfx, ambience), `src/ui/hud.ts`,
`src/dialogue/` (compact-DSL scripts).
## Save payload
None — vignette, no persistence.
## Assets
None on disk. Textures baked at runtime via `renderer.createTexture` +
`registerTexture` (particles, glows, fog blobs). Fonts: system stacks only.
## Status
Complete and verified. `npm run dev` (port 5175 via the repo launch config, or
Vite's default), `npm run build` passes (tsc + vite). The full main quest,
side quest, and secret were driven end-to-end with Inspector frame-stepping
(`DebugPlugin` + `window.__game` dev handle in `src/main.ts`); see FRICTION.md
for what that surfaced.
Verification notes for future sessions:
- The game does not advance in a backgrounded tab (rAF); drive frames with
`__yage__.inspector.time.freeze()/step(n)` and thaw only to screenshot.
- Dialogue advancing under stepped time needs a macrotask yield between
synthetic key taps (the runner's advance is async; see FRICTION.md #6).
- `window.__game.teleport(x, y)` moves the player (dev builds only).