Files

8.1 KiB

AGENTS.md — SciFi-XZBT

Guidance for AI coding agents working in this repository.

What this project is

A browser-only, zero-dependency sci-fi ambient audio + visual display. It synthesizes starship room tone (hull drone, worp core, life support, telemetry, alerts) with the Web Audio API and renders LCARD-styled UI, an audio visualizer, and a procedural "observation" viewscreen on HTML canvas.

It runs by opening index.html in a browser. There is no build step, no package manager, no server, and no test suite.

Architecture

index.html loads one stylesheet and eight scripts in a fixed order:

css/style.css
js/audio.js               -> js/config.js -> js/core-animations.js -> js/visualizer.js
js/observation-bezels.js  -> js/observation-engine.js
js/midi.js                -> js/generative-experience.js -> js/app.js

Order matters: every file defines plain classes/objects and publishes them on window; js/app.js runs last and consumes all of them. Do not reorder the tags without checking the dependencies.

File Owns ~Lines
index.html DOM skeleton, script/link tags 460
css/style.css LCARD themes, CRT effects, palettes 2,430
js/audio.js AudioManager, FuturisticNoiceCancellation + all synth classes (hull, warp, life support, telemetry, alert, Whataverse, expanded sci-fi) 6,890
js/config.js StarshipPresets, UniverseRegistry — data only, no behavior 1,170
js/core-animations.js CoreAnimations — settings-panel core animations 220
js/visualizer.js StarshipVisualizer — spectrum + worp core canvas 670
js/observation-bezels.js ObservationBezels — procedural SVG viewport frames per era 270
js/observation-engine.js ObservationEngine — celestial simulation, canvas rendering, per-universe waveform 3,590
js/midi.js XZBTControlBus (semantic control registry) + XZBTMidiController (Web MIDI / MIDI learn) 170
js/generative-experience.js XZBTGenerativeExperience — optional local LLM narration and neural speech 1,370
js/app.js DOM bindings, hotkeys, UI controllers, main loop 4,440
tools/package.ps1 Builds the standalone single-file HTML
dist/SciFiAmbientDisplay_V<commit>.html Generated output — never edit by hand

Hard constraints

  • No dependencies. No npm, no CDN links, no external fonts, images, or audio files. The packaged build must work when double-clicked while offline.
  • No ES modules. No import / export, no type="module". Scripts are classic globals.

The one documented exception

js/generative-experience.js is the only file permitted to reach the network, and it is the only file permitted to use import. It lazily pulls WebLLM and Kokoro via dynamic import() from CDN:

this.webllm = this.webllm || await import('https://esm.run/@mlc-ai/web-llm');
this.kokoroModule = this.kokoroModule || await import('https://esm.sh/[email protected]?bundle');

The exception is bounded, and every bound is load-bearing:

  • The imports live inside prepareExperience() / prepareTTS(). Nothing is fetched at parse time, so the packaged single-file build still opens and runs fully offline — the Generative Experience panel simply stays on STANDBY.
  • Both are guarded: navigator.gpu is checked before the WebLLM import, and a failed Kokoro load falls back rather than throwing.
  • No other subsystem may depend on this one. The deterministic engine stays authoritative; the LLM only verbalizes world state that audio.js and app.js already decided.

Do not widen this exception. New network use anywhere else, a static <script type="module">, or a top-level import in any file is still a bug. Web MIDI (js/midi.js) is a browser API, not a dependency, and is unaffected.

  • Publish globals explicitly. End each file with window.Thing = Thing;, matching the existing pattern.
  • All audio is synthesized, not sampled. New sounds are built from oscillators / noise / filters in js/audio.js.

Where to make a change

  • New room or ship preset, universe, palette → js/config.js
  • Sound generation, oscillators, envelopes, filters → js/audio.js
  • FNC comfort-filter behavior, source attenuation curves → FuturisticNoiceCancellation in js/audio.js
  • MIDI mapping, learn flow, new controllable targets → js/midi.js (register targets on the bus in js/app.js)
  • Speech profiles, prompts, LLM/TTS handling → js/generative-experience.js
  • Spectrum bars, warp-core animation → js/visualizer.js
  • Viewscreen frame / bezel shapes per era → js/observation-bezels.js
  • Planets, stars, drift, observation-mode canvas → js/observation-engine.js
  • Buttons, sliders, hotkeys, state wiring, animation loop → js/app.js
  • Colors, layout, theme classes, CRT overlay → css/style.css

Presets in config.js follow a fixed shape — copy an existing one rather than inventing fields:

'era-room': {
  id, name, era, theme, alertType, description,
  hull:        { volume, baseFreq, filterCutoff, resonance, noiseMix, harmonicSpread },
  warp:        { volume, bpm, carrierFreq, filterCutoff, pulseShape, resonance, swirlMix },
  lifeSupport: { volume, noiseType, highpassFreq, lowpassFreq, airflowModSpeed, airflowModDepth },
  telemetry:   { volume, density, era }
}

Adding a new JS file

  1. Create js/your-file.js and end it with window.YourThing = YourThing;.

  2. Add the tag to index.html in this exact form, positioned before any file that depends on it (and always before js/app.js):

    <script src="js/your-file.js"></script>
    

    tools/package.ps1 inlines assets by matching <script\s+src="([^"]+)"></script> and <link\s+rel="stylesheet"\s+href="([^"]+)"\s*/?>. Extra attributes, a different quote style, or a self-closing script tag will be silently left as an external reference and the standalone build will break.

Build

powershell -ExecutionPolicy Bypass -File .\tools\package.ps1

Writes dist/SciFiAmbientDisplay_v4.html (CSS and JS inlined). Re-run it after any change to CSS, JS, or index.html. tools/extract.ps1 is the original extraction script, kept for reference only.

Verifying work

There are no automated tests. Verification is manual:

  1. Open index.html in a browser; check the console is clean.
  2. Exercise the affected area — play a preset, switch era/universe, enter the Watch Experience, toggle FNC.
  3. Re-run package.ps1 and open the generated dist/SciFiAmbientDisplay_V<commit>.html with the network disabled to confirm it is genuinely self-contained. The Generative Experience panel must report an error and everything else must still work — that is the test for the exception above, not a failure.

Browser autoplay policy blocks audio until a user gesture; audio starting only after a click is expected behavior, not a bug.

The Generative Experience needs a WebGPU-capable browser (Chrome/Edge) and network access on first preparation. Absence of either is expected to degrade quietly, never to break the console.

Conventions and cautions

  • 2-space indentation; single quotes in JS; existing brace and spacing style.
  • js/app.js, js/audio.js and js/observation-engine.js are large. Make surgical, scoped edits — do not rewrite, reorder, or reformat whole files.
  • Do not reformat or lint files wholesale; diffs should stay minimal and reviewable.
  • Never edit anything in dist/ — regenerate it instead.
  • Preserve the offline, single-file-deliverable property in every change.

Terminology

Theme_Terminology_IP_Changes.md is the authoritative rename table and applies to identifiers as well as display strings. The universe id is whataverse, the theme class is theme-whataverse-tardix, preset ids are tardix-*, and the telemetry era is 'whataverse'. Do not reintroduce the original franchise spellings anywhere, including in comments.

TelemetrySynth still accepts 'who' and 'what' as era values purely for backward compatibility with older presets; do not write new presets against them.