An AI-powered tactical companion terminal for Fallout: New Vegas and Fallout 3
A full CRT terminal emulation that turns a browser tab into a living Pip-Boy companion — a physical RobCo device that reacts to your character's condition, with two Wastelands, an offline native toolset, and an AI Director that's optional, not required.
Live Demo · Features · Architecture · Getting Started · Development · Project History
Current version: 2.8.5 — "Foundations & Fidelity"
RobCo U.O.S. is a standalone, browser-native web application that acts as a real-time tactical companion for Fallout: New Vegas and Fallout 3 playthroughs. It tracks your character, inventory, factions, quests, and world state inside a fully immersive CRT terminal, and — when you want it — connects to the Google Gemini API to act as an AI game master that narrates your adventure and updates your sheet through strict, validated JSON.
It began as a Google Gemini Gem (a chat preset) and grew into a complete application with its own state engine, save system, cloud sync, procedural audio, and PWA install support.
This is not a chatbot skin. It is a structured game engine where the AI is locked into JSON output and every value is validated before it touches your campaign — and where the heaviest, most-used tools (combat math, barter, threat assessment, lookups, medical advisories, looting) now run entirely offline with no AI call at all. The terminal itself physically reacts to your character's condition.
Both games are first-class and fully data-driven. A single GAME_DEFS table plus per-game data files (reg_nv/reg_fo3, db_nv/db_fo3) drive everything — factions, skills, registries, databases, collectibles, theming, identity. New Vegas and Fallout 3 each get their own registries, bestiary, item data, default terminal colour, boot identity, and save-manager banner. Adding a future Fallout title is a data drop-in (a GAME_DEFS entry + its two data files), not a code rewrite.
Six in-terminal tools compute their results on-device from the game's own data — zero network, zero AI, the same answer every time. Reachable from the Tool Deck (a small button beside the Comm-Link message box) or typed commands.
| Tool | What it does |
|---|---|
| V.A.T.S. | Hit-% per body part, crit bonus (+5% NV / +15% FO3), and an exact melee/unarmed AP-strike optimiser; reads the equipped weapon + SPECIAL + a TARGET DT input |
| THREAT | Bestiary stat card for any creature + estimated time-to-neutralize and ammo/strike burn against your equipped weapon |
| TRADE (BARTER UPLINK) | Full offline barter terminal — buy/sell at real Fallout Barter-skill prices, confirm-gated, never auto-syncs |
| CONSULT | Databank lookup across items, perks, quests, locations, companions, and creatures, with key stats; says so plainly if nothing matches |
| BIO-SCAN | Medical advisory — HP tier, radiation, per-limb OK/CRIPPLED, addiction flags, and the right healing/rad/cure items (sourced from the game's own chem data) |
| LOOT | Salvage intake — search the item database and add anything to your pack at its canonical value (additive + confirm-gated) |
A [FEATURES] command registry lists every command the terminal supports and is kept honest by the build gate.
Nine capabilities, each with a graceful fallback when the device/browser doesn't support it:
- Sustained Power Cell — Screen Wake Lock (keep the display awake while reading)
- Haptic Solenoid — Vibration feedback on level-up, faction flips, and critical HP (honours reduced-motion)
- Eject Holotape — Web Share of your comm-link transcript (falls back to clipboard, then file)
- Pending-Directives Tally — app-icon Badging with your unresolved-quest count
- Pip-Boy Radio — a zero-byte, fully synthesized ambient station (WebAudio)
- Cold-Start / Degraded-Tube Boot — a first-ever full POST plus a rare (~1 in 100) glitchy boot variant, reduced-motion-safe
- Overseer's Log — local device telemetry (uptime, longest session, total power-on, boot count) merged with your campaign statistics
- High-Lumen Optics — a high-contrast display mode (auto-on under
prefers-contrast) - Immersion dial — a Full/Balanced/Minimal control for how much ambient atmosphere the terminal runs; a per-device preference (never rides your saves), defaulting to Full. A born-compliant seam the ambient layer will subscribe to
| System | Description |
|---|---|
| S.P.E.C.I.A.L. | All 7 attributes, editable and hard-clamped 1–10 |
| Skills | Per-game skill sets (NV's 13 incl. Guns/Survival; FO3's incl. Small Guns/Big Guns) |
| Limb Tracking | 5 limbs with cripple/restore states and unique trauma audio |
| Perks & Quests | Perk log (rank + level taken); quest log with objectives, status, and DLC tagging |
| Factions | Per-game reputation networks with fame/infamy, standing labels, and threshold alerts |
| World Grid Map | Region map with fog-of-war discovery, collectible markers, zoom, and a native "LOG VISIT" mark-visited control |
| Trackers | Collectibles (snow globes / bobbleheads), FO3 Lincoln memorabilia, NV traits, skill books (READ/UNREAD), NV skill magazines |
| Crafting | Recipe + breakdown registry with a batch craft/scrap panel (workbench/campfire/recycling) |
| Inventory & Ammo | Categorised inventory, per-caliber ammo reserves, carry weight 150 + STR×10, one-tap USE |
- Per-game default optic — New Vegas boots in the bright RobCo green; Fallout 3 in a distinct, duller Pip-Boy green (both WCAG-AA contrast-verified). Driven by
GAME_DEFS[ctx].theme. - Dynamic "(Default)" label — the OPTICS picker tags the active game's default colour.
- Per-game optic memory — each game remembers its own chosen colour independently (keyed by game context; a 3rd game needs no code change).
- Per-game identity — a boot identity line (e.g. "PIP-BOY 3000 — MOJAVE WASTELAND UPLINK") and a save-manager banner per game.
- All colour options (RobCo Green, Pip-Boy Green, Amber, Vault-Tec Blue, Legion Red, Ghoul Green, Neon Violet) are selectable in either game.
| System | Description |
|---|---|
| Gemini API | Direct connection via your API key (stored locally, never exposed) |
| Tri-Node JSON | The Director is locked to {narrative, state, modal} structured output (application/json) |
| Validated import | autoImportState() explicitly field-maps + validates every value before it persists — the AI is never the sole source of truth |
| Database injection | The active game's full weapons/armor/bestiary/chems/recipes/vendors CSVs are sent to the AI on every message as a dedicated part of the system instruction (alongside the directive). The same per-game data also powers the native offline tools via local lookups |
| Resilience | Bounded auto-retry with backoff, clear auth-error messaging, prompt-injection hardening, input caps |
| Fully optional | The six native tools and the whole UI work with no key and no network |
- Auto-save (debounced localStorage), A/B/C slots, file export/import with version migration, rolling backups with FNV-1a checksums.
- Live-campaign durability mirror — the campaign you're actively playing is continuously shadowed into IndexedDB (the same durable store slots and backups already use), so if a phone reclaims the browser's local storage under memory pressure, your campaign is automatically restored on the next startup instead of starting over. Recovery-only and one-directional (a saved-behind mirror can never overwrite newer progress), and a graceful no-op when IndexedDB is unavailable.
- Save version history — each slot retains up to 5 prior revisions in IndexedDB (riding its headroom, never the localStorage ceiling); view and restore any earlier version from the saves list. Restoring is confirm-gated and takes a rolling backup first; if IndexedDB is unavailable the feature is simply not offered and save/load is unchanged.
- Full backup bundle — a one-file "EXPORT FULL BACKUP" of your entire history (live campaign + all slots with their version rings + rolling backups + chat + playstyle), version-stamped and checksummed. IMPORT SAVE auto-detects a bundle and restores it — confirm-gated, integrity-checked (a bad or edited file is refused with no partial apply), and a rolling backup of your current state is taken first. Campaign/save data only — device preferences are never included (the two-store boundary holds).
- Read-side fail-loud save integrity (Layer 3) — a save that can't be read at boot is quarantined whole, never deleted: the exact bytes are preserved (localStorage + a durable IndexedDB copy), a READ FAULT banner announces it every boot until resolved, and a QUARANTINED RECORD row in the saves list offers EXPORT (recover the raw data) and confirm-gated PURGE. A detected storage eviction (the browser reclaimed local data while the cold-storage boot marker survived) gets its own banner — gated behind a strict signature so a new visitor never sees a false alarm. Slot saves that only ONE of the two stores accepted post a once-per-session degraded-write notice instead of reporting plain success.
- Cloud sync via Firebase Firestore — additive writes only (never a blind overwrite), confirm-gated destructive actions, Google sign-in (popup-only), anonymous boot, and a Gemini-key sync option.
- Offline cloud-push queue — a manual "Save to Cloud" pressed while offline (or that fails on network) is queued device-locally and flushed automatically on reconnect. Retry-only: it never auto-pushes on a state change — cloud sync stays a manual button. Bounded + contentHash-deduped (no duplicate cloud saves), uid-scoped, kill-switch-gated, and fully fail-safe (no IndexedDB / flag off → the button behaves exactly as before).
- Remote kill-switch — a fail-open feature-flag config that can disable a networked feature remotely, always defaulting to last-known-good / features-enabled so it can never black-screen the app.
- Keyboard
:focus-visiblerings, fullprefers-reduced-motionfreeze (CRT flicker/scanlines),aria-livechat,role="dialog"focus-trapped modals, AA-contrast tab states, and descriptive labels on every control (inventory, faction, limb buttons). - Installable PWA (iOS / Android / desktop), offline-capable (cache-first Service Worker), with a reliable "REBOOT TERMINAL" auto-update flow — a focus/visibility re-check plus a durable "has-updated-before" record surface a waiting update even in an installed standalone PWA.
- Touch-first responsive layout (verified at 360 px / 412 px, no horizontal overflow); the desktop two-column shell is gated to real mouse/hover devices so a phone never boots the desktop layout.
Every sound is synthesized live via the Web Audio API — no audio files ship in this project. Typewriter clicks, Geiger counter (rads ≥ 200), tinnitus (rads ≥ 600 / crippled head), CRT hum, limb-trauma/restore tones, wake/sync tones, the boot drone, and the Pip-Boy Radio station. All respect a master mute + per-source toggles, read from an in-memory cache (never localStorage on hot paths).
CRT scanlines, phosphor persistence ghosting, thermal-load tint while the Director is thinking, day/night cycle, radiation interference, carry-weight deformation, limb-trauma glitches, karma/critical-HP flashes, a live uptime clock, a periodic memory-cycle flicker, and the redesigned in-app FIRMWARE REVISION LOG changelog viewer (environment-aware: staging shows in-progress notes, production shows only released versions).
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Vanilla HTML5 / CSS3 / ES2022 | Zero-framework, browser-native (global-scope script tags) |
| Styling | CSS Custom Properties | Dynamic theming via --robco-* variables |
| Audio | Web Audio API | Procedural synthesis — no audio files |
| AI | Google Gemini API | Optional structured-JSON game master |
| OCR | Tesseract.js (Apache-2.0, self-hosted, lazy) | On-device Visual Upload text recognition (primary path, AI-vision fallback) |
| Cloud | Firebase Auth + Firestore | Cross-device save sync, sign-in, remote feature flags |
| PWA | Service Worker + Manifest | Installable, offline-capable, reliable auto-update |
| Hosting | GitHub Pages (prod) + Cloudflare Pages (staging) | Release-gated production; auto-deployed staging |
| Dev Tooling | ESLint + Prettier + Vite | Linting, formatting, dev server |
| Testing | Node + Playwright | Node gate (behavioural + static invariants) + boot-smoke / render / a11y checks |
GAME_DEFS (in state.js) declares each game's factions, skills, collectible label, theme, calculator coefficients, and seed inventory. _activeDef() returns the active game's config; a one-line GAME_FILES boot manifest in index.html selects which per-game data files to load. Feature code reads GAME_DEFS[ctx] rather than hardcoding game literals (Protocol 38), so the engine scales to N games by data alone.
css/ is flat with a gapped numeric prefix (not subfoldered like js/) because in CSS the file order is load-bearing — equal-specificity ties resolve by source order, so the listing itself has to show what loads after what. 99-mobile.css sits alone at the end on purpose.
├── index.html DOM, inline handlers, GAME_FILES boot manifest, SW registration
├── css/ 13 order-prefixed files (2.8.5 U-A2 split + the FO3 Pip-Boy build), source order = cascade order —
│ ├── 05-base.css Tokens, reset, layout, app-shell
│ ├── 10-chrome.css Device chrome (bezel/casing/glass) + per-game identity
│ ├── 15-overseer.css Director Uplink / Overseer presence
│ ├── 20-diagnostic-shell.css Diagnostic Shell mobile overlay (dev-only)
│ ├── 25-toolbar.css Tool Deck + Quick-Draw Holster (+ global a11y/reduced-motion)
│ ├── 30-modulebay.css Module Bay (Security & Configuration)
│ ├── 35-operator-boards.css Phase 3 Operator boards (batches 1-3)
│ ├── 40-curio-operations.css Curio Archive + Operations console
│ ├── 45-databank.css Databank / Records Bay
│ ├── 50-chassis.css Chassis diagnostic bay + Living Core
│ ├── 55-feedback-animations.css Feedback Animation Waves 1-3
│ ├── 60-fo3-pipboy.css FO3 landscape Pip-Boy casing/glass skin — [data-game='FO3'] only, NV untouched
│ └── 99-mobile.css Mobile Density Standard — MUST stay last (cascade order)
├── js/ Reorganized into subfolders by responsibility (2.8.5 U-A2)
│ ├── data/ Fallout game content: item DBs + registries
│ │ ├── db_nv.js FNV game CSV data + lookups
│ │ ├── db_fo3.js FO3 game CSV data + lookups
│ │ ├── reg_nv.js FNV Fallout Data Registry (read-only)
│ │ ├── reg_fo3.js FO3 Fallout Data Registry (read-only)
│ │ └── registry-core.js Shared registrySearch() (game-agnostic, both contexts)
│ ├── core/ The engine: campaign state, ambient runtime, storage layer
│ │ ├── state.js State, persistence, migration, GAME_DEFS, THEMES, _activeDef()
│ │ ├── runtime.js Ambient Runtime — lifecycle state machine + heartbeat + observer registry
│ │ └── idb.js Async IndexedDB durability engine (device-pref write-through shadow)
│ ├── ui/ UI lifecycle hub, panels, render/audio/save/account modules
│ │ ├── ui-core.js UI lifecycle hub — AudioSettings, loadUI, updateMath, window.onload boot orchestrator
│ │ ├── ui-core-nav.js Bezel subsystem nav — selectSubsystem, switchTab, SHORTCUT_ROUTES
│ │ ├── ui-core-overseer.js Director Uplink — setOverseerState, scope canvas, composer wiring, Tool Deck launcher
│ │ ├── ui-core-chassis.js THE LIVING CORE + CHASSIS panel — _coreRefresh, System Status, Service & Fault Console
│ │ ├── ui-core-modulebay.js Module Bay wiring, phosphor-tube/immersion-dial/wake-lock clusters, campaign-config board
│ │ ├── ui-core-cmd.js Command layer — native stat setters, COMMAND_REGISTRY, core event-bus subscriber wiring
│ │ ├── ui-render.js Render-pipeline hub (2.8.5 U-A4 split) — only _updateContextPanels
│ │ ├── ui-render-inventory.js Cargo Manifest & Ammo — addItem/delItem/renderInventory/renderAmmo
│ │ ├── ui-render-character.js Character & Field Status — squad, clock/calendar, faction standing, status, perks, quests
│ │ ├── ui-render-record.js Personal Record — session tally, equipped gear, collectibles, Lincoln memorabilia, traits
│ │ ├── ui-render-ledger.js Field Ledger — skill books/magazines tracker, campaign notes, chronicle event log
│ │ ├── ui-render-map.js Cartography Table — renderWorldMap SVG, zone zoom/travel, node keyboard nav
│ │ ├── ui-render-factions.js Faction Reputation & Karma — adjustFaction, renderFactionRep, Karma Center
│ │ ├── ui-render-economy.js Resource Economy — Craft panel, native Trade barter terminal
│ │ ├── ui-render-loot.js Item Acquisition — native Loot terminal, Visual Upload OCR apply flow
│ │ ├── ui-render-databank.js Native Databank Tools — Threat, Consult, Eligible Perks, Databank panel, Bio-Scan
│ │ ├── ui-audio.js Audio engine, boot sequence, optics (THEMES table)
│ │ ├── ui-saves.js Save slots, file import/export, rolling backups, autocomplete
│ │ └── ui-account.js Account/UPLINK panel, cloud save picker, save-manager header
│ ├── services/ Everything that talks to the outside world
│ │ ├── api.js Network-layer hub — transmitMessage lifecycle, comm-config cache, fetchAuthorizedModels
│ │ ├── api-directive.js getSystemDirective + its 8 _directive* section builders (Suite 131 golden-master)
│ │ ├── api-import.js AI → state import — autoImportState, sanitizeImportedContainer
│ │ ├── api-router.js Offline native command routing — NATIVE_COMMAND_ROUTER, quick-log, transmitTerminal
│ │ ├── cloud.js Firebase auth + Firestore push/pull + remote config (ES module)
│ │ └── ocr.js Visual Upload on-device OCR: lazy Tesseract.js, parser, hybrid routing + kill-switch
│ ├── dev/ Dev-only tooling
│ │ └── test-console.js Diagnostic Shell (gated by _devConsoleUnlocked())
│ └── vendor/ Self-hosted Tesseract.js (Apache-2.0) — main API, worker, wasm core
├── sw.js Service Worker (cache-first, atomic precache, reliable update)
├── manifest.json PWA manifest (version-less name + app shortcuts)
├── tests/
│ ├── robco-diagnostics.js Node persistence/structure audit (the single canonical runner)
│ ├── test.html Browser-side runtime import-contract audit
│ └── *.mjs Playwright boot-smoke / render-check / a11y-baseline
├── scripts/gate.js The full local gate (lint, format, the Node runner, browser checks)
├── ARCHITECTURE.md Full system dependency map & patterns
├── CHANGELOG.md Version history (in-app FIRMWARE REVISION LOG reads this)
├── CLAUDE.md Agent rulebook — the universal contract + the retrieval map
├── rules/ Subsystem rule notes, loaded only when that surface is touched
│ ├── state-and-save.md State fields, saves, migration, durability
│ ├── deploy-and-cache.md Service worker, CACHE_NAME, deploy verification
│ ├── auth-and-cloud.md Auth hard rules, cloud write safety, kill-switch
│ ├── ui-and-mobile.md Panels, mobile baseline, UX stability, the UI-* protocols
│ ├── audio.md Adding an audio source
│ ├── game-data.md Provenance + game-agnostic feature code
│ ├── ai-contract.md Tri-Node schema safety + AI determinism
│ ├── file-layout.md Boot order (machine-checked), repomix, UTF-8 integrity
│ ├── testing-and-gates.md Static guards, test.html sync, Diagnostic Shell triggers
│ └── docs-and-library.md Changelog style, doc-reference integrity, the library model
└── assets/ PWA icon + app-shortcut icons, ocr/ (vendored OCR language data)
Global-scope <script> tags load in strict order (per-game db/reg pair is chosen by the boot manifest):
0. core/idb.js → window.IdbStore (async IndexedDB engine; loaded before the boot manifest)
1. data/db_nv.js / data/db_fo3.js → databaseCSVs, lookupItemInDb (active game)
2. core/state.js → state, APP_VERSION, GAME_DEFS, THEMES, saveState, migrateState
3. data/reg_nv.js / data/reg_fo3.js → FALLOUT_REGISTRY (active game, read-only)
4. data/registry-core.js → registrySearch (shared, game-agnostic)
5. ui/ui-audio.js → AudioSettings, audio + boot + optics functions
6. ui/ui-render.js → render-pipeline hub (2.8.5 U-A4 split) — only _updateContextPanels
7. ui/ui-render-inventory.js → Cargo Manifest & Ammo (2.8.5 U-A4 split)
8. ui/ui-render-character.js → Character & Field Status: squad, clock/calendar, faction standing, status, perks, quests (2.8.5 U-A4 split)
9. ui/ui-render-record.js → Personal Record: session tally, equipped, collectibles, Lincoln, traits (2.8.5 U-A4 split)
10. ui/ui-render-ledger.js → Field Ledger: skill/magazine tracker, campaign notes, chronicle (2.8.5 U-A4 split)
11. ui/ui-render-map.js → Cartography Table: renderWorldMap (2.8.5 U-A4 split)
12. ui/ui-render-factions.js → Faction Reputation & Karma (2.8.5 U-A4 split)
13. ui/ui-render-economy.js → Resource Economy: Craft + Trade (2.8.5 U-A4 split)
14. ui/ui-render-loot.js → Item Acquisition: Loot + Visual Upload OCR apply (2.8.5 U-A4 split)
15. ui/ui-render-databank.js → Native Databank Tools: Threat/Consult/Eligible Perks/Bio-Scan (2.8.5 U-A4 split)
16. ui/ui-saves.js → save slots, file import/export, autocomplete
17. ui/ui-account.js → renderAccount, renderSavesList, undoLastSync
18. services/ocr.js → window.routeVisualUpload (lazy Tesseract.js OCR; never loads at boot)
19. core/runtime.js → window.AmbientRuntime (lifecycle state machine + observer scheduler)
20. ui/ui-core.js → appendToChat, loadUI, updateMath (the ui-core spine hub)
21. ui/ui-core-nav.js → selectSubsystem, switchTab, SHORTCUT_ROUTES (2.8.5 U-A1 split)
22. ui/ui-core-overseer.js → setOverseerState, the Director Uplink scope canvas (2.8.5 U-A1 split)
23. ui/ui-core-chassis.js → _coreRefresh, initChassisCore, System Status (2.8.5 U-A1 split)
24. ui/ui-core-modulebay.js → renderModuleBay, the campaign-config board (2.8.5 U-A1 split)
25. ui/ui-core-cmd.js → native stat setters, COMMAND_REGISTRY (2.8.5 U-A1 split)
26. dev/test-console.js → window.initTestConsole (Diagnostic Shell; gated by _devConsoleUnlocked)
27. services/api.js → transmitMessage, fetchAuthorizedModels, comm-config cache (2.8.5 U-A3 split)
28. services/api-directive.js → getSystemDirective + its 8 _directive* section builders (2.8.5 U-A3 split)
29. services/api-import.js → autoImportState, sanitizeImportedContainer (2.8.5 U-A3 split)
30. services/api-router.js → NATIVE_COMMAND_ROUTER, transmitTerminal, quick-log routing (2.8.5 U-A3 split)
31. services/cloud.js → window.saveCurrentToCloud / window.loadCloudSave (ES module)
ARCHITECTURE.md is the canonical deep reference (persistence lifecycle, audio chain, boundaries, and add-a-field/audio/panel checklists).
- Node.js — the version pinned in
.nvmrc(currently Node 24, the active LTS line). Dev tooling only; not required to run the app. Both the local gate and CI (Linux + Windows) read this same file so every environment runs one Node version. - A Google Gemini API key — optional; the native tools and the whole terminal work without one
git clone https://github.com/zerckzzyHD/Robco-UOS.git
cd Robco-UOS
npm install # dev dependencies (ESLint, Prettier, Vite, Playwright)npm run dev # Vite dev server with hot reload (typically http://localhost:5173)- Open the terminal and let the boot sequence finish.
- Pick your game (New Vegas or Fallout 3).
- (Optional) Paste a Gemini key in Configuration → VALIDATE KEY & FETCH ENGINES, then pick a model — only needed for the AI Director.
- Start playing: type commands or free text in the Comm-Link, or use the native tools (VATS, TRADE, THREAT, CONSULT, BIO-SCAN, LOOT) with no key at all.
This is a static site — no build step to run it.
- Production: GitHub Pages at https://zerckzzyHD.github.io/Robco-UOS/, built from
mainand release-gated — it publishes only on a version release. - Staging: a private Cloudflare Pages build from
dev(robco-uos-dev.pages.dev) for real-device testing, auto-deployed on every dev push and stamped as a DEV BUILD. - Post-deploy release receipt:
npm run release-receipt— a manual after-a-deploy check (not a gate step) that fetches the LIVE site and confirms the served version + cache stamp match the deployed commit, so a silently-failed update ("pushed ≠ live") is caught loudly instead of leaving users on stale code. It names the parts only a real device can confirm (installed-PWA upgrade, save survival, auth) and leaves those to you.
npm run lint # ESLint (zero warnings)
npm run format # Prettier
npm run dev # Vite dev server
npm run gate # FULL gate: lint + format + Node runner + boot-smoke + render + a11y + test.html
npm run gate:fast # Fast subset run by the pre-commit hook
npm run gate:iter # OPT-IN iteration pre-check (lint changed + format + Node runner); never a commit/push gateCommits and pushes are blocked unless the gate is green. The pre-commit hook runs the fast subset (lint, format, the Node test runner); the pre-push hook + CI run the full gate (adds Playwright boot-smoke, a 360/412 render-check, an accessibility baseline-diff, and the test.html runtime audit). A CACHE_NAME bump is required whenever a served file changes, and the test count is kept in sync across every doc in the same commit.
All unreleased work goes to dev; main is release-only. Each commit keeps the docs current and bumps CACHE_NAME when a served file changes.
npm run lint && npm run format
git add -A
git commit # pre-commit: cache-bump guard, then fast gate (Node runner)
git push origin dev # pre-push: full gate (+ Playwright + a11y + test.html)
Full Evolution Timeline
Began as a Google Gemini Gem — a system prompt that turned the Gemini chat into a Fallout: New Vegas game master, with all state tracked in the AI's context window via ASCII art.
Evolved into a standalone browser app: state offloaded to JavaScript, native Gemini API integration, the Tri-Node JSON contract, a modular file split, and PWA integration.
Procedural audio, CRT visual effects, the 14-faction network, the save envelope + cloud sync, the quest log, and the wiki-sourced Fallout Data Registry + combat database.
The browser-native era: a second game (Fallout 3) added as a first-class, fully data-driven context; the six heavy tools (VATS, TRADE, THREAT, CONSULT, BIO-SCAN, LOOT) converted to offline native calculators; nine device capabilities; per-game theming + identity; a comprehensive accessibility pass; cloud auth + a remote kill-switch; a hardened PWA auto-update flow; and a self-improving test gate.
The device made physical: the whole UI reframed as a reactive RobCo terminal — an illuminated bezel subsystem selector in place of the tab bar, hardware-styled OPERATOR / OPERATIONS / DATABANK / CHASSIS screens, a living Director Uplink, and a reactive power core with tactile feedback animations across the terminal. Deeper offline self-reliance (native item USE, TERMINAL-mode stat edits, native GPS/PERKS/level-up, travel-here), on-device Visual Upload OCR with an AI-vision fallback, ceremony moments, tighter mobile density, and a staging-only Diagnostic Shell.
A production-quality, two-game browser application with:
- Both Fallout: New Vegas and Fallout 3 as fully data-driven game contexts (
GAME_DEFS, per-game registries/databases/theming/identity) - Six native offline tools (V.A.T.S., TRADE, THREAT, CONSULT, BIO-SCAN, LOOT) — deterministic, no AI, plus a self-checked command registry
- Eight device capabilities (Wake Lock, Vibration, Web Share, Badging, Pip-Boy Radio, cold-start/degraded boot, Overseer's Log, High-Lumen Optics)
- Per-game theming — per-game default optic, dynamic "(Default)" label, per-game colour memory, per-game boot/save identity
- Device bezel chrome — the app renders inside a physical RobCo terminal casing, with the old tab bar replaced by an illuminated subsystem selector (OPERATOR/OPERATIONS/DATABANK/UPLINK/CHASSIS/SETTINGS + a flat DIRECTORY fallback) that routes through the same underlying tab router; CHASSIS hosts device telemetry + firmware/carrier/feature-flag status, and SETTINGS is the one home for Account, the Module Bay, Save Archive, and Campaign Configs
- Fallout 3 landscape Pip-Boy — rotate a Fallout 3 campaign sideways and the same three subsystem keys, the UPLINK/CHASSIS/SETTINGS controls, and a flat directory recast as a real Pip-Boy 3000 casing: three domed lamps reading STATS/ITEMS/DATA (with their real names riding along underneath), a radio knob with a swinging tuner pointer, a status gauge with a needle and chrome ring, and a toggle switch with a real lever, all set in a dark, weathered metal casing that now wraps the glass on both sides with a system-status gauge, an embossed nameplate, and a brand plate above the screen, matching the real device's housing. Each of the six main screens is noticeably denser and closer to the game — S.P.E.C.I.A.L. shows a fill bar per attribute, body-part health boxes are labeled, and your Vault Boy figure now shows a dashed outline and the word CRIPPLED on a damaged limb, exactly like the real damage screen. Each screen's sub-sections get their own dash-separated row of tabs on the glass, scroll inside a bounded display that the casing can never cover, and remember which one you last had open. Portrait keeps today's layout untouched, and New Vegas is unaffected either way; a hand-inked Vault Boy figure (with distressed face and dashed CRIPPLED states) is now drawn in, while indicator sway and a working knob detent are still to come
- Schematic View — the flat fallback, per machine — the Module Bay's hardware boards have a permanent plain-list alternative that now covers every control the bay owns (all 14 sound-channel chips derived live from the bay itself, the AI key/engine/handshake, and the campaign-log export + app installer), sized to the mobile tap-target floor, and framed in each machine's own voice (a RobCo field service schematic on New Vegas, a Vault-Tec maintenance diagram on Fallout 3) while keeping identical control names and slot numbers so the two views can never disagree. Your choice of view is remembered across reloads. A build check enforces bay↔schematic parity, so a new board can't quietly go missing from the flat list
- Director Uplink — the living Overseer — the Comm-Link is reskinned as a phosphor-oscilloscope presence whose waveform reacts to the real AI lifecycle (listening/thinking/speaking/no-carrier/offline), with a per-game status strip and a self-contained mobile view
- Tool Deck + Quick-Draw Holster — a zero-footprint launcher key beside the Comm-Link message box raises a bottom-sheet deck for the six native tools, and the old blind D-Pad shortcuts are redesigned into four gear-vector sockets that show, fire, and let you rebind your quick-draw gear
- OPERATIONS — the quartermaster's freight console — your inventory screen reads as freight-handling hardware: a LOAD-CELL WEIGH BRIDGE bends a physical load beam in live proportion to your carry weight (nominal/amber/SEIZED), a six-drawer CARGO MANIFEST replaces the flat item filter with pull-drawers that scroll in place (every item reachable, nothing capped), items can be equipped or bumped in quantity right from their row, and FIELD FABRICATION/BARTER UPLINK/SQUAD ROSTER/CURIO ARCHIVE match the same hardware language (with SQUAD ROSTER's companion list now correctly reading each game's own roster)
- OPERATOR — SKILL MATRIX / STATUS EFFECTS / FACTION STANDING reskins — your skills show as a 13-channel drag-to-set VU meter array, active status effects light up as color-coded compound lamps (buff/debuff/neutral) with a tick countdown and purge key, and faction standing is one shared INFAMY◂▸FAME reputation console with a per-faction channel selector and an all-faction mini-pin strip so nothing is hidden
- DATABANK — The Records Bay — your world map is a real spatial "Phosphor Cartography" chart: surveyed locations glow as connected nodes tracing a known-route trail, a radar sweep and a blinking "YOU ARE HERE" marker bring it to life, and uncollected snow globes/bobbleheads/Lincoln memorabilia show as distinct signal-return glyphs; your quest log is a numbered directive rack with status lamps, a filterable status drawer bank, and a native CYCLE key to advance a quest's status yourself; the databank search, campaign record, campaign notes, and session stats all match with an amber query terminal, a tape-spool chronicle, a filterable field-notes ledger, and a mechanical odometer counter bank
- Full character/world systems — SPECIAL, per-game skills, limbs, perks, quests, factions, world-grid map with mark-visited, and trackers (collectibles, Lincoln memorabilia, traits, skill books, magazines) + a crafting panel
- Native USE + TERMINAL stat edits — using an aid item now applies its real effect (heal, rads, limb repair, a timed buff, clearing an addiction or poison) instantly and offline, with no AI round-trip; typing straight into the TERMINAL command line can set or nudge any stat, SPECIAL attribute, or skill, or grant a level, all deterministic and fully offline
- [GPS]/[MAP] and eligible-perks lookup — native, no AI — the compass-grid command now jumps straight to the CARTOGRAPHY TABLE instead of round-tripping to the AI; leveling up reports your real skill-point pool (10 + INT/2) so you can allocate it yourself via SKILL MATRIX, without moving your scroll position; and a new
[PERKS]/[PK]command lists every perk you already qualify for at your current level, straight from the registry - TRAVEL HERE on the world map — native, no AI — tapping a location's sector sheet on the CARTOGRAPHY TABLE now offers a TRAVEL HERE button beside MARK SURVEYED, instantly setting that location as your CURRENT position (and marking it visited) with no AI round-trip
- Visual Upload — native on-device OCR, AI-vision fallback — attaching a screenshot now scans it right on your device by default (self-hosted, lazy-loaded Tesseract.js), works fully offline after first use, and shows a review screen you confirm before anything is added; if the on-device scan is unavailable or fails, it hands off to the existing Gemini-vision path automatically, or on request via a TRY AI VISION button — both are remotely kill-switched with a graceful "add items manually" fallback if neither is available
- Ceremony Moments — starting a new campaign runs a short, skippable commissioning sequence instead of two bare reset lines; the Director now greets you the first time you open the Uplink each session; a post-update boot calls out the update with a POST line, a casing glint, and a highlighted revision-log button; returning after a few days away gets a quiet "recalibrating" boot line; and Module Bay/cartridge/Tool Deck installs now get a consistent physical settle flourish (SEAT, the third Protocol UI-9 motion verb)
- Tighter mobile boards — on narrow phones, board spacing, faction/status/perk/skill tiles, and the Director Uplink transcript all sit a little closer together, trimming a noticeable amount of scrolling with every tap target still comfortably above the minimum touch size
- Diagnostic Shell (dev/staging-only) — the developer console is re-founded on a data-driven tool registry with a two-signal environment gate, so a future non-destructive sandbox and an owner-only toolbench can share one panel without ever leaking a destructive tool to a live player; every existing dev control still works exactly as before
- Optional AI Director — Tri-Node JSON, validated import, resilient + prompt-injection-hardened
- Saves & cloud — auto-save, A/B/C slots (with confirm-gated overwrite/delete + version history), export/import + migration, rolling checksummed backups, additive Firestore sync (with its own confirm-gated overwrite/delete + version history), Google sign-in, remote kill-switch, per-game filtered saves list, read-side fail-loud integrity (corrupt saves quarantined + recoverable, eviction detection, degraded-write notices)
- Accessibility + PWA — focus rings, reduced-motion, live regions, dialog focus traps, AA contrast; installable, offline, reliable auto-update; touch-first responsive
- Wiki-sourced data — per-game Fallout Data Registries + combat databases (weapons, armor, bestiary, chems, recipes, vendors, quest items), all from the Independent Fallout Wiki
- A self-improving gate — a broad behavioural and static-invariant suite in the canonical Node runner, plus Playwright boot-smoke / render-check / a11y baseline and a
test.htmlruntime audit; CI + a nightly run back it up
| Document | Description |
|---|---|
| ARCHITECTURE.md | System dependency map, persistence lifecycle, audio chain, boundaries, and add-a-X checklists |
| PRIVACY.md | Plain-English privacy policy — what is stored, where, and how to delete it |
| CHANGELOG.md | Full version history (also read by the in-app FIRMWARE REVISION LOG viewer) |
RobCo Industries (TM) — Unified Operating System Copyright 2075-2077 RobCo Industries
Built with vanilla JavaScript, procedural audio, and an unhealthy obsession with CRT aesthetics.
Game data sourced from the Independent Fallout Wiki under CC-BY-SA 3.0.