RELEASE
planning/2.8.0/audits/IMMERSION_AUDIT.md
sha256 a09f3d003e0de438 · 47889 bytes ·
original held in the private archive
# IMMERSION_AUDIT.md — "Living Terminal" Design Audit of the Parked Roadmap
> **FILED UNDER 2.8.0 — PRODUCED-BY, NOT MEASURED-VERSION.** This document *measures* an earlier codebase
> (see its baseline stamp below), but it was *produced* as part of the audit/planning phase that became the
> 2.8.0 overhaul. Planning artifacts are filed by the release whose work produced them, never by the version
> they discuss. The version in the title or baseline is the code it examined, not the folder it belongs in.
> (A 2.5.0 and 2.6.0 folder do exist, holding feature designs for features that shipped in those releases. There
> is no 2.7.0 folder because no artifact has been identified as produced during 2.7.0.)
> **ANALYSIS ONLY. Nothing implemented, committed, or pushed. No parked plan modified. No served code written.**
> Started clean from `origin/dev` (`git fetch && git checkout dev && git reset --hard origin/dev`).
> Grounded on `dev` @ `027be1b` (v2.7.0, cache `robco-terminal-v2.7.0-r5`, 1557 tests / 130 suites).
> Every idea is grounded in files/functions actually read on `dev` (line refs inline).
>
> **Charge:** make the RobCo U.O.S. terminal feel like a *real, living piece of Fallout technology that has always
> existed inside the wasteland* — not a website. Immersion above all. This DEEPENS the two parked plans; it does not
> replace them and does not duplicate the sibling docs.
>
> **Sibling docs built upon (read first, deliberately NOT re-treaded):**
> - `ROADMAP_AUDIT.md` — the general re-baseline + 15 consolidation/architecture/tech-debt enhancements. *This doc is the
> immersion counterpart: where ROADMAP_AUDIT consolidates duplicate work, IMMERSION_AUDIT deepens the felt experience.*
> - `WASTELAND_UPLINK_SPEC.md` — the unified ambient living-world engine (world-clock + seeded-roll + local bank; PUSH
> broadcasts / PULL radio / map encounters / INTERCEPT AI-augment). **This is the substrate most ideas below plug into.**
> - `FEATURE_REMAKES.md` — the four screen rebuilds (Phosphor Cartography map, Targeting-Silhouette VATS, Manifest &
> Loadout inventory, Streaming Narrator). *These rebuild screens; the ideas below add ambient/atmospheric dimensions
> those rebuilds don't cover.*
> - Chain-1 sources also read: `RECREATION_IDEAS.md` (Boot MOTD / Attract Mode / Recon-Grid / UPLINK), `AI_SLATE.md`
> (INTERCEPT / RADIO banter / COMPANION / SCAN / OVERSEER), `CAPABILITY_SLATE.md` (device caps; hacking minigame /
> gyro / TTS / share-target held for v2.8.0), `GAME_THEMING_AUDIT.md` (per-game GT-1..GT-5), `DIEGETIC_AUDIT.md`
> (HOUSE_STANDARD voice), `CONTENT`/`CLOUD`/`PERFORMANCE`/`ACCESSIBILITY` audits.
---
## 0. The immersion thesis — three levers the parked plans under-use
The re-baseline in ROADMAP_AUDIT already established *what* is built (all 6 native calculators, all 9 device caps,
theming GT-1/2/3, the fog-of-war map, the ambient-engine spec). The **felt-immersion residue** — the gap between "a
tactical companion webapp" and "a RobCo terminal that has always sat in this Vault" — concentrates on three levers the
parked steps mention only in passing:
1. **CONTINUITY / MEMORY — "the terminal remembers me."** The app already computes rich, *buried* telemetry it never
surfaces at the moment of attention: the Overseer's Log device stats (`renderOverseerLog`, `ui-core.js:187`; boot
count / longest session / total power-on), the campaign session stats (`renderSessionStats`, `ui-render.js:601`;
kills / caps / damage / location-visit count), a permanent fog-of-war trail (`state.locationHistory`), and — crucially
— a **full in-universe calendar** (`_resolveGameDateTime`, `ui-render.js:265`: weekday / month / day / year off
per-game epochs FNV Oct 19 2281, FO3 Aug 17 2277). None of this feeds the boot screen, the radio, or the standby
cycle. The terminal computes a memory of your playthrough and then hides it.
2. **AMBIENT LIFE — "the wasteland ticks on its own."** WASTELAND UPLINK is the substrate for this, but its parked spec
treats day/night, weather, radio, and encounters as generic tables. The living-world signal gets far stronger when
the ambient bank is keyed off **where you actually are** (map zone-type: vault / settlement / wilderness / cave — the
`zones[]` data already carries this) and **when you actually are** (the in-world calendar/date, not just the
`ticks%240` hour). The hooks exist (`appendToChat(...,'sys',true)` no-persist push at `ui-core.js:2617/2657`; 15
zero-byte synth voices in `ui-audio.js`; disjoint `ambient-*` body classes); the parked plan just doesn't wire them
to place and date.
3. **REACTIVE PHYSICALITY — "this is a physical CRT that feels the world."** The body-state class layer
(`updateMath`, `ui-core.js:2350–2483`) already flickers on rads, sags on weight, flashes on karma/crit-HP, and dims
on standby. WU-F2 haptics + WU-F6 degraded-boot already treat the terminal as a physical object. But the *cumulative*
campaign never registers on the glass, standby is a plain dim, and the idle-focused screen is dead. The instruments
are all in the orchestra (RECREATION_IDEAS' phrase); nothing conducts them to react to the arc of a playthrough.
**The 15 ideas below are organized around those three levers.** Every one EXTENDS a parked item or an existing system,
adds a felt dimension the siblings don't, is offline-safe + game-agnostic (Protocol 38) + gate-guarded, and honors the
"writes nothing durable unless it's a real gameplay action" discipline the UPLINK spec locks in. None bumps
`APP_VERSION` without owner approval; each served-file change is a single `CACHE_NAME` `-rN` bump (Protocol 1).
**Emergent-behavior map (which existing systems combine).** The strongest ideas are where systems *cross*:
| Idea | State/systems it reads | Existing hook it drives | Emergent "aliveness" |
|---|---|---|---|
| #1 Calendar & anniversaries | in-world date + loc + factions | UPLINK bank · boot · radio | the wasteland has a *today* |
| #2 Continuity readout | Overseer Log + campaign + calendar + quests | boot POST splice | boot greets *you* |
| #3 Location-aware ambience | `state.loc` + zone-type + hour | synth audio + UPLINK push | places *sound* different |
| #4 Personal-legend news | quests + factions + `state.stats` | radio/UPLINK bulletins | the world *talks about you* |
| #5 Overseer incident log | kills / near-death / faction / days | Overseer Log panel | the terminal *witnesses* your run |
| #9 Faction ambient signals | reputation matrix + loc | UPLINK push + map ping | your standing has *presence* |
| #15 Standby "power-down" | calendar-elapsed + UPLINK | standby/wake path | leaving & returning *means something* |
---
# THE 15 IMMERSION ENHANCEMENTS
*Exactly 15. Immersion-first, each a natural extension of the parked roadmap + a real system. Complexity Low/Medium/High.
"Placement" is a recommendation for owner review, not a commitment. No filler; none duplicates a sibling doc's slot.*
---
## 1. Wasteland Calendar & Anniversaries — the terminal knows what *day* it is
- **Builds on:** WASTELAND UPLINK day/night substrate (`WASTELAND_UPLINK_SPEC` §5.4 + ROADMAP #2); Boot MOTD
(`RECREATION_IDEAS` Idea 1); the **already-shipped in-world calendar** (`_resolveGameDateTime`/`formatGameTime`/
`getGameDate`, `ui-render.js:265–334`; per-game epochs in `GAME_DEFS[ctx].calendar`, `state.js:314/413`).
- **The enhancement:** The UPLINK spec's world-clock only reads the *hour* (`ticks%240`). But the terminal already
computes a full absolute date — **weekday, month, day, year** — from per-game epochs. Extend the ambient bank so
broadcasts, radio bulletins, and the boot readout can template on the real in-world **date and weekday**, and add a
tiny data-only `GAME_DEFS[ctx].ambient.almanac` table of **date-keyed wasteland observances**: the Great War
anniversary (Oct 23), a Mojave Express "payday", a New Vegas "founding", Capital-Wasteland dates for FO3, seasonal
cues (a "long cold night" broadcast in deep winter months). On a matching date the UPLINK push / radio surfaces one
in-voice line (`> [WASTELAND UPLINK] 208 YEARS SINCE THE FLASH. STAY IN THE LIGHT.`); on any other date it's silent.
All copy is templated from live state at emit time; nothing persisted.
- **Why it feels alive:** A wasteland that has a *today* — a weekday, a date, an anniversary — is dramatically more
inhabited than one that only has "day" and "night". It rewards long campaigns (you'll roll past a real anniversary),
it's environmental storytelling per-byte, and because the date is derived from *your* `ticks`, two players on
different in-game days get different worlds. This is the single cheapest "always existed in Fallout" lever and no
sibling doc uses the calendar at all.
- **Gameplay / UX benefits:** Gives the buried `formatGameTime` output a second surface (boot + radio, not just the
Bio-Metrics readout); makes advancing `ticks` feel consequential; zero new input burden.
- **Complexity:** **Low–Medium.** A data table + a date-match helper feeding the existing UPLINK bank; no new subsystem.
- **Placement:** **v2.8.0** (rides the UPLINK U1/U2 substrate + the Boot MOTD unit).
- **Dependencies / architecture:** UPLINK bank shape (`GAME_DEFS[ctx].ambient`, ROADMAP #2/#12); the shipped calendar
helpers (read-only); Protocol 38 (almanac is per-game data, FO4 = a new block); fallout.wiki sourcing for real dates
(Protocol 3); the UPLINK "writes nothing durable" guard covers it (§7). No `APP_VERSION` bump.
---
## 2. Session-Resume Continuity Readout — deepen the Boot MOTD into a "welcome back, Courier"
- **Builds on:** RECREATION_IDEAS Idea 1 (single-line Boot MOTD); WU-F7 Overseer's Log (`renderOverseerLog`,
`ui-core.js:187`); the campaign state (`_pendingDirectivesCount`, `ui-core.js:1100`; `state.loc`/`rads`/`quests`); the
in-world calendar (#1); the per-game boot splice already at `ui-audio.js:1049` (`runBootSequence`, 120 ms cadence).
- **The enhancement:** RECREATION Idea 1 proposes *one* MOTD line. Deepen it into a short, fail-safe **SESSION RESUME**
block spliced into the POST — a genuine continuity readout that reads *four* subsystems at once: time since last
uplink + boot count (Overseer Log), active-directive count (`_pendingDirectivesCount`), current location + rad buffer
(campaign), and **days-in-the-wasteland** (from the calendar day-offset). First-ever boot instead prints
`> NEW OPERATOR PROFILE — NO PRIOR TELEMETRY`. Everything wrapped in `try/catch` → any absent/corrupt shape degrades
to *no* readout, boot never throws. Example:
`> LAST UPLINK 2H14M AGO · DAY 47 IN THE MOJAVE · 3 ACTIVE DIRECTIVES · GOODSPRINGS · RAD BUFFER NOMINAL`.
- **Why it feels alive:** The boot screen is the single most-repeated surface in the app and today it says nothing about
*you*. Making the terminal's first words a précis of your own campaign is the strongest "it remembers me" beat
available, and it surfaces the Overseer/session telemetry at the exact moment of attention (today it's buried in a
DATA-tab panel almost nobody opens).
- **Gameplay / UX benefits:** Zero-friction orientation on return ("where was I, what's pending"); reinforces the
continuity fantasy; pure phosphor text on the existing reduced-motion-safe cadence.
- **Complexity:** **Low.** One `_bootMotdBlock()` reading two localStorage shapes + `state`, spliced beside the WU-T3
identity line; fail-safe.
- **Placement:** **v2.8.0** (coordinates with WU-F6 boot + the UPLINK date read #1).
- **Dependencies / architecture:** Couples `ui-audio.js` boot to the `robco_v8` + `robco_overseer_log` shapes (mitigated
by `try/catch`); read-only, offline → no kill-switch; game-agnostic (all from state/GAME_DEFS, no game literal);
Suite guard: renders with prior telemetry, without it (fresh profile), and with a corrupt `robco_v8` (block omitted,
boot survives).
---
## 3. Location-Aware Ambience — the wasteland *sounds and reads* different where you stand
- **Builds on:** WASTELAND UPLINK U2/U3 (weather + radio + broadcasts); the 15 zero-byte synth voices
(`startCrtHum`/`setGeigerRate`/ambient in `ui-audio.js`); the map zone data (`zones[]` with implicit type — vault /
settlement / landmark / base / factory / cave — read by `renderWorldMap`, `ui-render.js:1225`); `state.loc`.
- **The enhancement:** Today the CRT hum + geiger baseline are driven only by `rads`. Extend the UPLINK engine so the
ambient layer reads the **zone-type of your current location** and shifts the *baseline* atmosphere: a **vault** adds a
faint sub-bass reactor drone (reuse `setCrtHumIntensity` frequency shift) + a slightly higher idle geiger tick; a
**settlement** biases UPLINK broadcasts toward market/townsfolk chatter templates; **wilderness** toward wind/distress;
a **cave/factory** toward drips/machinery + darker tint. All expressed through *existing* transient hooks (hum
frequency, `setGeigerRate` blip, `ambient-*` classes, broadcast template selection) — nothing new synthesized, nothing
persisted, real rad classes always outrank cosmetic ones (UPLINK §4 arbitration).
- **Why it feels alive:** "Places sound different" is one of the deepest immersion cues a terminal can have — a vault
humming under you vs. open Mojave wind makes `state.loc` a *sensory* fact, not a text field. It turns the map's dormant
zone-type data into felt atmosphere and gives the ambient engine a reason to vary that isn't just a timer.
- **Gameplay / UX benefits:** Rewards travel; makes the location field meaningful beyond the map; entirely passive (no
input); degrades to silence under mute / intensity-off.
- **Complexity:** **Medium.** A zone-type → ambience-profile map (data) + wiring the UPLINK tick to read
`state.loc`→zone→type; reuses all existing audio/class hooks.
- **Placement:** **v2.8.0** (rides UPLINK U2/U3; the zone data is shipped).
- **Dependencies / architecture:** UPLINK body-class arbiter + the no-write invariant (§7); needs a robust
loc→zone→type resolution (reuse `scoreZoneForLoc`, `ui-render.js:1269`, with a clean "unknown → neutral wilderness"
fallback); Protocol 38 (zone-type profiles are data; FO4 rides its own zones); reduced-motion → tint is instant, audio
unaffected. Battery: reuses the focused-only, long-tick UPLINK loop.
---
## 4. Personal-Legend News Callbacks — your deeds become wasteland news (no AI)
- **Builds on:** WASTELAND UPLINK radio/bulletin bank (U3) + broadcast push (U1); the deterministic (non-AI) side of
the Radio tuner (R3 #2 / B1-05 synth); `state.stats` (kills / caps / damage, `ui-render.js:601`), `state.quests`,
`state.factions` + the 2D reputation matrix (`getFactionStanding`, `ui-render.js:390`).
- **The enhancement:** AI_SLATE AI-A proposes *AI-generated* radio banter. This is the **deterministic** complement — a
local "wasteland news" register that turns *your own* milestones into recurring, templated bulletins with no network:
completing a quest becomes `> RADIO MOJAVE: WORD IS A COURIER SETTLED THE {quest} BUSINESS…`; crossing a faction
threshold becomes `> …NCR PATROLS SPEAK WELL OF A WANDERER NEAR {loc}`; a kills milestone becomes a "dangerous
drifter" bulletin; caps/level milestones become color. A small seeded pool per category (game-agnostic
`GAME_DEFS[ctx].ambient.news`) with cooldowns so it's occasional, not spammy, and always templated from live state at
emit time (never stored).
- **Why it feels alive:** "The world is talking about me" is the payoff Fallout's radio is famous for (Three Dog / Mr.
New Vegas reacting to your deeds). Delivering a *deterministic* slice of that — where the terminal calls back to things
*you* actually did, offline, for free — is the highest-impact roleplay beat in this list and turns the radio from
ambience into a mirror of your playthrough.
- **Gameplay / UX benefits:** Makes quests/factions/stats feel consequential beyond their panels; gives the shipped
synth radio (WU-F5) a reason to be on; sets up the AI-A banter (AI_SLATE) as the *optional* enrichment layer on the
same bank (exactly the UPLINK static-core / AI-augment seam, §3).
- **Complexity:** **Medium.** A news-template bank + milestone detection (diff `state.stats`/`quests`/`factions` on the
UPLINK tick, engine-local memory only) + cooldowns.
- **Placement:** **v2.8.0** (deterministic core on UPLINK U3) → AI-A banter is the later online garnish.
- **Dependencies / architecture:** UPLINK bank + seeded-roll (ROADMAP #2, C1/C2); read-only (milestone *detection* reads
state, writes nothing — the actual kill/quest mutation is the gameplay layer's job); Protocol 38 (news pool per game);
the "writes nothing durable" guard; low-frequency so `aria-live` (Suite 94) isn't spammed.
---
## 5. Overseer's Incident Log — the terminal *witnesses* your campaign
- **Builds on:** WU-F7 Overseer's Log (`renderOverseerLog` + `robco_overseer_log`, `ui-core.js:138/187`) and the merged
Session Statistics panel (`renderSessionStats`, WU-F10); the native-input-path protocol (ROADMAP #6); the campaign
state milestones (#4's detection).
- **The enhancement:** The Overseer's Log today is dry device telemetry (uptime / boot count). Deepen it into a diegetic,
auto-recording **incident log** — a short, capped, *device-local* ring of notable campaign moments the terminal
"observed": `DAY 12 — FIRST BLOOD LOGGED`, `DAY 19 — CRITICAL POWER EVENT (HP < 25%)`, `DAY 31 — NCR STANDING:
IDOLIZED`, `DAY 47 — 100 HOSTILES NEUTRALISED`. Entries are generated from the same milestone crossings as #4 (kills
thresholds, near-death via the shipped `crit-hp-flash` crossing, faction-standing changes, days-survived), stamped
with the in-world date (#1), stored **local-only** (like the existing Overseer stats — never campaign state, never
cloud), capped as a ring, and browsable in the OVERSEER'S LOG panel under a `INCIDENT RECORD` divider. Add a native
"PURGE INCIDENT LOG" control (Protocol 6/UI-5) so the operator owns it.
- **Why it feels alive:** A terminal that keeps its *own* maintenance/incident record — that "remembers" the day you
first nearly died or the day the NCR started to respect you — reads as a machine that has been running your whole
journey. It's the continuity lever made browsable, and it rewards long-term use without ever nagging.
- **Gameplay / UX benefits:** A zero-effort, auto-written campaign journal; pairs with the manual `campaign_notes`
(operator-written) as the *machine-written* counterpart; surfaces milestones the panels don't celebrate.
- **Complexity:** **Medium.** Milestone→entry recording (reuse #4's detection), a capped local ring (mirror the
`ERROR_LOG_CAP` ring-buffer pattern already in the codebase, Suite 58), a render section, a purge control.
- **Placement:** **v2.9.0** (needs the milestone-detection layer #4 first; a gameplay-round polish).
- **Dependencies / architecture:** Device-local storage (like `robco_overseer_log`, NOT Protocol-4 campaign state, NOT
cloud — this keeps it outside the save/sync surface entirely); reuse the ring-buffer + `_openSysModal` idioms; the
incident vocabulary is game-agnostic (thresholds/dates, no game literal); no `APP_VERSION` bump.
---
## 6. Focused-Idle Attract Mode with *your* telemetry — deepen the screensaver
- **Builds on:** RECREATION_IDEAS Idea 2 (focused-idle attract/burn-in screensaver); the standby subsystem
(`enterStandby`/`exitStandby`/`_startMemCycle`, `ui-core.js:472–521`); the Overseer + session telemetry;
`prefers-reduced-motion` (Suite 94).
- **The enhancement:** RECREATION Idea 2 proposes a generic drifting `◄ ROBCO U.O.S. ►` attract plate after ~90 s of
*focused* idle (distinct from blur-standby). Deepen it so the attract plate isn't generic marquee text but a slow,
drifting **status attract** of *your* live telemetry: current location, day-in-the-wasteland (#1), active directives,
total power-on, a rotating diegetic line ("MONITORING WASTELAND FREQUENCIES…"). The slow positional drift still serves
as a real OLED/AMOLED burn-in guard; any input instantly wakes it via the existing `exitStandby()` wake path.
- **Why it feels alive:** An idle CRT that lapses into showing *its own operator's* vitals is exactly the "attract mode"
a real terminal ran — and it fills the currently-dead focused-idle void (today a reader who isn't typing gets only the
15-minute `_startMemCycle` line, `ui-core.js:472`). It converts idle time into ambient presence instead of a blank
dim.
- **Gameplay / UX benefits:** Glanceable status without interaction; genuine burn-in mitigation on phones; reuses
standby's wake tone/resync (no new audio); fully gated (toggle + reduced-motion → static).
- **Complexity:** **Low–Medium.** A focused-idle timer + one `#attractLayer` element animated by CSS `@keyframes`,
populated from existing telemetry getters; body-class arbitration with `standby`/`rad-*`/`time-night`.
- **Placement:** **v2.8.0** (a self-contained idle-visual unit; pairs with #2's telemetry surfacing).
- **Dependencies / architecture:** Extends the standby subsystem (Protocol 22 — no parallel idle manager); markup+CSS in
already-precached files (one cache rev, no new asset); needs the Protocol-8 plan-audit for the class-stacking cases
(attract during `rad-critical`, standby↔attract handoff) RECREATION Idea 2 already enumerates; render-check at
360/412 (overlay must not overflow); no network → no kill-switch.
---
## 7. Emergent CRT "Condition" — the glass shows the wear of a long campaign
- **Builds on:** WU-F6 Cold-Start / Degraded-Tube boot aesthetic (`_pickBootFlavor`/`boot-degraded`, `ui-audio.js:969`);
the body-state class layer + arbitration (`updateMath`, `ui-core.js:2350`; UPLINK §4 disjoint `ambient-*` namespace);
the per-game `THEMES` palette (WU-T1); the Overseer uptime + campaign stats.
- **The enhancement:** Today the CRT reacts only to *instantaneous* state (rads, weight, karma, crit-HP). Add a very
subtle, cosmetic **cumulative-condition** layer — a disjoint `ambient-*` class set the UPLINK engine can apply — that
reflects the *arc* of a session/campaign: a very long uninterrupted session (Overseer uptime) introduces a faint,
slow "tube-warmth" glow drift; a deep-underground zone-type (#3) adds a grimier scanline; sustained extreme standing
(deeply idolized *or* vilified across factions) nudges the phosphor a hair warmer/cooler. Every effect is tiny,
transient, never touches real `rad-*`/`weight-*` classes, always loses to a real hazard (§4), and is fully neutralised
by `prefers-reduced-motion` and the master immersion toggle.
- **Why it feels alive:** A terminal whose glass slowly "warms" over a marathon session, or reads grimier the deeper you
are, feels like a physical object that has *been running your whole journey* — the WU-F6 degraded-boot idea extended
from a one-off boot flavor into an always-on subtle physicality. It's the reactive-physicality lever done as
atmosphere, not information.
- **Gameplay / UX benefits:** Ambient reward for long/deep play; deepens the CRT identity the app is built on; costs no
interaction and conveys nothing critical (purely decorative, so no color-only-meaning risk).
- **Complexity:** **Medium.** A cumulative-condition reader on the UPLINK tick + a handful of `ambient-*` CSS rules;
the *hard* part is restraint + the class-arbitration audit (must never imply a rad/weight state the user doesn't have).
- **Placement:** **v2.9.0 or later.** Highest "could feel gimmicky" risk of the set — ship after the UPLINK arbiter is
proven, default subtle/off, owner-tuned intensity.
- **Dependencies / architecture:** The UPLINK disjoint-namespace + no-write guard (§7) is mandatory (this must never
become a real state write); THEMES for per-game tint deltas (Protocol 38); reduced-motion hard-block; Protocol 8
plan-audit enumerating every concurrent body-state.
---
## 8. Dusk/Dawn That Lands + Time-of-Day Voice — make the day/night substrate *felt*
- **Builds on:** WASTELAND UPLINK day/night substrate (§5.4, U2) + the authoritative `time-night` class
(`updateMath`, `ui-core.js:2418–2423`, night = hour ≥ 20 or < 6); the radio DJ greeting seam (U3); the synth
hum/geiger; the in-world hour + calendar (#1).
- **The enhancement:** Today `time-night` is a hard binary toggle with no transition and no consequence beyond a tint.
Deepen the UPLINK day/night into something that *lands*: transient `ambient-dusk`/`ambient-dawn` transition tints on
the phase crossings (layered *under* the authoritative `time-night`, never conflicting); **time-of-day radio greetings**
("GOOD EVENING, WASTELANDERS…" pulled from the day/night phase, per §5.4); a subtle **night hum/geiger shift** (quieter,
cooler); and **night-weighted encounter/broadcast tables** (harsher after dark). The world-clock owns the phase; every
consumer reads it (the UPLINK spec's exact design, here given concrete felt outputs).
- **Why it feels alive:** Dusk and dawn *arriving* — the screen warming at sunset, the DJ greeting the hour, the wasteland
getting harsher at night — is core Fallout atmosphere the current hard toggle throws away. It makes advancing `ticks`
through a day a sensory event and ties the radio, the CRT, and the ambient engine to one clock.
- **Gameplay / UX benefits:** Time-of-day becomes meaningful (a reason to notice the hour); one clock drives three
surfaces (tint / voice / encounter weight) with no duplication; sets up a future Hardcore/Survival layer to read the
same clock (UPLINK §5.5).
- **Complexity:** **Low–Medium.** Transition tints (CSS) + phase-read greeting (data) + a night weight multiplier on the
existing tables; all substrate the UPLINK spec already scopes.
- **Placement:** **v2.8.0** (UPLINK U2, alongside #1/#3).
- **Dependencies / architecture:** UPLINK world-clock (reads `ticks`, never writes); disjoint `ambient-dusk/dawn` vs
authoritative `time-night` (§4); reduced-motion → instant tints; Protocol 38 (greeting/encounter copy per game);
no new asset (CSS in precached `terminal.css`).
---
## 9. Faction Consequence — the *ambient signal* layer of your reputation
- **Builds on:** the parked R3 Faction Consequence Engine (v2.9.0 #5: rep thresholds → vendor lock/unlock, bounty
hunters, map markers); the shipped 2D reputation matrix (`getFactionStanding`/`adjustFaction`/`FACTION_THRESHOLDS`,
`ui-render.js:378–416`); WASTELAND UPLINK push + the incoming-transmission nudge (`incomingTx`); the map fog-of-war.
- **The enhancement:** The parked Faction Consequence Engine is framed *mechanically* (vendors, bounties, markers). Add
its **atmospheric/sensory half** — the felt presence of your standing, driven by the UPLINK push: crossing into
*Idolized* with a faction emits an occasional friendly ambient broadcast near their territory
(`> NCR PATROL RECOGNISES YOUR COLORS`); *Vilified* raises the odds of a hostile `incomingTx` nudge
(`> UNKNOWN FREQUENCY — TRIANGULATING YOUR POSITION`) and a "hostile signal" ping on the map's current-location cell;
a threshold *crossing* fires the shipped `playFactionThresholdSound` (`ui-audio.js:789`) + an optional haptic (#14).
The *mechanical* consequences stay in the R3 engine; this is purely the ambient reaction so reputation has **presence**
between vendor screens.
- **Why it feels alive:** A reputation you can *feel* in the air — patrols acknowledging you, bounty hunters tuning your
frequency — is what makes standing matter in Fallout. It converts a numeric fame/infamy matrix into wasteland
atmosphere and gives the bounty-hunter fantasy a diegetic on-ramp before the mechanical engine even resolves it.
- **Gameplay / UX benefits:** Makes the ±5 faction buttons feel consequential immediately; the hostile nudge creates
genuine tension; ties the shipped faction-sound + map + reputation systems into one felt loop.
- **Complexity:** **Medium.** Threshold-crossing detection (diff `state.factions` on tick, engine-local) → weighted
UPLINK broadcasts + a map ping class; reuses the shipped sound + matrix.
- **Placement:** **v2.9.0** (the ambient layer of R3 #5; can precede the mechanical engine).
- **Dependencies / architecture:** UPLINK push + seeded-roll (ROADMAP #2); the reputation matrix (read-only — detection
writes nothing); the map current-cell render (`renderWorldMap`); Protocol 38 (per-game faction framing, ties to #12);
the no-write guard; low-frequency to avoid `aria-live` spam.
---
## 10. INTERCEPT Inbox — deepen the "incoming transmission" nudge into a reason to stay tuned
- **Builds on:** WASTELAND UPLINK `incomingTx` nudge (§2.3) + INTERCEPT AI-augment seam (U5); AI_SLATE AI-H (INTERCEPT
distress/numbers signals, static-library-first, AI-augment optional); the `appendToChat(...,'sys',true)` no-persist
push; the native command router (`NATIVE_COMMAND_ROUTER`, `api.js:964`).
- **The enhancement:** UPLINK's `incomingTx` is a rare one-off nudge that pre-fills the input. Deepen INTERCEPT into a
small, session-scoped **signals surface**: a `[INTERCEPT]` native command (offline-first, from a static bank of ~20
distress calls / numbers-station logs / faction chatter — the AI-H BUILD-NOW core) that renders a short intercepted
transmission, plus occasional *ambient* intercepts the UPLINK engine drops into the comm-link. AI augmentation (AI-H,
flagged `aiIntercept`) is the *optional* variety layer on the exact same bank; offline it degrades to the static
library, never a dead feature. Session-scoped only — nothing persisted (comm-lines ride the no-persist push).
- **Why it feels alive:** A wasteland that occasionally *broadcasts at you* — a distress call bleeding onto your
frequency, a numbers station counting in the dark — is the atmosphere that makes a terminal feel plugged into a living,
dangerous world you're only one node of. It gives the operator a diegetic reason to keep the terminal on and turns the
comm-link into a receiver, not just a chat box.
- **Gameplay / UX benefits:** A pull surface (`[INTERCEPT]`) *and* an ambient push, sharing one bank; the static core
ships fully functional with zero signal (offline-safe); it's the model for the UPLINK static-core / AI-augment split.
- **Complexity:** **Medium.** Static signal bank (data) + a `[INTERCEPT]` router entry + UPLINK ambient-intercept event;
the AI-augment (AI-H) is the later flagged garnish.
- **Placement:** **v2.8.0** (static core on UPLINK U1/U5) → AI-augment rides App Check (ROADMAP #3).
- **Dependencies / architecture:** UPLINK bank + push; the router (don't re-fork it — CONSULT already absorbed
command-palette intent, ROADMAP note); `aiIntercept` kill-switch + fail-safe-to-static (Protocol 32/33) for the AI
layer; Protocol 38 (signal bank per game); injection-hardened if AI-augmented (§3). No `[DATA]` writes.
---
## 11. Diegetic Cold-Boot Onboarding — first power-on as an in-world operator handshake
- **Builds on:** WU-F6 Cold-Start boot (first-ever POST gated by `robco_booted_before`, `ui-audio.js:975`); the parked
R2 "diegetic onboarding / first-run tour"; the R2-k Playthrough-Type clarity pass (ROADMAP #13, reuses the WU-E2 idle
banner template); the campaign-config panel + `playthroughType`/`gameContext`/`campaignMode` fields.
- **The enhancement:** Today first-run drops the user straight into the terminal with no framing, and Playthrough
Type / game selection are unexplained. Fuse WU-F6's first-ever cold boot with the parked onboarding into a single
**diegetic operator handshake**: the first cold POST flows into an in-world "TERMINAL REGISTRATION" — pick your game
(which RobCo software this unit runs), name the operator, choose a Playthrough Type *with the R2-k explanations
inline*, all framed as RobCo setup lines in the HOUSE_STANDARD voice, not a modern modal wizard. It runs exactly once
(the existing first-boot flag), is skippable, and never re-appears.
- **Why it feels alive:** The first thing a real RobCo terminal did on cold power-on was *configure itself* — a
registration handshake is the most authentic possible onboarding and it makes the very first impression feel like
booting a machine that has been waiting for you, not opening a webpage. It also solves the real UX gap (unexplained
Playthrough Type) inside the fiction instead of with a help tooltip.
- **Gameplay / UX benefits:** New users understand game/Playthrough/RNG choices *before* committing (ROADMAP #13's goal),
delivered diegetically; muscle memory for returning users is untouched (it never fires again); reduces the "what does
this do?" support surface.
- **Complexity:** **Medium.** Extends `runBootSequence` first-boot branch into a short interactive setup; reuses the
campaign-config controls + the WU-E2 explanation template.
- **Placement:** **v2.8.0** (coordinates WU-F6 boot + R2 onboarding + ROADMAP #13 clarity).
- **Dependencies / architecture:** Must NOT regress WU-F6's degraded/normal boot flavors (Suite 122) — the handshake is
an *additive* first-boot branch, not a rewrite; reduced-motion safe (CR-1); Protocol 38 (game list is data-driven, FO4
slots in); no `APP_VERSION` bump; render-check the interactive setup at 360/412.
---
## 12. Per-Game EXPERIENCE as data — FO3 and FNV should feel like different *machines*
- **Builds on:** the parked R2-m "per-game EXPERIENCE" wish-list; ROADMAP #12 (deliver R2-m as a `GAME_DEFS` data
extension guarded by a Suite-89-style check); the shipped theming GT-1/2/3 (`THEMES` + `GAME_DEFS[ctx].theme`, Suites
124/127/130) and the deferred GT-4/GT-5 (per-game framing + save styling); the UPLINK bank (#1/#3/#4/#8).
- **The enhancement:** ROADMAP #12 rightly says deliver R2-m as data. This is the **immersion-specific slice** of that:
extend `GAME_DEFS[ctx]` with a `voice`/`ambient` block so FO3 vs FNV diverge across *terminology* (Karma Center vs
Faction Standing — already partly done via `usesKarmaCenter`), **faction framing** (Enclave/BoS/Lyons vs
NCR/Legion/House), **ambient bank** (Capital Wasteland vs Mojave broadcasts/news/almanac — #1/#3/#4), **boot & save
identity** (shipped GT-3), and **CRT character** (the FO3 duller-green + heavier framing of GT-4). The net effect: an
FO3 campaign *reads, sounds, and frames* like a grungier Capital-Wasteland unit; an FNV campaign like a warmer Mojave
one — all as declared data, zero feature-code branches.
- **Why it feels alive:** "This is a different RobCo unit for a different wasteland" is the deepest per-game immersion
win — and it's the connective tissue that makes ideas #1/#3/#4/#8/#9 feel game-authentic rather than generic. A
terminal that *is* a Capital-Wasteland machine (not a re-skinned Mojave one) reads as native to its game.
- **Gameplay / UX benefits:** Each game feels distinct without fragmenting the codebase; FO4 becomes a single new
`GAME_DEFS` block (proof the seam scales); consolidates the scattered R2-m sub-items into one data surface.
- **Complexity:** **Medium.** A `GAME_DEFS[ctx].voice/ambient` extension + wiring existing surfaces to read it; the risk
is *scope creep* on R2-m's "all 10" — keep it to terminology/faction-framing/ambient/CRT-character.
- **Placement:** **v2.8.0** (the data seam most other immersion ideas key off; GT-4 framing folds in here).
- **Dependencies / architecture:** Protocol 38 + a Suite-89-style guard (fails the build if a new `=== 'FO3'` literal
appears — ROADMAP #12); ties to `getSystemDirective` decomposition (ROADMAP #4) for per-game AI voice; the UPLINK
`GAME_DEFS[ctx].ambient` seam (#1/#3/#4); no `APP_VERSION` bump.
---
## 13. RobCo Hacking Minigame as a diegetic "locked subsystem" — reward, not toy
- **Builds on:** CAPABILITY_SLATE B1-11 (the iconic RobCo password-guess hacking minigame, parked SPEC-FIRST); the
INTERCEPT/UPLINK bank (#10); the native router + command registry; the per-game data seam (#12).
- **The enhancement:** B1-11 parks the hacking minigame as a standalone easter-egg. Reframe it as a **diegetic gate that
pays off**: rare `> ENCRYPTED PARTITION DETECTED` events (surfaced by the UPLINK engine or an INTERCEPT signal) invite
the operator to run the classic likeness-scoring hack; success **unlocks a small piece of flavor** — a lore holotape
entry, a rare optic/theme, an almanac secret (#1), or a hidden attract message — rather than being a dead-end toy.
Failure locks the partition out with a diegetic taunt (the AI-C static taunt library, offline; AI-augment optional).
Fully keyboard-navigable, self-contained DOM module, no new capability.
- **Why it feels alive:** The RobCo hack is *the* most recognizable terminal interaction in Fallout — giving it a
diegetic purpose (locked subsystems that hide real flavor) makes the terminal feel like it has depths to earn into,
the subtle long-term-use reward the charge asks for. It's the one interaction players will recognize instantly as
"this has always been a RobCo terminal."
- **Gameplay / UX benefits:** A skill-based diversion with a real payoff; a home for unlockable flavor (themes, lore,
attract lines) that rewards exploration; the static taunt library ships offline.
- **Complexity:** **Medium–High.** A self-contained hacking module (garbage grid + candidate words + likeness scoring +
keyboard nav) is a sizeable new surface — B1-11 flags "spec carefully."
- **Placement:** **v2.9.0 or later** (a substantial standalone module; sequence after the UPLINK/INTERCEPT banks it
hooks into exist).
- **Dependencies / architecture:** Reduced-motion + keyboard-nav + 360/412 render (Protocol 10/17); the unlock rewards
must be additive device-prefs/flavor, not campaign-state writes (keep it out of the save surface); Protocol 38
(locked-content pool per game, #12); the AI taunt is a flagged, fail-safe-to-static garnish (Protocol 32/33).
---
## 14. Chassis Feedback Choreography — the terminal *physically reacts* to the world
- **Builds on:** the shipped WU-F2 Haptic Solenoid (`triggerHaptic`, opt-in, reduced-motion-aware) + WU-F6/WU-F1
device layer; the 15 synth audio voices (`ui-audio.js`); the body-state crossings already detected in `updateMath`
(crit-HP, karma, weight) + faction thresholds (`playFactionThresholdSound`) + level-up jingle.
- **The enhancement:** The haptic + audio SFX exist but fire on a scattered handful of events. Deepen them into a
deliberate, tasteful **feedback choreography**: distinct, recognizable haptic+audio *signatures* for the meaningful
world-crossings — faction Idolized (rising chord + soft double-pulse), near-death (the shipped heartbeat + a low
buzz), rad-storm onset (#8, a warning tick + tremor), level-up, a UPLINK intercept (#10, a short "signal lock" blip).
Every signature is opt-in (existing `AudioSettings` + haptic toggles), reduced-motion/mute-safe, and *restrained* (one
per crossing, cooldowns) so the box feels like a physical instrument responding to events, not a buzzing phone.
- **Why it feels alive:** A terminal that you can *feel* react — a distinct pulse when the NCR finally respects you, the
chassis tensing as a rad-storm rolls in — is the reactive-physicality lever completed. It makes the meaningful moments
land in the body, which is exactly what a diegetic hardware device would do, and it ties the audio, haptic, and UPLINK
event layers into one coherent language.
- **Gameplay / UX benefits:** Meaningful moments get a recognizable signature (learnable, not noise); reuses shipped
synth + haptic (no new assets); entirely behind existing opt-in toggles + master mute + reduced-motion.
- **Complexity:** **Low–Medium.** A signature table mapping crossings → (existing sound + existing haptic pattern) +
cooldowns; reuses everything, adds no new synthesis.
- **Placement:** **v2.8.0** (rides shipped WU-F2 + the UPLINK events #8/#10).
- **Dependencies / architecture:** Protocol 7 (every audio source: master-mute guard + own key); WU-F2 haptic
reduced-motion/opt-in discipline; the UPLINK no-write guard (feedback is transient); Protocol 38 (signatures are
game-agnostic — tied to crossings, not game literals); restraint is the design risk, not the tech.
---
## 15. Standby as "Powered-Down Wasteland Watch" — leaving and returning *means something*
- **Builds on:** the standby subsystem (`enterStandby`/`exitStandby`, `ui-core.js:483–521` — today: dim + kill
geiger/hum + a plain `> COURIER RETURNED. SYNCHRONIZING TELEMETRY...` on return); WASTELAND UPLINK (paused on
blur/hidden by design); the in-world calendar (#1); the wake-tone resync path.
- **The enhancement:** Today standby is a plain dim and the return line is static. Deepen the away/return cycle into
continuity: on blur, the terminal enters a diegetic low-power **watch** state (a single slow "STANDBY — MONITORING
WASTELAND FREQUENCIES" line, then quiet); on return, the `exitStandby` resync reports — in-voice — *what changed while
you were gone*: real elapsed wall-time framed against the in-world day (#1) ("COURIER RETURNED — 2H14M DARK · DAY 47
HOLDS"), an occasional "signal intercepted during standby" hook (#10), or a rad-weather note. Still writes nothing
durable (the UPLINK engine is inert during standby; the resync lines ride the no-persist push).
- **Why it feels alive:** Making the *return* a small event — the terminal telling you it kept watch, that time passed,
that a signal came in while you were away — closes the loop on "this machine runs whether I'm here or not." It turns
the most mundane lifecycle transition (tab blur/focus) into a continuity beat, which is precisely where an
always-on wasteland terminal should reassert its presence.
- **Gameplay / UX benefits:** Re-orients you on return (how long, what happened); reinforces the living-world fantasy at
the exact re-engagement moment; reuses the existing wake tone + telemetry resync (no new audio).
- **Complexity:** **Low–Medium.** Extend `enterStandby`/`exitStandby` with a watch line + a state-aware return message
(elapsed time + calendar + optional intercept); reuses the wake path.
- **Placement:** **v2.8.0** (small, self-contained; pairs with #1 calendar + #10 intercept).
- **Dependencies / architecture:** Extends standby (Protocol 22 — no parallel idle manager); the resync lines use
`appendToChat(...,'sys',true)` (no-persist, confirmed `ui-core.js:2657`); UPLINK stays inert during standby (its own
invariant); Protocol 38 (return copy game-agnostic); no `APP_VERSION` bump, no new asset.
---
# At-a-glance — the 15 immersion enhancements
| # | Title | Builds on (roadmap/system) | Immersion lever | Complexity | Placement |
|---|---|---|---|---|---|
| 1 | Wasteland Calendar & Anniversaries | UPLINK day/night · Boot MOTD · in-world calendar | Ambient life | Low–Med | v2.8.0 |
| 2 | Session-Resume Continuity Readout | Boot MOTD · Overseer Log · calendar | Continuity | Low | v2.8.0 |
| 3 | Location-Aware Ambience | UPLINK U2/U3 · synth · map zone-type | Ambient life | Medium | v2.8.0 |
| 4 | Personal-Legend News Callbacks | UPLINK radio/bulletins · stats/factions/quests | Continuity/world | Medium | v2.8.0 |
| 5 | Overseer's Incident Log | WU-F7 Overseer Log · native-input · milestones | Continuity | Medium | v2.9.0 |
| 6 | Focused-Idle Attract w/ telemetry | RECREATION #2 · standby · telemetry | Reactive physicality | Low–Med | v2.8.0 |
| 7 | Emergent CRT "Condition" | WU-F6 degraded boot · body-classes · THEMES | Reactive physicality | Medium | v2.9.0/later |
| 8 | Dusk/Dawn That Lands + Voice | UPLINK U2 day/night · time-night · radio | Ambient life | Low–Med | v2.8.0 |
| 9 | Faction Consequence — ambient layer | R3 #5 Faction Engine · rep matrix · UPLINK push | World reactivity | Medium | v2.9.0 |
| 10 | INTERCEPT Inbox | UPLINK incomingTx · AI-H INTERCEPT · router | Ambient life | Medium | v2.8.0 |
| 11 | Diegetic Cold-Boot Onboarding | WU-F6 cold boot · R2 onboarding · R2-k clarity | Roleplay/authenticity | Medium | v2.8.0 |
| 12 | Per-Game EXPERIENCE as data | R2-m · ROADMAP #12 · GT-4/GT-5 theming | Roleplay/authenticity | Medium | v2.8.0 |
| 13 | Hacking Minigame as locked subsystem | B1-11 hacking · INTERCEPT bank · unlocks | Authenticity/reward | Med–High | v2.9.0/later |
| 14 | Chassis Feedback Choreography | WU-F2 haptic · synth SFX · body-crossings | Reactive physicality | Low–Med | v2.8.0 |
| 15 | Standby "Powered-Down Watch" | standby subsystem · UPLINK · calendar | Continuity | Low–Med | v2.8.0 |
**Distribution:** 10 in v2.8.0 (ambient substrate + continuity + physicality that ride the UPLINK/boot/standby seams),
3 in v2.9.0 (incident log, faction ambient layer, and the harder items that need earlier layers), 2 flagged v2.9.0/later
(emergent CRT condition + hacking subsystem — highest gimmick/scope risk, ship last). **By lever:** Continuity 5
(#2/#4/#5/#15 + #1), Ambient life 4 (#1/#3/#8/#10), Reactive physicality 3 (#6/#7/#14), Roleplay/authenticity 3
(#11/#12/#13), World reactivity 1 (#9).
**Consolidation with the siblings (deliberate, not accidental):** #1/#3/#4/#8/#10 are all **consumers of the ONE
WASTELAND UPLINK engine** (ROADMAP #2's "one engine, many consumers" — they add *felt outputs*, not new substrate);
#2/#6 surface the **same buried Overseer/session telemetry** at boot and idle; #9/#12 are the **immersion halves** of
ROADMAP #12 + the R3 Faction Engine (the mechanical halves stay in those plans). Nothing here forks a new subsystem the
roadmap already owns.
---
## Cross-cutting constraints (all 15 honored)
- **Offline-safe / no outage:** every idea's core is deterministic + offline; the only network touch is the *optional*
AI-augment on #4/#10/#13, which is flagged (`aiRadio`/`aiIntercept`) and fail-safe-to-static (Protocol 32/33).
- **Writes nothing durable unless it's a real action:** the ambient/continuity ideas ride the no-persist
`appendToChat(...,'sys',true)` push + transient `ambient-*` classes + device-local prefs (Overseer-style), never the
campaign `robco_v8` save or cloud (the UPLINK §7 invariant + its permanent gate guard cover them). #5's incident log is
explicitly device-local, outside the Protocol-4 save surface.
- **Game-agnostic (Protocol 38):** all copy/tables live in `GAME_DEFS[ctx]` (`ambient`/`voice`/`almanac`/`news`); a
third game (FO4) is a new data block, zero feature-code change; a Suite-89-style guard fails the build on a new game
literal.
- **Accessibility:** all motion honors `prefers-reduced-motion` (Suite 94); ambient text is low-frequency so
`#chatDisplay` `aria-live` isn't spammed; every audio/haptic is opt-in behind existing toggles + master mute; no
color-only meaning; 360/412 render-check for any layout (Protocol 10/17).
- **Vanilla/no-build, popup-auth untouched, free/BYO-key, cache-first SW:** no framework, no auth change, no
`APP_VERSION` bump without owner approval; each served-file change is one `CACHE_NAME` `-rN` bump; the ambient engine
is the one new precached JS file (already scoped by the UPLINK spec).
- **The gate:** each idea ships with both-runner parity tests (Protocol 15/2a) + a static source-invariant guard
(Protocol 20) for its no-write/reduced-motion/game-agnostic invariants, per the escape-ratchet (Protocol 36b).
---
*END — analysis only. Nothing was implemented, committed, or pushed. Parked steps untouched; sibling docs deepened, not
duplicated. `planning/` is gitignored. Awaiting owner review + explicit approval before anything folds into the roadmap.*
STAMP · generated for RELEASE v2.8.5 commit 06e5180 (06e51801b38a) · archive input-tree hash c07fbfbdd2e1ddeb · 754 files · no wall-clock timestamp (regenerates identically when nothing changed).