Museum ambience, reader sounds, and automatic doors
Status: IMPLEMENTED (issue #28, 2026-08-12; owner round two 2026-08-13). The controller lives in src/inception/audio/museumSoundController.ts over the pure rules in src/inception/audio/museumSound.js; the corridor portal doors and in-room return doors carry the automatic inside-out aperture; the Menu has a Background sound volume slider whose zero mutes every museum sound. Rooms have no ambient bed; their R readers and boundary doors may play the short interaction effects below. This plan does not add narration to the museum runtime.
Experience rule
- Museum corridors carry a very quiet deep-space air/noise bed.
- Enclosed exhibit rooms have no ambient sound.
- ANY visitor — the local player or a networked one — approaching a door opens it automatically and plays one short opening sound, whether or not they go on to enter. The room title above a door is always readable.
- Opening and closing the R reader plays one short holographic gesture each.
- The Menu has one Sound volume slider, and it moves EVERY museum sound — the bed, the door effects, the reader gestures, and any future non-narration sound. 100% is the museum's own mix, 0 mutes it, and it goes to 200% for a quiet room or a laptop speaker (owner round nine).
- Sound supports the space; it must never become the main event.
The generated review assets are:
content/inception/assets/audio/museum/deep-space-ambience-loop-v1.mp3content/inception/assets/audio/museum/door-open-energy-v1.mp3content/inception/assets/audio/museum/reader-open-hologram-v1.mp3content/inception/assets/audio/museum/reader-close-hologram-v1.mp3
They are deterministic procedural originals generated by scripts/generate-museum-audio.mjs; no third-party recording or model output is involved.
Deep-space ambience
The ambience is filtered, pink-leaning noise with a barely perceptible low body and no melody, voice, alarm, impact, or repeating rhythmic event. The source loop is 24 seconds and is crossfaded at the sample level for a clean loop.
Runtime rules:
- Start only after a user gesture satisfies browser audio policy.
- Fade in over 1.5 seconds; fade out over 0.8 seconds.
- Target an intentionally quiet perceived level, approximately 24–30 dB below ordinary narration. Begin with runtime gain
0.20; tune by ear on laptop, headphones, phone, and iPad rather than normalizing it louder. - The bed is the museum's REFERENCE LEVEL: every short effect is mixed as a multiple of it (
EFFECT_LEVELS), and its runtime gain is computed from the peak its own bytes were normalized to (ASSET_PEAK). Hand-set gains had the door arriving at thirteen times the bed (owner round eight); the door is now 3x and the reader gestures 2x. Re-normalizing an asset changes its gain, not its loudness in the room. - Play only while the local visitor is in the main museum corridor or another explicitly declared deep-space corridor zone.
- Do not play inside Van Gogh House or any other exhibit room. Whether the Van Gogh learning corridor should inherit this sound is a curator decision; default it to silent because its visual course already carries a guided narration in the demo.
- Keep one shared loop and one gain node. Do not create an audio element per corridor segment.
- Pause when the page is hidden and resume with a fade, not from a new random point.
Automatic door behavior
Opening is a visual state, not an automatic teleport. The visitor approaches, the door clears, and crossing the existing portal plane begins the existing transition.
Use a small state machine per local active door:
closed → opening → open → closing → closed
- Begin opening when ANY visitor — local or networked — is within range of the door rectangle (owner round two: no facing requirement; everyone in the space sees the same door answer whoever walks up to it, whether or not they enter). The range depends on where the door is: 3.0 m in the corridor, where a door is something you cross toward, and 1.5 m for a room's own way out (owner rounds eight and nine) — inside a place you are standing in, a door opening metres off reads as the room reacting to you.
- Keep it open until every visitor is beyond 3.6 m (2.1 m in a room). The wider close threshold is hysteresis; it prevents a door and sound from chattering at one distance.
- The opening animation should take about 0.65–0.9 seconds and dissolve FROM THE INSIDE OUT: a clear aperture grows from the door's centre with a soft rim, not a uniform whole-sheet fade and not hinged metal-door motion.
- The room title (nameplate) above a door is ALWAYS shown — it no longer breathes or fades with its door.
- Play the opening sound once on the
closed → openingtransition — never once per frame or on the closing transition. The level the LOCAL device plays it at is attenuated by the local player's own distance to that door (full within 3 m — as far as a corridor door opens — and silent beyond 20 m), so a remote visitor's far door is a whisper. - Add a per-door local cooldown of at least 1.5 seconds between SOUNDS; the door's motion itself never refuses.
- A muted Background sound setting (volume zero) suppresses playback but does not change door movement or portal behavior.
- A room still loading remains sealed. Approaching may show a quiet loading response, but it must not open into an unloaded space or play a false success sound.
- The Van Gogh connector keeps its own reviewed distance curve and remains local-only.
R reader interaction sounds
- A real closed-to-open R reader transition plays the 0.46-second rising holographic gesture once.
- Closing an open reader by R, Escape, the visible Close control, walking out of range, or leaving the room plays the 0.34-second folding gesture once.
- Maximize, Restore, scrolling, and replacing content inside an already open reusable panel do not play either sound.
- The guided Demo's scripted readers and narration remain unchanged; these cues belong to the visitor-triggered R reader in the museum runtime.
- The effects are quieter than the door and much shorter than narration. They contain no speech, melody, alarm, or sharp click.
- The existing Menu Sound: On / Off preference silences both reader effects immediately. A failed or still-loading audio buffer never blocks the reader.
Menu and persistence
- One Sound volume slider in the existing Menu (owner round two supersedes v1's plain On/Off switch; round nine widens it to everything), not a separate floating HUD.
- It scales EVERY museum sound: the bed through the next frame's fade, the short effects on their shared bus — including one already in flight. 0% mutes the museum, 100% is its own mix, 200% is the ceiling.
- Default to the mix for a new visitor, but do not autoplay until a real gesture. Older settings carry forward: v1's Off reads as muted, v2's bed-only percent reads as the same number for everything.
- Persist the preference locally under a versioned museum setting key (
inception.sound.v3, an integer percent). - The setting must be available to keyboard, pointer, and touch, announce its value to assistive technology, and update audio immediately.
Architecture
Create one reusable museum audio controller owned by the main runtime:
- lazy Web Audio context or equivalent browser-safe audio layer;
- one loop source/gain path for ambience;
- a small reusable pool for short effects;
- explicit
setZone,setVolume,doorOpened,readerOpened,readerClosed,suspend, anddisposemethods; - no independent animation or timer loop; transitions use the museum's frame clock or Web Audio automation;
- failed audio loads are silent and non-blocking.
Asset URLs should be build-resolved and content-local. Published room documents must not supply arbitrary audio URLs. A future room-specific sound requires a reviewed asset registry and a schema decision; it is outside this batch.
Acceptance criteria
- The corridor loop begins only after user interaction, stays subtle, loops without a click, and fades out before entering a room.
- Every exhibit room has no ambient bed; only its boundary door and an explicitly opened/closed R reader may play short effects.
- Volume zero immediately silences all museum ambience/effects and survives a reload; raising it resumes the bed only where the active zone allows it, and the slider scales the bed alone.
- One R open produces one opening gesture and one actual close produces one closing gesture; Maximize/Restore, the image view, and redundant cleanup calls stay silent.
- One approach produces one opening sound — from the local player or a networked one, entering or not — at a level set by the local player's own distance. Standing near or crossing back and forth inside the hysteresis band produces no repeated sound.
- A loading or failed room never opens early.
- Page hide/show, room unload, sign-in UI, and runtime disposal leave no orphan audio playing.
- Tests cover zone changes, menu persistence and migration, autoplay rejection, fades, hysteresis, cooldown, nearest-visitor triggering with local-ear attenuation, and silent failure.
- Manual QA includes speakers and headphones at normal system volume; if the ambience is the first thing a reviewer notices, it is too loud.
High-level LOE
| Work | LOE |
|---|---|
| Shared audio controller, asset loading, fades, lifecycle | 1.5–2.5 days |
| Menu toggle and persistence | 0.5–1 day |
| Generic automatic-door state and integration | 1.5–3 days |
| Tests and multi-device/manual audio QA | 1–2 days |
Total: approximately 4.5–8.5 engineering days, depending on how many door types are unified in the first implementation.