Untitled

Site

WebRTC experiment review — October 22

  • [x] Revise the WebRTC plan around a connectivity probe followed by a three-human, reliable-channel game experiment with rotated hosts. Prioritize authoritative turn-position error in cycle lengths and non-host tail latency; document existing input/delta constraints, worker delivery stalls, concurrent STUN/TURN setup, explicit host-stall aborts, and gates before unreliable delivery or private-room productization. Documentation only; implementation/deployment remain unapproved.

WebRTC private-match proposal — October 21

  • [x] Write a review plan for peer-hosted WebRTC matches, including authority, STUN/TURN/signaling, loss recovery, host lifecycle, browser coverage, measurements, and dedicated-server alternatives. Proposal only; implementation and deployment are not approved. The public-arena hosting plan remains unchanged.

Automatic program-file recovery — October 21

  • [x] Inline a production-only recovery handler before the entry module so missing entry scripts, failed dynamic imports, and failed module/style preloads can recover at the ordinary game URL. Application-caught module errors use the same handler. Verify fresh HTML is reachable before unregistering only the exact game worker scope and clearing only this game's cached HTML/JS/CSS; preserve media, IndexedDB/settings and unrelated app caches.
  • [x] Retry once, with a ten-minute session guard and a URL guard when storage is unavailable; remove the temporary cache-busting query after successful startup. Bound recovery to eight seconds. Offline/unreachable-host and repeated failures show a message instead of looping. The error panel's reload action stays on the ordinary page.
  • [x] Service-worker navigations revalidate HTML against the host, with a 2.5-second timeout and installed-build fallback. Media stays cached, and background worker updates still wait without interrupting active play. Existing cached documents must receive this release before its inline recovery can run; this does not establish that the reported Chrome failures were cache-related.
  • [x] Chrome fixture tests pass for missing initial modules, scoped cleanup/media preservation, unreachable-host preservation and persistent-error loop prevention. Built-game tests pass for legacy cached-build migration, automatic failed multiplayer import recovery without an update-page visit, offline CLU/cycle/BIT resources, ranged audio and background updates that leave the menu/game intact.

Stable bloom with scene antialiasing — October 21

  • [x] Reproduce rectangular image loss in fresh headless WebKit on macOS during solo opening viewport changes. A frozen-frame comparison isolates bloom; subsequent HDR readback found non-finite scene color components. Bloom spreads these through its mip chain. The earlier suspected MSAA resolve explanation was not sufficient: separating buffers alone still reproduced the defect.
  • [x] Render the scene into a dedicated HDR multisample/stencil target, then copy to single-sample composer buffers with a finite-radiance guard before bloom. Replace NaNs with zero and bound radiance to 0–1024 to prevent non-finite values contaminating the blur. Retain adaptive scene MSAA and supersampling; dispose the extra scene target/copy pass with the view. This adds one full-screen copy and a dedicated scene buffer.
  • [x] Replace the shadow Gaussian's negative-base GLSL pow with direct multiplication; pow on negative bases is undefined even for an exponent of two. This correctness fix alone did not remove all non-finite scene pixels. Their remaining source needs investigation if localized defects become visible.
  • [x] WebKit and Chrome opening resize checks pass at four viewport sizes with finite-pixel readback of both composer buffers; inspected 1920px captures show the complete scene. Production build and asset audit pass. Native macOS fullscreen transition still needs user confirmation.

Controls help shortcut — October 20

  • [x] Move the controls-help shortcut from C to Y in CLU and cycle games to reduce accidental activation. Update desktop hints and browser checks; touch controls remain available.

Continuous multiplayer scenery motion — October 20

  • [x] Carrier positions are local, but previously used the snapshot-stepped match clock. Give the carrier, Solar Sailer and clouds a continuous local rendering clock in multiplayer, independent of packet arrivals and round resets. Solo scenery uses interpolated simulation time. Keep the authored opening carrier placement unchanged.
  • [x] All 642 unit tests pass, including packet holds, backwards timestamp corrections, round resets and solo pause/reset coverage. Local headless Chrome on macOS verified continuous carrier displacement across 179 multiplayer frame intervals with no page errors (node test-results/carrier-clock-check.mjs). Subjective play confirmation remains pending.

Restore aircraft antialiasing quality — October 19

  • [x] Investigate the quality change introduced with ray-cast cycles: the former 1.25–1.5× scene supersampling became a 1× starting level, and temporary frame-budget misses permanently lowered the session ceiling. This affects rasterized Recognizers and Solar Sailer geometry as well as cycles.
  • [x] Start scene and ray-cast renderer quality controllers at 1.5× with up to supported 4× MSAA, retaining pixel/texture budgets. Keep the fallback floor at native resolution rather than 0.85×. Retry rejected levels after sustained headroom and a 60-second cooldown, backing repeated failures off up to five minutes. Performance fallback remains available.
  • [x] Chrome rendered aircraft comparisons at 1×/1.5× show cleaner Recognizer edges; Solar Sailer captures also generated. Real framebuffer test confirms 1.5×/4× initial quality, native-resolution fallback, later recovery, and restoration of independent normal/ray-cast controllers. Unit tests cover sample support, startup quality, temporary stalls and bounded retry behavior. Higher starting resolution costs more GPU work; actual hardware can still reduce quality under sustained load.

Multiplayer delivery resilience and host diagnostics — October 19

  • [x] Send authoritative snapshots at 30 Hz (120 Hz simulation unchanged). After catch-up, encode/broadcast only the latest state, retaining all simulation steps and trail corners. This avoids queuing obsolete intermediate snapshots. The additive metadata and cadence change remain compatible with protocol 5.
  • [x] Adapt confirmed-path playback between 75 and 125 ms using a bounded arrival-gap window. Healthy delivery returns to the 75 ms floor; clock adjustments remain monotonic and capped at ±2%. Local input prediction remains immediate. Extreme outages still hold the last confirmed pose.
  • [x] Expose tronMultiplayerReport() while connected: bounded RTT, arrival gaps, send/arrival interval variation, buffer size/holds, and host pump counters. Server diagnostics report late callbacks, maximum callback gap, catch-up steps and discarded elapsed time. They measure scheduling, not CPU execution cost. Arrival minus send interval variation includes network and receiving-process scheduling, without requiring synchronized clocks.
  • [x] Seeded 60-second moderate-jitter replay: 20 Hz fixed buffer held 37 frames; 30 Hz adaptive buffer held zero after warmup. A previous production trace with much longer outages improved only from 148 to 142 held frames; buffering is deliberately capped rather than hiding those outages with excessive latency.
  • [x] Straight-motion interpolation skips full trail-history scans when the snapshot pair contains no turn. Corners still walk confirmed trail segments.
  • [x] Instrumented production sample (65 seconds): snapshot-gap p99 60.9 ms, 11 gaps over 75 ms, ~20 KB/s, ~119.8 ticks/sec. Host runtime counters: maximum callback gap 16 ms, no callbacks over 50 ms, no discarded time. RTT was higher in this separate sample (median 374 ms), so before/after network numbers are not a controlled performance comparison. Host timers are I/O-updated and cannot measure CPU execution cost; see Cloudflare timer semantics. This does not conclusively exonerate the host or identify the RTT source.
  • [x] A separate 20-second production repeat measured median RTT 79.4 ms, p95 RTT 93.6 ms, maximum snapshot gap 57.7 ms, and zero gaps exceeding the base 75 ms buffer. Runtime counters again showed no late callbacks. The large RTT variation between runs remains unattributed.
  • [x] Reproduce a bounded probe with node tools/validation/measure-multiplayer.mjs; it joins as one participant. MP_PROBE_SECONDS, MP_PROBE_URL, MP_PROBE_ORIGIN, and PROBE_REPORT configure the run. Long observation gaps are flagged rather than silently counted as normal scheduling.
  • [x] 639 unit tests, production build/asset audit, and rendered two-client/14-connection multiplayer coverage pass. Regressions cover bounded buffer recovery, clock continuity, independently decodable catch-up snapshots and diagnostic attribution.

Gentler multiplayer clock corrections — October 19

  • [x] Local WebKit capture found playback-clock rates spanning approximately 0.914–1.10 despite no buffer underruns or backward motion. Packet scheduling jitter can vary the arrival-based clock even at near-zero RTT.
  • [x] Correct local prediction and remote playback clocks over two seconds, capped at ±2% instead of ±10% over a quarter-second. Keep the existing 75 ms remote buffer, immediate local input prediction, monotonic time, and pause recovery.
  • [x] Repeat WebKit capture measured rates 0.991–1.008 with no buffer holds or backwards motion. Eight playback regression tests pass, including timer batching, packet jitter, corners, and combined server/render stalls. This addresses measured speed pulsing; subjective play verification and other sources of stalls remain possible.

Single-line boot progress — October 19

  • [x] Replace the current boot status in place rather than appending completed stages. Retain the ENCOM heading, animated dots/cursor, half-second stage threshold, and full console timing report.

Reuse startup patrol connectivity — October 18

  • [x] Investigate the Safari screenshot showing 23,328 ms of enemy placement in a 26,481 ms boot. Random patrol candidates could repeatedly search the large labyrinth for a route to the same destination. Reuse collision-checked route points within each placement pass; nearby candidates/search nodes can join a proven route through a swept-clear segment. Sealed pockets still require rejection; gameplay pathfinding remains unchanged.
  • [x] Keep connectivity proofs local to a placement pass so seeded results do not depend on earlier games. Include layout/run seeds in the console loading report for exact reproduction of outliers.
  • [x] Local headless WebKit 26.6 on macOS: fixed-seed placement 1.4–1.8 s → 0.39–0.46 s; eight randomized boots reached the menu in 3.59–4.92 s, placement 0.66–1.99 s. The user's exact 23-second seed was not captured, so this is not proof that all outliers are eliminated.
  • [x] Full 634-test suite and production build/asset audit pass. Additional regression records swept-clear segments and independently checks that every spawned labyrinth tank is connected to its beam; cache tests cover separating walls, distant points, and reproducibility after another seed.

Lazy Solar Sailer — October 18

  • [x] Remove Solar Sailer loading from boot and from eager credit-preview imports. Start its optional background load after 30 seconds of local active play in CLU, solo cycles, or multiplayer; server match age does not trigger it immediately. Credit preview loads it on demand. Existing flyby scheduling joins naturally when resources arrive; no mode waits for this scenery.
  • [x] Yield between model adaptation phases so that resource preparation allows rendering. GLTF parsing and later GPU upload still use the renderer/main-thread pipeline; this is not a worker-decoding implementation or a guarantee of zero frame stalls.
  • [x] Browser checks verify no renderer/model request during boot or program entry, followed by a single model load in each of the three game modes. Offline PWA asset caching remains unchanged and may fetch the source asset in the background.

Reuse materialization edge calculations — October 18

  • [x] Trace materialization edges once per shared mesh geometry, then clone the resulting line buffers per vehicle. A weak cache follows source geometry lifetime and invalidates on position/index replacement or version changes. Materials, colors, animation uniforms, GPU buffers, and disposal remain independently owned.
  • [x] Fixed layout/run seed 1982 in local Chrome 155 headless: cached boot approximately 5.84 s → 3.86 s; rendering-world setup approximately 2.32 s → 1.07 s; arena setup approximately 1.33 s → 0.72 s. This reuses CPU calculations without reducing geometry fidelity.
  • [x] All 632 unit tests pass. Browser comparison of a warmed-cache Recognizer materialization against freshly calculated Three.js edges produced identical geometry and pixels (1,432 wireframe vertices). Unit regression covers buffer independence, disposal, and source-geometry changes. Production build and asset audit pass.

Startup scheduling — October 18

  • [x] Keep seeded simulation initialization sliced into 8 ms CPU budgets, but yield through scheduler.yield() (ordinary timer task fallback) instead of waiting for a full animation frame per slice. Rendering setup retains its existing paint boundaries. Asset caching avoids transfers, not simulation construction, model adaptation or GPU setup.
  • [x] Chrome 155 headless on macOS, fixed layout/run seed 1982: initial simulation approximately 2.44 s → 1.07–1.11 s; cached terminal ready approximately 7.02 s → 5.84–5.86 s. Timings are local development measurements, not production/Safari guarantees. Browser startup responsiveness checks pass in Chrome and WebKit: animated dots, repeated world-build paints, and cycle launch. WebKit startup frame gaps stayed under 25 ms in the measured runs. Full 631-unit suite passed.

ENCOM boot transcript — October 18

  • [x] Show stage-specific ENCOM progress messages for work lasting at least 500 ms, and retain only completed stages meeting that threshold. Omit aggregate startup timings and checkpoints from the transcript; no elapsed times appear on screen. Keep detailed console timing diagnostics unchanged. Append individual lines without rebuilding the transcript; preserve the animated working indicator and scroll within the existing terminal margins on small screens.

Continuous grid speed — October 18

  • [x] Solo, multiplayer authority/prediction, and AI forecasts now use a smooth additive increase of 1% of initial speed per elapsed racing second, retaining the 200% cap (reached at 100 seconds). New rounds reset to 100%; staging and paused arenas do not advance the clock.
  • [x] Keep GRID SPEED visible throughout countdown, racing, and results. Remove speed-increase beeps and temporary warning countdowns entirely; match countdown audio is unchanged. Multiplayer protocol advances to 5 because predicted movement changed; deploy client and Worker together.
  • [x] Unit checks cover linear progression, the cap, scaled turbo/brake and AI forecasts, reset/pause behavior, and persistent indicator text.

Per-play analytics and exit announcement — October 18

  • [x] Production play markers distinguish space-paranoids, cycles-solo, cycles-mp, and bit. Space counts once when a fresh run reaches running mode; cycles count each racing round with a living assigned player (not spectators); BIT counts once after microphone permission and actual activation. Pause/resume and menus do not count. Markers honor analytics opt-out, are excluded from offline precache, and use one temporary iframe. App-start tracking is unchanged.
  • [x] Chrome headless production-build fixture verified exact mode/restart reports, BIT deduplication, no menu/spectator/development/opt-out reports, and one iframe; all Cloudflare report uploads intercepted and aborted. Unit test verifies run/round transitions. Scratch Vite builds now honor their output directory in the public-assets plugin.
  • [x] Replace the runtime illegal-exit announcement with the approved Runway transport-reference voice and subtle loudspeaker effects. Preserve the dry source and generation provenance. Add 14.95 dB with peak limiting to match the previous clip at −21.23 LUFS (measured true peak −1.85 dBTP). Existing per-player escape trigger and playback gain remain unchanged. Prior Leda source is retained; the original isolated film audition remains source-only.

title: Implementation plan topTitle: TRON subtitle: Current simulation scope, decisions, and acceptance criteria

Extended model and open-source acknowledgments: Extended credits.

Archived original grid-announcer recordings — October 18

  • [x] Preserve approved clean ElevenLabs transport isolation and its loudspeaker/echo version under assets/source/audio/grid-announcer, alongside the original illegal-exit isolation and matching effect audition. All four are catalogued source-only with provenance and verified hashes; no runtime references or playback changes. The existing generated exit announcement remains active pending approval of the original-voice replacement.

Solo roster player marker — October 18

  • [x] Show the black/white player slash on the solo player's roster circle only, with PLAYER accessibility text. Do not change cycle human flags or the rendered bike. MP spectators remain unmarked unless following an actual human. Headless Chrome roster checks pass, including no bike-state mutation and solo/MP marker transitions. Local change; not deployed.

Three-cycle team announcements — October 18

  • [x] Starting team speech only plays for an assigned team with exactly three cycles in solo or MP. Count team roster slots rather than surviving cycles so an early crash does not cut off speech. Smaller teams do not consume the first eligible announcement; eligible rounds retain the 20% later-match probability and equal original/alternate selection.
  • [x] All 18 team-voice unit tests pass, including one/two/four-cycle exclusion, other-team isolation, solo/MP coverage and teammate death during playback. Browser fixture updated to use three-cycle teams. Local change; not deployed.

Arena escape alarm — October 17

  • [x] A confirmed player cycle escape alerts all active arena-patrol Recognizers with a one-time position/velocity report. Guards leave their patrol route, investigate the exit and pursue upon visual acquisition using existing perception, search, attack and target-retirement behavior. No unseen live tracking; ordinary non-grid patrols receive no direct alarm. Initial outside testing spawns do not trigger it.
  • [x] Alarm clears stale neutralization state for the new escape but does not activate destroyed/materializing/teleporting guards. Multiplayer still silently derezzes escaped riders, so this pursuit applies to the surviving solo road cycle. Tests cover multiple guards, immutable observations, exclusions and an actual GameSession breach crossing. All 630 unit tests and production build/asset audit pass; pursuit feel has not been browser-playtested. Local change, not deployed.

Local illegal-exit announcement — October 17

  • [x] Use the approved Gemini Leda flight-controller reading with loudspeaker EQ and subtle echo when a rider clears the arena boundary through a breach. Shared simulation increments an escape revision, carried in MP snapshots; only that client's assigned seat hears it. Solo uses the player cycle. Spectator targets, ordinary crashes, initial outside spawns and joining after an escape do not trigger speech.
  • [x] Play once per confirmed exit, including subsequent solo exits after reentry. Mute, home/disconnect, reassignment and new rounds cancel; missing/muted audio does not replay later. Allow the line through the result hold after a silent MP exit. Stop any overlapping team-leader line. Existing MP derez behavior is unchanged.
  • [x] Preserve the dry generated master, generation direction and processing provenance; runtime contains only the approved processed recording. All 628 unit tests and production asset audit pass. Headless Chrome verifies actual sample loading/decoding and playback (10.17 seconds) without errors. Local change; not deployed, and MP requires the updated Worker snapshot field.

Escalating light-cycle grid speed — October 16

  • [x] Solo, multiplayer authority and JavaScript AI training share a 10% compounded speed increase every 15 seconds of active arena racing. Each increase ramps over one second, caps at 2× starting speed, and resets each match. Cruise, turbo and braking speeds scale together; reserve capacity/recharge and reaction times are unchanged. Paused/outside-arena play and staging/result time do not advance the ramp.
  • [x] Display a silent SPEED INCREASE IN 3/2/1 countdown, followed by one confirmation beep when the increase begins and GRID SPEED: N% for three seconds (October 17 adjustment). No further warning at the cap; no backlog of beeps after mute/network gaps. Uses terminal HUD styling.
  • [x] AI speed forecasts and local MP prediction account for grid speed. Snapshots include the grid multiplier and protocol advances from 3 to 4 to reject outdated current clients. Requires coordinated client/Worker deployment. Existing AI policies are unchanged; no evolution run has been performed under the new rules yet.
  • [x] All 620 existing unit tests plus five new speed-ramp tests pass. New coverage checks proportional cruise/turbo/brake motion, AI forecasts, cap, staging/pause/reset, warning timing and beep deduplication. Production build/asset audit passes. Headless Chrome at 1280×800 verifies the rendered solo 3/2/1 countdown, 110% notice and actual accelerated cycle speed without page errors; screenshot inspected (test-results/cycle-speed-ramp.png). Local implementation; not deployed.

Solo team radio — October 16

  • [x] Enable the existing team radio path for solo cycle play using the player's cycle team. Preserve the one-second launch delay, first-match guarantee, subsequent 20% chance, equal choice between original/alternate recordings, and existing gains. Non-cycle play and disconnected multiplayer sessions remain ineligible. Returning home resets the guarantee; solo retries preserve it.
  • [x] Seventeen focused unit tests pass, including solo selection/retry/session reset and disconnected multiplayer isolation. Headless Chrome verifies all eight recordings decode, schedule and play in both solo and MP paths without page errors. Production build and asset audit pass. Local change; not deployed.

Alternate team radio lines — October 16

  • [x] Add a second generated line for each team, selected 50/50 whenever an announcement plays. Keep the first-participated-match guarantee and subsequent 20% playback probability. Selection happens once per launch, never per frame. All generated clips use the increased gain; Blue's original film recording retains its existing gain.
  • [x] Revised alternate scripts: Gold “Gold team, stay focused. Make every turn count.” Blue “Blue flight, on me. Hold formation. Wait for my mark.” Green “All Green cycles. Keep them turning. Leave no way out.” Red “Red team, move in. Press the attack. Give them no room.” Same user-supplied Alan reference and commanding generation direction; masters and provenance catalogued. Gold, Blue and Green files run 4.08 seconds; Red runs 5.07 seconds. Radio treatment without time stretching. SHA-256 checks confirm all four original recordings are unchanged.
  • [x] Fifteen team-voice unit tests pass, including 50/50 selection boundaries, one selection per playback, original/alternate Blue gain, first-match and 20% behavior. Headless Chrome verified all eight buffers preload/decode and remain active after their scheduled delay without errors. Alternate set is integrated locally, not deployed.
  • [x] Prior release e209382 (website fb8c596, Pages run 38982565833) deployed successfully: first voice set, fourfold generated-voice gain, first-match/20% playback, multiplayer-first menu, early loading dots and hidden-mobile-label correction. Live browser check verified published menu, gains/probability and all four original voice assets.

Occasional multiplayer leader announcements — October 16

  • [x] Guarantee the local team's announcement on the first participated launch of a multiplayer session, then make one independent 20% draw per subsequent participated launch. Queued spectator rounds do not consume the first launch. Muted/missing audio consumes that match's decision without delayed replay. Returning home/disconnecting resets the session; changing rounds or teams does not restore the guarantee.
  • [x] All 11 team-voice unit tests pass, including exact probability boundary, one decision per round, first-match/reset behavior and spectators/mute. Timing, team selection and volume remain unchanged. Local change; not deployed.

Preserve hidden menu labels during transition — October 16

  • [x] Transition copies use rendered text rather than raw textContent, so the hidden CLU mobile restriction no longer appears on desktop when selecting CLU or another program. The actual mobile notice is retained when visible.
  • [x] Headless Chrome regression covers selected/unselected desktop CLU copies and visible mobile notice preservation. Whitespace checks pass. Local fix; not deployed.

Multiplayer leader radio for all teams — October 16

  • [x] Add user-approved Gold, Green and Red leader takes using the same local assigned-seat radio path as Blue. Preserve the original Blue sample. Every team hears only its own clip, once per round, scheduled one second after racing begins. Solo, queued spectators and mid-match joins remain silent; mute, disconnect, exit, reassignment and round/result transitions cancel playback.
  • [x] Gold: “This is Gold-1 to Gold-2 and 3. Split up. Take them one-on-one.” Green: “Green-1 to Green-2 and 3. Draw them in. Close the trap.” Red: “Red-1 to Red-2 and 3. Break formation. Cut them off.” Generated with Runway seed_audio from the user-supplied Alan voice sample. Approved masters, generation metadata, processing and underlying rights constraints are catalogued. Runtime uses approved radio treatment without time stretching. Gold, Green and Red playback gains are four times the original level (3.4 versus the unchanged Blue gain of 0.85), following the user’s second doubling request.
  • [x] Eight targeted unit tests pass, including every assigned team and a different spectator target. Headless Chrome loads/decodes all cycle samples without errors and verifies the correct buffer remains active after the one-second delay for each team (Gold 4.55 s, Blue 3.91 s, Red/Green 4.05 s). Production build/asset audit passes with all three new content-hashed audio assets. Local integration; not deployed.

Immediate loading status and multiplayer-first menu — October 16

  • [x] Put critical loading layout and dot-animation CSS directly in the entry HTML, so the status can paint before external scripts or styles arrive. Keep the discrete dot status active with reduced motion; cursor and other motion preferences remain separate.
  • [x] LIGHT CYCLES MULTIPLAYER is the first menu item and default selection. The explicit development cycleStart route still selects solo cycles.
  • [x] Headless Chrome and WebKit 26.6 verify all four dot states while every external script and stylesheet is blocked, in normal and reduced-motion modes. Chrome menu checks verify the first/default item, all hover targets, click/tap activation, credits return, keyboard selection and CLU launch. Production build/asset audit passes. These changes are local; no claim that all subsequent main-thread stalls are eliminated.

Foreground startup before offline installation — October 16

  • [x] Delay service-worker registration/update until the opening terminal is ready. Previously the window load event could start the approximately 90 MiB offline installation while the foreground was still fetching modules, models and audio. Existing installed workers still serve cached resources immediately; new installations begin after startup.
  • [x] Split startup instrumentation into entry-document/bootstrap, styles/terminal paint and game-module download/evaluation measurements. Safari unused-preload warnings alone do not identify a failed request or the cause of the reported 16-second pre-startup delay; download/evaluation timing is now separately observable.
  • [x] Production build/asset audit passes. Headless Chrome PWA test verifies registration occurs after menu enablement, installability, offline reload/play, ranged audio, and waiting updates through play/home until explicit update.html activation. Corrected an obsolete test expecting automatic activation on return home. This local change has not been deployed; no production speedup is claimed.

AI follow-up training — October 16

  • [x] Completed one bounded generation: current policy plus three mutations, three training seeds and four spawn rotations each, 60-second encounters, two workers; seed offset 360000. Current approach-340000-0-0 ranked first (fitness 1.0175 versus 0.7862, 0.6856 and 0.6053). No weights promoted.
  • [x] Selected policy then completed eight fresh seeds/four rotations: 14 wall eliminations and 7 trap-assist credits across 32 matches. All reached the 60-second limit without a winner, so this run does not establish full-match win-rate improvement. Candidate and baseline are identical because the incumbent won selection. Serial AI p99 0.204 ms and tick p99 0.276 ms pass the existing performance gates. Summary: tools/ai/results/mobile-followup-360000.json; full local record: test-results/cycle-ai-mobile-followup.json. Trainer exited normally.

Mobile programs and cycle controls — October 16

  • [x] Enable the terminal on mobile; disable only CLU, labeled “(UNAVAILABLE ON MOBILE)”. Mouse hover/click and touch taps select programs; keyboard navigation skips disabled choices.
  • [x] Cycle touch controls: tap left/right to turn (or follow while spectating), hold top turbo or bottom brake, with simultaneous steering and pedal input. MENU opens a tappable exit confirmation; CONTROLS explains gestures; eligible players can tap NEW MATCH. BIT and MCP also have touch exit menus. Pedals release on cancellation, blur, hidden controls and disposal.
  • [x] All 607 unit tests and production build/asset audit pass. Headless Chromium iPhone 13, iPad Pro 11 and Pixel 7 emulations verify menus and CLU restriction; desktop pointer tests pass. CDP multitouch verifies simultaneous turbo/turn, release/cancellation and brake. Actual solo launch, help, exit cancellation and return home pass. Physical mobile Safari/Chrome performance and feel remain to be checked. Deployed client 3883d5b via website 7bdeda8 (Pages run 38927792047 succeeded on retry after a dependency download timeout). Production headless iPhone emulation verified CLU disabled, multiplayer launch, touch guide and touch-only exit without page errors.

Multiplayer roster controls guide — October 15

  • [x] The multiplayer C / CONTROLS panel now explains team groups, filled active versus empty eliminated circles, the local player's white outline, gray waiting circles, wall-kill and hollow trap-assist dots, and opponent-colored dots. It explicitly identifies the black-and-white diagonal slash on both human cycles and their roster circles. Solo help is unchanged.
  • [x] Overflowing help starts at a reachable top edge and scrolls in short windows. Headless Chrome at 1280×800 and 1280×600 verified the actual MP controls content and heading accessibility with no page errors; inspected the rendered panel capture. Syntax and whitespace checks pass. Included in the mobile release authorized for deployment.

Blue-team multiplayer launch dialogue — October 15

  • [x] Preload the user-approved cycles_blue_leader_speech.mp3 as cycle audio. Only clients with an assigned BLUE seat schedule the non-spatial team-radio clip, one second after observing the countdown-to-racing transition. It plays once per round; solo play, queued spectators, other teams and mid-match joins do not receive it. Assignment, not the spectator camera target, selects the team.
  • [x] Mute, leaving play, disconnect, seat reassignment, round changes and results cancel pending/active playback. Audio nodes disconnect on completion/reset. Runtime asset is an exact copy, catalogued with film provenance and use constraints.
  • [x] Ten targeted multiplayer audio unit tests pass, including the exact one-second schedule and eligibility/lifecycle cases. Headless Chrome (TRON_URL=http://127.0.0.1:5188/ node tests/browser/multiplayer-team-voice.mjs) decoded the 3.91-second clip, preloaded every cycle sample without errors, and kept the scheduled voice active beyond the delay. Production build and binary/immutable-asset audit pass. User confirmed the blue speech sounds perfect. Approved for deployment with the ten-second result hold and initial placement responsiveness fix.

Initial placement responsiveness and longer result hold — October 15

  • [x] Initial enemy placement now consumes the same seeded simulation generator in approximately 8 ms work slices, yielding to browser paint between slices. Spawn-cell checks and maze-exit route searches both cooperate; synchronous simulation callers and restarts retain the same results and random order. This addresses the initial pause that preceded the earlier model-loading improvements.
  • [x] Headless Chrome 155, 1280×800 (TRON_URL=http://127.0.0.1:5188/ node tests/browser/loading-responsive.mjs): initial/cached navigation recorded 271/234 animation frames during placement, maximum frame gaps 16.8/21.4 ms, all four dot states, and successful cycle launch without page errors. Cooperative scheduling adds elapsed loading time to preserve UI responsiveness. Individual GPU compilation operations can still block later in loading.
  • [x] Multiplayer win/tie hold increased from 5 to 10 seconds before selecting the next roster. Regression verifies the roster stays fixed for the full hold. Seeded synchronous/asynchronous session equivalence, reset behavior and initialization failure propagation pass. All 602 unit tests and production build/asset audit pass. Isolated browser server stopped. Changes are local; the hold requires a multiplayer Worker deployment.

Responsive initial resource loading — October 15

  • [x] Model adaptation and world/cycle presentation construction now yield to browser paint between expensive phases, including cached loads. View factories finish asynchronously before the application uses them; background tabs have a timer fallback.
  • [x] node tests/browser/loading-responsive.mjs passed in headless Chrome 155 at 1280×800 on initial and cached loads: all four loading-dot states appeared, 54 frames were rendered during world construction in each run, and solo cycles launched without page errors. All 600 unit tests pass. Remaining limitation: initial simulation placement and individual GPU compilation operations can still block briefly; these are not moved to a worker.

Direct rotation into multiplayer formation — October 15

  • [x] Formation travel now interpolates toward the final shot's fixed orientation, rather than recalculating the destination orientation from each intermediate camera position. This removes a moving aim target that could cause an initial yaw detour or reversal. Position travel, wall-clearance arch, materialization and moving launch hold remain unchanged.
  • [x] Regression checks the rotation follows one shortest arc and never turns away from the final heading for all four teams. It fails on the previous implementation and passes with the correction. All 42 multiplayer unit tests pass. Headless Chrome 155 at 1280×800 (TRON_URL=http://127.0.0.1:5188/ node tests/browser/multiplayer-transition.mjs) verifies camera arrival, materialization, the moving launch hold and player follow with no page/shader errors. Production build/asset audit passes; isolated server stopped. Local change; not deployed.

Moving multiplayer launch hold — October 15

  • [x] Corrected the launch hold placement: server materialization lasts only the shared solo formation duration (1.833 seconds). Cycles then race and lay trails while the client holds the completed formation shot fixed for the shared 0.6-second launch hold, before cutting to player follow. Previously those 0.6 seconds extended the stationary countdown and the camera cut immediately on movement. A new round or result still releases an obsolete shot.
  • [x] All 41 multiplayer unit tests pass, including camera position remaining fixed while bike positions advance, then cutting after the hold. TRON_URL=http://127.0.0.1:5188/ node tests/browser/multiplayer-transition.mjs passed on headless Chrome 155 at 1280×800: all-camera barrier, visible materialization, fixed launch shot with growing trails, and subsequent player view. Inspected test-results/mp-team-launch-hold.png; no page/shader errors. Isolated test server stopped afterward. Local change; deployment requires both Worker timing and client camera updates.

Monotonic recovery after combined stalls — October 15

  • [x] Reproduced a backward-clock correction when a render pause over 200 ms coincides with slow server tick progress and a newly received snapshot. Restoring the normal playback buffer could then place the remote clock behind its last displayed pose; the predicted local camera clock had the same recovery hazard. Both now preserve their previous clock minimum within a round, while retaining fresh-clock initialization for a new round. No extra interpolation delay or invented remote turns.
  • [x] Seven playback regression tests pass, including the new combined-stall cases for remote cycles and local camera. The remote regression failed before this correction. A separate headless Chrome 155 diagnostic across two actual local matches recorded 843/750 racing samples, zero backward clock steps or held samples, and frame p99 17.6 ms in both rounds; it did not reproduce the user's ongoing jitter. The controlled stall regression establishes one real cause, not proof that every reported jitter source is fixed. Browser/direction clarification requested. Local change, not deployed.

First multiplayer formation readiness — October 15

  • [x] Camera readiness also waits for the asynchronous cycle renderer selection, completion of the home transition, a visible document and existing audio readiness. Previously the initial camera could acknowledge readiness while the detailed renderer was still loading/compiling, allowing the server's short formation timeline to advance underneath first-use work.
  • [x] Detailed cycles warm both transparent formation and opaque racing pipelines with asynchronous compilation plus small offscreen draws before reporting renderer preparation complete. The warmup restores the render target and material flags and disposes its temporary target. Later matches reuse the prepared renderer.
  • [x] Headless Chrome 155, 1280×800: node tests/browser/multiplayer-first-formation.mjs deliberately holds the detailed renderer module for six seconds, confirms the server remains in camera staging with cycles hidden, then observes 2.41 seconds remaining at the beginning of visible materialization and a successful launch without page/shader errors. Inspected test-results/mp-first-materialization.png. This reproduces the readiness race with an artificial cold load, not the user's exact Safari/GPU timing. Local change; no deployment yet.

Multiplayer connection recovery and terminal errors — October 15

  • [x] Initial multiplayer connection retries up to three times, with an eight-second timeout per attempt and 500 ms between attempts. Dispose failed sockets and heartbeat timers; explicit cancellation stops retries, and protocol mismatch requests a reload immediately. This mitigates transient handshakes; it does not identify or repair a persistent network/server failure. Three production Chromium handshakes succeeded (about 1.2–3.1 seconds). The reported Safari failure remains unreproduced: current Playwright WebKit was unavailable, and the older installed engine stalled and was stopped.
  • [x] Shared game errors now use the ENCOM terminal font, blue text, black background, normal heading scale, wrapping and logo. Hide the tank/menu chrome, focus the return control, and provide RETURN TO PROGRAMS plus RELOAD TERMINAL. Returning after multiplayer failure resets the menu; early loading failures can reload the home URL.
  • [x] All 597 unit tests pass, including retry success, finite failure, timeout cleanup, version mismatch and cancellation. node tests/browser/multiplayer-errors.mjs in headless Chrome 155 verifies three injected failures, terminal styling, keyboard focus, no overflow at 1280×800 and 640×600, and return to selection without page errors. Inspected test-results/multiplayer-error-terminal.png. Changes are local pending deployment.

Reference organization by subject — October 15

  • [x] Reorganized local docs/references material into subject folders, merging image/video locations for cycles, CLU/tanks and Recognizers. Maze trace overlays now live under mazes/; generator and documentation-copy paths follow them. Updated reference-page links and added subject aliases for the archived film collection while retaining legacy URL mappings. Original files and the existing archived collection are preserved; Finder metadata from the old folders was moved to temporary storage. Verified all 19 reference-page local links, both built trace backgrounds, the organization invariants, production build/asset audit and Worker dry-run.

Tight spiral and pocket avoidance — October 15

  • [x] Shared solo/MP AI now checks recent turn handedness. After two same-direction turns, another turn that leaves less than 2.5 cycle lengths for the following corner is marked risky; wide loops and opposite-direction exits remain allowed. This is a bounded warning heuristic, not a guarantee against every self-trap.
  • [x] Replace occupancy-only room estimates with bounded swept-edge reachability after projecting 0.6 seconds of travel and the proposed own trail. Respect fractional walls, trail lifetime and emitter clearance. Prefer safe exits over proven small pockets; exhausted search budgets do not prove confinement. Cap each search at 512 segment tests and reserve 2,048 tests for safety checks. Reuse tactical results in the emergency guard instead of choosing right on equal-clearance ties; absent cached scores, prefer the target-facing direction when adequately clear. Existing reaction delays remain intact.
  • [x] Validation on Apple M2 Max / Node 22.22: all 592 unit tests pass, including both handednesses, wide-loop exceptions, fractional/expired trails, budget exhaustion, opponent-facing escape ties and a simulated narrow-pocket approach. node tools/ai/stress.mjs: 12 bots / 2,048 segments, AI p99 0.615 ms, maximum 0.952 ms, no overflow. Headless Chrome 155 (node tests/browser/cycle-ai.mjs --trial): rendered-frame AI p99 0.60 ms, dense AI p99 0.40 ms, no page errors. Inspected the rendered capture; this does not establish subjective play quality.
  • [x] Four paired 90-second-limit matches (seeds 1982–1985), using isolated baseline/current snapshots with self-wall death instrumentation: self-wall crashes 32 → 23, direct opponent wall kills 6 → 10. Per-match current self-wall totals 5/7/5/6. Small exploratory sample, not proof of general improvement; unavoidable and other self-traps remain. User reports the AI is becoming more interesting to play against. No new training or deployment is part of this change.

Selected offense policy release — October 15

  • [x] Final bounded run: population 4, one generation, three training seeds, eight final seeds, 60-second horizon, two workers, seed offset 350000, initial cycle-ai-early-offense-round1.json. Saved test-results/cycle-ai-early-offense-round2.json plus checkpoint. The new mutation earned 2 wins / 7 direct kills / 11 trap assists in 32 final matches; previous candidate approach-340000-0-0 earned 4 / 9 / 9; deployed aggression-1-0 earned 4 / 7 / 4. Selected the previous candidate rather than the new mutation. Its combined two fresh-seed evaluations total 7 wins / 19 kills / 15 assists across 56 matches, versus deployed 6 / 15 / 8. These remain small, correlated seat samples; the second evaluation's paired fitness improved in four of eight groups, so gains are not uniform.
  • [x] Promoted selected weights into shared/simulation/cycle-ai/policies/aggression-v2.js, used by the common solo/MP default. Preserved aggression-v1.js for rollback. Updated the plateau trainer's starting import to the selected policy; training tools still never promote automatically. Selection summary is retained in tools/ai/results/early-offense-promotion.json.
  • [x] Headless Chrome 155 at 1280×800 verified the exact trial policy, tuning values, rendering and execution with no page errors. AI work per rendered frame p99 0.40 ms (max 1.00 ms); dense 12-cycle/2,048-trail p99 0.40 ms (max 0.80 ms). Inspected test-results/cycle-ai-trial.png; report test-results/cycle-ai-trial-browser.json. This is automated rendered validation, not a human judgment of enjoyment. Training stopped before browser/performance checks.
  • [x] Release validation: all 586 unit tests pass with the selected default in both solo and MP. Updated the regression test's explicit policy ID after it correctly flagged the default change. Production build/asset audit and Worker dry-run pass; 506 files, 65 immutable media names, no reference footage. Both film-sound and Disney BIT credit updates are included. User authorized production deployment after this run.

Early confirmed offense and film credits — October 15

  • [x] Offline fitness version 2 gives a confirmed enemy wall kill or successful trap assist one base point plus up to one early-elimination point, decaying linearly with death time over the match horizon. Direct owners and trappers share a single victim pool (half to each role when both exist); duplicate victims/owners cannot multiply credit. Dead wall owners remain eligible, allies and escaped cycles are excluded. Unfinished confinement no longer contributes fitness, but remains in diagnostic counts. Approach stays capped at 0.15 per team. Earlier wins keep the existing bonus. Scores from older fitness versions are not directly comparable.
  • [x] Capture confirmed death times/credit shares in the offline benchmark and tournament artifacts only. No live simulation or roster attribution code changed. Successful trap timing uses death/confirmation time, not the earliest historical confinement, because a stale trap might have reopened. Formation-time bonuses would need validated active-trap timestamps. All 586 unit tests pass, including early/late timing, shared victim pools, duplicates, dead owners, unfinished confinement and excluded victims.
  • [x] Added Frank Serafine / Serafine FX Studios to docs/credits_display.txt and docs/credits_extended.txt: Sound Effects Design and Synthesis for TRON (1982), with an explicit statement that gameplay uses sampled film effects. Verified against BFI programme credits and Serafine's interview. Added that BIT is owned by Disney and comes from TRON (1982), separately from the program's MIT software license. All six existing credits/terminal tests pass, including eight-line/60-character display bounds. Changes are local, not deployed.
  • [x] Bounded fitness-v2 run: population 4, one generation, three training seeds, six final seeds, 60-second horizon, two workers, seed offset 340000, initial policy from cycle-ai-approach-round1.json. Artifact: test-results/cycle-ai-early-offense-round1.json plus checkpoint; 48 training matches and 72 final comparisons. Candidate approach-340000-0-0 scored 10 direct kills / 6 trap assists / 3 wins in 24 fresh-seed matches versus deployed 8 / 4 / 2 and previous candidate 7 / 4 / 3. Confirmed offense points: 25.106 versus 18.950 deployed and 18.755 previous. Mean fitness: 1.19794 versus 0.89348 and 0.93079. Four of six seed groups improve paired fitness over deployed; much of the direct-kill gain comes from one group, so this is exploratory rather than proof of general improvement.
  • [x] Candidate serial timing passes: AI p99 0.184 ms, full tick p99 0.279 ms, max 8.063 ms. Training finished; no background run remains. Candidate is saved for play review; deployed/local default weights remain unchanged. No production deployment is part of these credit/training edits. Final production build and asset audit pass (506 files, 65 immutable media names); git diff --check is clean.

Continued approach evolution — October 15

  • [x] Round 2 continued from test-results/cycle-ai-approach-round1.json: population 4, two generations, two training seeds, six final seeds, 60-second matches, two workers, seed offset 320000. Trainer supports --initial, retains initial-policy results alongside the deployed baseline, and offsets the mutation RNG as well as match seeds. Saved test-results/cycle-ai-approach-round2.json and checkpoint. The requested battery pause was interrupted; the run completed before process inspection. Confirmed no training processes remained and did not automatically restart until the user said the battery was okay.
  • [x] Round 2's training winner approach-320000-0-0 regressed on unseen matches: 0.3994 fitness versus deployed 0.4482 and previous candidate 0.6874. Retained the first candidate (approach-310000-1-0) as the next starting point. In this fresh 24-match evaluation, that first candidate earned 5 wins / 9 direct kills / 9.5 shared trap assists versus deployed 2 / 7 / 7, with positive paired fitness in four of six seed groups. No policy promotion or deployment.
  • [x] Round 3 after battery recovery: node tools/ai/train.mjs --population=4 --generations=1 --trainSeeds=3 --heldOutSeeds=6 --seconds=60 --workers=2 --seedOffset=330000 --initial=test-results/cycle-ai-approach-round1.json --artifact=cycle-ai-approach-round3. 48 training matches and 72 final evaluation matches. nice -n 10 was attempted but sandbox priority adjustment was denied; Node still ran with two workers, so do not claim reduced OS priority. Run has finished.
  • [x] Fresh-seed round 3 results (24 matches per policy): candidate approach-330000-0-1 7 wins / 5 direct kills / 6 trap assists; deployed 4 / 10 / 5; first candidate 4 / 6 / 7. Mean fitness 0.62145 versus 0.61196 deployed and 0.56602 previous. Candidate fitness improved in only three of six paired seed groups versus deployed; more wins accompanied fewer direct kills. This is not sufficient evidence of improved aggressive play. Serial timing passed: AI p99 0.171 ms, full tick p99 0.267 ms; full tick max 8.932 ms slightly exceeded the 120 Hz budget. Saved test-results/cycle-ai-approach-round3.json and checkpoint; no policy change or deployment.
  • [ ] Before further weight-only evolution, consider stronger early confirmed kill/trap rewards and short interaction scenarios. Current outcome-weighted fitness can favor winning without increasing direct offense. No automatic training restart is scheduled.

Bounded approach-reward evolution — October 15

  • [x] Ran node tools/ai/train.mjs --population=4 --generations=2 --trainSeeds=2 --heldOutSeeds=4 --seconds=60 --workers=3 --seedOffset=310000 --artifact=cycle-ai-approach-round1. The trainer now starts from the deployed DEFAULT_POLICY, supports disjoint seed offsets and named artifacts, and records the initial policy/reward configuration. 64 training matches plus 32 fresh-seed evaluation matches; each seed uses all four team seats. No live-policy file was changed.
  • [x] Candidate approach-310000-1-0 versus deployed aggression-1-0 on four unseen seed groups: 2/16 versus 0/16 wins; 11 versus 16 timeouts; 5 versus 6 direct wall kills; 5 versus 2 trap assists; mean fitness 0.5708 versus 0.3891. Paired fitness improved in three of four groups. Approach credit itself was slightly lower, so the fitness improvement is not merely more proximity. Small, correlated seat samples and symmetric baseline mirrors are not proof of general superiority or enjoyment. Direct kills did not improve; do not promote based on this score alone.
  • [x] Serial candidate performance check after the tournament: AI p99 0.253 ms, full tick p99 0.367 ms, full tick max 2.583 ms; timing gate passed on this Mac. Ten targeted approach/fitness tests and git diff --check pass. Artifact: test-results/cycle-ai-approach-round1.json (plus checkpoint). Training completed; no background training remains. No candidate browser/playtest or production promotion was performed.
  • [ ] Review candidate play and direct-kill behavior before promotion. Earlier kill/trap timing rewards and authored interaction scenarios remain unimplemented.
  • [x] Investigated MP renderer fallback: CycleRendererGuard receives browser-frame dt, not network RTT. At target 60 FPS, three consecutive two-second windows below 39 FPS trigger the normal renderer after four seconds of warm-up. CPU stalls, snapshot work and local training can contribute to frame time; this does not establish the cause of the reported MP fallback. The fallback is one-way until manual Shift-R/reload. No renderer code changed; GPU/CPU profiling is still needed to attribute it.

Obstacle-aware approach reward — October 15

  • [x] Deployed reaction/overtake release 0109fd6 via website a68a1ad, Pages run 38792346237, Worker version 67ade4d5-f5ae-4311-9849-4442e306cfb8. Public headless Chrome confirmed menu entry, 120 decoded snapshots, twelve cycles, restart/camera readiness/materialization and no page errors. Production contains the reaction and charge-aware overtake changes, not the subsequent offline training work below.
  • [x] Added offline approach instrumentation in tools/ai/approach.mjs and connected it to all three evolution/training entry points. Once per simulated second, build a 2.4 m cardinal route graph with swept-disc edges against the shared trimmed/damaged/expired trail geometry and solid arena boundary. Thin walls between free nodes still block traversal. Invalid endpoints and disconnected opponents earn no approach reward. This is a conservative geometric route estimate: narrow off-grid passages can be missed, heading/turn constraints and future moving obstacles are not predicted. No straight-line fallback. Training arenas remain closed; exterior breach navigation is outside this evaluator's scope.
  • [x] Compare previous/current AI positions against the same previous target position and previous geometry; additionally require current connectivity. This excludes passive opponent approach and topology-only distance changes, and avoids treating the AI's newly emitted trail at its old position as a blocked starting point. Reward progress only in the 20–120 m route-distance band. Signed progress with a per-pair high-water mark prevents fixed-target approach/retreat farming. Pair credit is bounded and averaged over initial enemy pairings, so deaths do not inflate scores. Total team approach bonus is at most 0.15 fitness points, below one direct kill (0.5) or trap assist (0.35).
  • [x] All 583 unit tests pass, including detours, thin barriers, open/too-narrow doorways, disconnected endpoints, passive approach, disappearing walls, reward caps, fixed normalization and simulation invariance. Three 60-second smoke matches (seeds 1982–1984) exactly match the uninstrumented outcomes/decision totals; team approach fractions span 0.068–0.194 instead of all saturating. Instrumentation costs 1.73–1.84 wall-clock seconds per 52–60 simulated-second match on this Mac; these are offline costs, not live-tick work. A four-seat 30-second tournament worker smoke passes and records approach credit in fitness. Artifacts: test-results/cycle-ai-approach-smoke.json and test-results/cycle-ai-approach-tournament.json. Config/version is saved with training artifacts. Timing passes exclude reward collection; concurrent smoke measurements are not a new performance guarantee.
  • [ ] New reward is implemented and locally verified. A subsequent bounded evolution round is recorded above; no new policy has been promoted. Earlier confirmed kill/trap rewards, no-offense penalties and authored short interaction scenarios remain the next training work. Do not interpret reward implementation or unchanged-policy smoke results as evidence of improved aggression.

AI reaction fairness and overtake setup — October 15

  • [x] The evolved controller previously bypassed the classic reaction profile: its emergency guard could turn on the next 120 Hz tick. Tactical and emergency turns now schedule a seeded, per-intention delay; changing the intended turn restarts the delay. Keep the six-tick turn cooldown. Human input remains immediate.
  • [x] Delay is max(0.08 seconds, 0.65 × cycle-length travel time) + U(0,1) × cycle-length travel time, sampled at the current speed and rounded up to simulation ticks. A 10,000-sample seeded check found 32.57% of braking-speed reactions, 12.28% at cruise and 0% at full turbo fit within one cycle length. This is a reaction-to-new-intention constraint, not a ban on preplanned close-clearance turns. At changing speed, traveled distance naturally differs from the sampling speed.
  • [x] Allow turbo to set up an overtake beside a nearby parallel enemy before a direct cutoff exists. Require actual forecasted ground gain, available charge/reserve, clearance and a safe exit. Reward progress toward the lead needed for a subsequent crossing, not mere proximity. Braking remains a timing/escape candidate; empty brake reserves cannot produce a braking request. Keep the same nine candidates and existing query/work caps.
  • [x] All 577 unit tests and production build pass. Three 60-second, 12-cycle smoke matches yielded five direct wall kills versus three with the reaction change alone. AI p99 was 0.141–0.262 ms and full-tick p99 0.211–0.427 ms; one cold full-tick maximum was 10.69 ms, similar to the reaction-only baseline's 10.68 ms. This small sample does not establish improved win rate or player enjoyment. Reproducible artifacts: test-results/cycle-ai-reaction-smoke.jsonl and test-results/cycle-ai-overtake-smoke.jsonl. These reaction/overtake changes were subsequently deployed as 0109fd6; no new evolution run was part of that release.
  • [x] Headless Chrome 155 on macOS passed the solo AI browser check with no page errors: live-frame AI p99 0.70 ms, dense 12-cycle/2,048-trail fixture p99 0.50 ms. Inspected test-results/cycle-ai-arena.png; report is test-results/cycle-ai-browser.json. This checks rendering and execution, not subjective driving quality.
  • [ ] Next training proposal: mix 30–60-second interaction scenarios with full arena matches; add earlier confirmed kill/trap rewards, a modest no-offense outcome penalty, and bounded progress toward attack positions rather than per-frame proximity rewards. Count a victim once across direct/assist credit, retain performance gates, and evaluate unseen seeds plus human play. Existing training already limits matches to 180 seconds and rewards faster wins, but not earlier individual kills. Do not promote a policy solely for surviving longer or increasing proximity.

Production release — October 15

  • [x] Deployed TRON ed06122 via website 7176923, Pages run 38789514609, and Worker version 06141c2d-3243-4d4d-8c4b-6799d21eece6. All 574 release tests, production build and Worker dry-run passed. Public Chrome verified protocol 3, 106 decoded snapshots, camera readiness, materialization and solo restart into racing with no page errors. This includes spectator framing, five-second result hold, team formation, human wire slashes, solo materialization audio and the revised error panel. The subsequent AI changes above are not part of this release.

Multiplayer materialization sound — October 15

  • [x] MP now plays the solo cycle-entry-startup.wav cue 0.3 seconds into materialization, at the same gain and matching playback offset. Do not replay the transport dialogue; stop the cue at the same formation/launch boundary as solo. Suppress the older generic cue that fired prematurely when the roster changed.
  • [x] Wait for cycle samples to finish loading before acknowledging camera readiness. Regression coverage checks no cue during staging, correct sample/gain/offset, no duplicate sources on repeated snapshots, and pause/resume/launch cleanup. All 31 focused audio/camera tests and the production build pass. Headless Chrome confirmed the 3.058-second solo startup buffer played once during MP materialization, with a 0.006-second catch-up offset and no staging playback. The initial browser probe copied full game state from audio initialization and timed out; lightweight audio instrumentation passed. Local changes only.

Materialization timing and human paint — October 15

  • [x] Latest direction: five-second winner/last-cycle hold; once all cameras arrive, materialization begins immediately without a countdown. Solo and MP now share one formation/launch-hold timing object so their timing cannot drift.
  • [x] Apply each human cycle's black/white slash to construction lines as well as the solid body, in both the mesh and analytic renderers. Preserve the slash through the analytic solid glow. Unmarked AI cycles retain their body-colored construction lines; the existing palette still sets each wireframe's body hue and brightness controls remain active.
  • [x] All 573 unit tests and production build pass. Headless Chrome confirms the readiness barrier, immediate materialization without countdown, camera hold and launch in the normal renderer without shader errors. Analytic renderer captures verify human/AI image differences during wire and solid stages, plus all four team hues. Inspected the blue-team mesh reveal with two human markings. Restarted port 5173 with the current authority; changes remain local.

Connection error panel and local server recovery — October 15

  • [x] Give the error panel balanced inset padding, a smaller responsive heading, readable message wrapping and a compact reload button. Add an accessible alert label. Inspected headless Chrome captures at 1440×900 and 390×844; no horizontal overflow. Production build passes.
  • [x] Confirmed the existing port 5173 server accepted protocol 2 and rejected the new protocol 3 client. Restarted it with current code and verified protocol 3 connects. The usual local URL works again; production is unchanged.

Multiplayer team materialization transition — October 15

  • [x] Hold the winner/last-cycle result shot for five seconds before selecting the next roster. Move each seated player's camera smoothly over three seconds to the solo materialization perspective, rotated for their assigned team's wall. Use the solo close formation spacing for every MP team; queued spectators prepare a gold-team view.
  • [x] Keep cycles hidden and simulation stopped while cameras travel. Each client acknowledges its rendered arrival with its round and seat; the authority waits for every connected client before immediately starting the shared 1.833-second materialization and 0.6-second hold (no countdown timer or countdown beeps), then clients cut to normal cycle follow. Preserve the end-state camera position as the next flight's departure point. Reduced motion jumps to the destination but still acknowledges readiness.
  • [x] Clear readiness on roster changes, reject stale acknowledgments, release disconnected clients from the barrier, and disconnect clients that cannot prepare within 45 seconds. Late arrivals during materialization queue for the next round. Return for a sole human now runs this camera sequence instead of skipping directly into racing.
  • [x] Remove the player's team label from MP countdown text. Retain team names in winner announcements.
  • [x] Protocol 3 requires the matching client and server; production remains on protocol 2 until a coordinated deployment. Older connections are rejected rather than silently bypassing camera readiness.
  • [x] The initial transition passed 572 unit tests, production build and Worker deployment dry-run. The multiplayer browser lifecycle also passes with two rendered clients, 14 connections and an overflow queue. Headless Chrome on macOS verifies a delayed second client holds materialization, cycles remain hidden until ready, the camera holds throughout the reveal, and launch cuts to the player's cycle. Inspected close gold-team materialization and launch captures in test-results/mp-team-materialization.png and test-results/mp-team-launch.png. Changes are local, not deployed.

Spectator opponent framing — October 15

  • [x] When following a cycle before a match or after death, orbit the existing camera boom to frame the nearest living opposing cycle as well. Keep the current zoom, height and speed-dependent follow distance; ease the orbit with a bounded angular speed and aim between the two viewing directions. Exclude allies, dead cycles and escaped cycles; resume ordinary follow when no opponent remains.
  • [x] Preserve opening shots, target-switch transitions, death holds and camera collision clearance. Walls can still shorten the boom, and abrupt opponent changes can temporarily leave the frame while the orbit catches up.
  • [x] Production build passes. Headless Chrome on macOS rendered the full arena with a gold followed cycle and nearby blue opponent both visible; inspected test-results/spectator-opponent-framing.png, with no page errors. Dynamic feel still needs user playtesting.
  • [x] All 568 unit tests pass, including pair visibility in landscape/portrait views and countdown/racing states, unchanged follow distance, nearest-opponent filtering, bounded rotation and unchanged driving framing.

First-match jitter and startup update recovery — October 15

  • [x] Reproduce clock lag after a two-second first-load rendering pause while snapshots continue. Local prediction and remote playback now re-anchor after a gap longer than their 0.2-second frame bound, instead of discarding elapsed time and advancing at snapshot boundaries while catching up. Normal frames retain continuous rate correction.
  • [x] Reproduce a separate local freeze/jump when high RTT drives prediction into its 200 ms extrapolation cap. Reserve two snapshot intervals below that cap (100 ms maximum RTT-derived presentation lead at current settings). Keep wire timestamps based on estimated authority time, independent of capped visual lead; immediate turns remain local and fractional. Extend input coverage to 500 ms RTT.
  • [x] Remove automatic home-screen service-worker activation/reload. Background updates wait until existing tabs close; explicit update.html recovery remains available. Chrome verifies a waiting update does not reload the menu and old-cache/missing-module recovery still works.
  • [x] 565 unit tests, production build, and isolated headless Chrome multiplayer lifecycle checks pass with 250 ms transit each way plus injected jitter. The first browser attempt shared the ordinary development server and timed out on sole-player restart; the isolated arena passed.
  • [x] Deployed TRON afa6c09 through website 0e78e3a; Pages run 38761215638 succeeded. Production Chrome confirmed the prediction-headroom code in the served client, 52 decoded snapshots, immediate solo restart and no page errors. A 30-second public packet recording had 48.1 ms median, 64.1 ms p95 and 118.2 ms maximum packet gaps, no backward remote poses, and 32 held cycle-frames in 25,923 samples. A separately observed 1.7 m local jump was a race-start transition, not evidence of continuous driving jitter. Synthetic first-load/high-latency regressions reproduce concrete failure modes; user-device confirmation remains necessary.

Cycle formation body colors — October 15

  • [x] Use the cycle body color for materialization wireframes: copy the actual body material in the mesh renderer and use the existing body-color uniform for contours, grid and halo in the analytic renderer. Preserve line intensity, coverage, halo attenuation, fade stages and solid-body glow timing.
  • [x] Production build and Chrome materialization shader/lifecycle check pass; capture all four team colors and inspect blue/red wire stages. Publish with the verified multiplayer prediction-clock correction below. These are client-only changes; the existing multiplayer Worker remains compatible.

Multiplayer follow-camera packet jitter — October 15

  • [x] Reproduce backward local follow-target motion under 20–50 ms variable snapshot delivery. Remote cycles already use monotonic buffered playback, but the local prediction/camera clock reset from each packet arrival and RTT sample. Keep a continuous prediction clock, correcting its rate by at most ±10% over a 0.25-second correction interval; reset on round changes. Preserve immediate fractional input prediction, authoritative collision state and the existing 75 ms remote buffer.
  • [x] At 144 Hz rendering, the regression reproduces up to 0.885 m backward travel with the old clock; the new clock has no backward steps and at most 0.0267 m deviation from the nominal per-frame distance. Also exercise an RTT change, new-round reset, immediate input, joined trails and no early future turn. Correct an older test's artificial backward wall-clock jump so its future input occurs after preceding frames.
  • [x] 564 unit tests and production build pass. Headless Chrome on macOS passes the two-rendered-client multiplayer lifecycle test with injected packet delays (TRON_MP_JITTER=1 node tests/multiplayer-browser.mjs). Runtime/browser tests do not establish subjective production smoothness. Deployed in TRON e5f9d72 through website 59f21d0 (Pages run 38758748338). Production Chrome received 68 snapshots with no page errors and verified immediate solo restart. Long stalls, speed changes and authoritative input reconciliation can still require position corrections.

Evolved AI and trap attribution release — October 15

  • [x] Release checks: 563 unit tests, production build/asset audit, Worker dry run, and headless Chrome roster, MCP game-launch and two-client multiplayer checks pass on macOS. Publish the playtested aggression-1-0 policy for solo/MP, persistent trap-assist attribution and hollow roster dots, and MCP closing-sentence fade. Later training found no qualifying improvement; retain the playtested weights.
  • [x] Deploy compatible multiplayer Worker 3f4f21f1-73fa-43c5-ba0d-c383a16eecdb. Optional trap-assist snapshot data preserves the existing protocol. Training and research artifacts remain offline; no automatic training runs in production.
  • [x] Publish TRON 9863ee0 through website e090204; Pages run 38754625290 succeeded. Production Chrome entered multiplayer, decoded 55 snapshots with no page errors, and verified solo Return restarts immediately without countdown. Historical local-only notes below describe their state when written. This completion record was added after deployment.

JavaScript cycle AI plan — October 14

  • [x] Write the fast, compelling cycle AI plan, prioritizing bounded runtime cost above tactical sophistication. Cover cutoffs/containment, joint turn and reserve planning, competent seeded variation, offline win-rate evolution and an optional tiny neural scorer.
  • [x] Implement the first bounded shared JavaScript controller, joint turn/turbo/brake scoring, cutoff/containment incentives, continuous safety queries, deterministic near-best variation and development tuning. Retain classic/open-road control and isolate human seats. Cycle JEV requests are skipped for the new mode.
  • [x] Add seeded baseline/stress/comparison tools, versioned offline policy evolution and an optional tiny neural scorer. No evolved/neural policy is promoted. Reference M2 Max measurements: dense twelve-bot AI p99 about 0.49 ms in Node and 0.4 ms in Chrome; new team wins 9/12 spawn-rotated mixed matches, a small correlated sample. Detailed commands, runtime limits and evidence are on the plan page.
  • [ ] Complete slower-device/server measurements, advanced coordinated maneuvers, statistically supported policy promotion and real-player review. This change is local; no deployment requested.

Cycle roster wall eliminations — October 14

  • [x] Track each opposing cycle eliminated by a cycle's trail and show a 3 px dot in the victim's team color beneath the wall owner's roster circle. Center each row, wrap at five dots and preserve roster placement. Retain awards after owner death; exclude self/friendly crashes and duplicate victim credit; clear on new rounds.
  • [x] Include the optional award list in full and compact multiplayer snapshots. Remove the redundant USERS and WAITING totals from the active multiplayer status line; retain latency and the spectator's own queue position.
  • [x] Headless Chrome roster checks pass for colors, centered wrapped rows, unchanged active-roster position and round reset; rendered capture inspected. Twenty-one focused collision/reward/multiplayer tests pass, including full/delta snapshot awards and reset. Implementation is local pending a requested deployment.

Multiplayer waiting roster — October 14

  • [x] Show one plain hollow gray circle per waiting player without a seat (eliminated seated players remain only in the colored roster), linked by gray lines and followed by a chevron toward the active teams. Position the queue independently to preserve the centered active roster; hide it when the queue is empty.
  • [x] node tests/cycle-roster.mjs passes in headless Chrome on macOS: three/one/zero waiting players, unchanged active-circle coordinates, hollow gray styling without stripes, connectors, restart and hiding. Inspected the rendered roster capture. Long queues may extend beyond the left edge on narrow screens.

Content-addressed media and incremental offline updates — October 14

  • [x] Extend existing Vite-hashed models/music to 65 public media files: audio, fonts, images/icons and BIT models use {name}-{sha256-prefix}.{extension} in production. Keep logical development paths and old production aliases. Build asset-manifest.json, resolve dynamic audio/model requests through the manifest, and rewrite copied BIT documents/scripts without modifying Vite's already-hashed chunks.
  • [x] Precache only hashed media URLs. Record per-file SHA-256 metadata and copy matching cached responses into a new release cache; download only missing or changed files. Migrate older caches without metadata by verifying their stored bytes once. Preserve the working cache if installation fails, and remove old caches only on activation.
  • [x] Remove version-query audio requests from current callers. Resolve older ?v= audio aliases to the hashed cached response, including byte-range requests, without intercepting API URLs. Fix BIT's font-preload path.
  • [x] Validation on macOS/headless Chrome: 536 unit checks pass; five cache regressions cover unchanged/changed files, legacy migration, versioned ranges and failed updates. node tests/browser/pwa-incremental.mjs uses the actual production cache and changes one script: only bit/config.js downloads, while all media is reused and the active cache survives until activation. node tests/pwa.mjs and node tests/pwa-update.mjs pass offline play, hashed install icons/fonts, ranged audio, non-interrupting updates, older-cache recovery and missing-module recovery. Async browser assertions now poll for completed worker installation rather than accepting a pending promise.
  • [x] Production build audits verify every emitted public-media filename against its actual content and original source. Offline cache remains approximately 89.7 MiB; compatibility copies remain deployed but are excluded from precaching.
  • [ ] Faster game initialization remains separate: the cached-load profile measured about 5.8 seconds dominated by simulation setup, scene construction, model preparation and shader compilation. This change reduces network traffic across releases, not that CPU/GPU work.

Module-load recovery — October 14

  • [x] Route the error screen's Reload action through the uncached update.html recovery page so an old entry document is not simply reloaded from its existing service-worker cache. Identify module-loading failures with an uppercase update instruction.
  • [x] Let the recovery page return home after first-time service-worker activation as well as replacement of an existing worker. Preserve the normal game's policy of waiting until the home screen to activate background updates.
  • [x] npm run build and node tests/pwa-update.mjs pass on macOS/headless Chrome. Browser regressions cover an old cached entry updating into a playable game, a deliberately missing multiplayer module, failed first cache installation, the actual Reload click visiting the update page, and return to a usable program menu. Fresh production multiplayer also passed with advancing snapshots and no page errors; the user confirmed the original tab works again. The precise failing request in the user's Safari tab was not captured.

Repository organization and video removal — October 14

  • [x] Implement organization stages 1–6: focused shared simulation modules, discovered unit tests, grouped browser/tool scripts with CLI compatibility, canonical runtime/source/reference directories, asset catalog and explicit production packaging.
  • [x] Remove reference videos entirely and ignore video extensions. Rewrite video paths out of Git history; retain runtime audio and still images. Extraction inputs must be supplied separately.
  • [x] Verify 531 unit checks, Worker dry run, PWA offline/update behavior, multiplayer browser lifecycle with jitter, and production subdirectory paths on macOS/headless Chromium.
  • [x] Deploy TRON de3453e through dekorte.com b3e161d, Pages run 38617728189. Worker version 0352103a-89e1-4d2b-880c-3bb9be2c2c41. Production Chromium check: menu entry, 48 decoded snapshots, 12 cycles, solo Return skips countdown, no page errors; canonical/legacy cannon audio bytes match. Protocols 1 and 2 each delivered validated snapshots. Initial clean CI build exposed a missing audit-output directory; fixed and verified without a preexisting directory.
  • [ ] Retire compatibility paths only after deployed-client cache review. Real-player feel remains unverified.

Immediate multiplayer turns near fixed walls — October 14

  • [x] Remove the eight-tick input lead from outgoing commands and local motion prediction. The authority validates timestamp freshness but applies accepted commands on its next 120 Hz tick, including valid future-dated commands from cached clients. Preserve sequence checks, turn-rate limits and authoritative collisions; do not backdate impacts.
  • [x] Retain a local fractional keypress tick for pending-input replay. Apply the turn at the currently displayed position in the same frame, finalize the preceding trail at that corner and continue the new segment. Only integer timestamps are sent on the wire. Remote playback remains buffered at 75 ms.
  • [x] npm test: 528 checks pass. Fixed-wall regressions approach an existing arena boundary with 1.8 m of collision-shape clearance at 38.4 and 96 m/s. Immediate scheduling survives at zero and two ticks (16.7 ms) of simulated input transit; the former eight-tick schedule crashes. At six ticks (50 ms) transit, both approaches are already too late. With two ticks of transit, accepted corner displacement is 0.64 m normally and 1.6 m at turbo. These are deterministic simulation checks, not measured real-network latency.
  • [x] Local prediction tests cover zero/80 ms RTT estimates, fractional keypress times, same-frame direction changes without position jumps, joined trail corners and no repeated turns across frames. npm run build, npm run worker:check and git diff --check pass. Restarted local Vite on port 5173 so its authority loads the new handler. TRON_MP_JITTER=1 node tests/multiplayer-browser.mjs passes in headless Chrome on macOS with two rendered clients, twelve cycles and fourteen connections.
  • [ ] Real-player fixed-wall feel and realistic network-transit review; bounded rollback remains unimplemented. Included in the October 14 reorganized production release above.

Remote cycle playback under packet jitter — October 14

  • [x] Replace remote forward prediction with a bounded snapshot history and continuous monotonic playback clock. Packet arrival adjusts playback speed by at most 10%, rather than resetting the time origin. Use a named 75 ms presentation buffer; the tested 50 ms buffer occasionally ran dry under 15–50 ms delivery jitter. Local input prediction, server timing and collision authority are unchanged.
  • [x] Interpolate remote positions along confirmed trail corners, trim their displayed trails to the same pose and remap active segment indices. Keep current authoritative HUD/reward data and deaths; never resurrect a dead cycle to play an old pose. Hold at the latest confirmed point during network stalls; clear history on new rounds and disconnect disposal.
  • [x] node --test tests/multiplayer-playback.test.js tests/multiplayer.test.js tests/multiplayer-audio.test.js: 21 checks pass. At 144 rendered frames/sec with alternating 15–50 ms snapshot delivery delays, the straight-line normal-speed test reduces worst frame-step error from 1.344 m to 0.0267 m, with no backward/held frames after warm-up. Also check multiple corners, trail attachment, local isolation, immutable snapshots, history bounds, stalls and round reset.
  • [x] TRON_MP_JITTER=1 node tests/multiplayer-browser.mjs passes in headless Chrome on macOS with two rendered clients, twelve cycles, fourteen connections and jittered WebSocket delivery. Inspect the normal-renderer capture. npx vite build and git diff --check pass; existing build warnings remain.
  • [ ] Real-player motion and close-cutoff review. The buffer adds approximately 75 ms behind received state (plus network transit); it improves presentation at a latency cost. Longer stalls can still hold remote motion. Deployed TRON b9b1948 through dekorte.com c5a52e0, Pages run 38608501930. Full release checks: npm test passes 525 tests and npm run build passes. Production Chrome verified the published 75 ms playback code, 53 decoded snapshots, a six-cycle arena and immediate solo Return restart, with no page errors. The existing server was unchanged.

Multiplayer production release — October 14

  • [x] Validate compact snapshots, fractional-tick presentation and retained eliminated-human roster stripes: npm test passes 522 tests; npm run build and npm run worker:check pass. Headless Chrome on macOS passed the two-rendered-client multiplayer check in the preceding change.
  • [x] Deploy the compatible Worker first: version b669337a-c12e-4c6d-8bdc-81fc946f58ec. Protocol 1 remains available for cached clients.
  • [x] Publish TRON e4612e7 through dekorte.com 8991c03; GitHub Pages run 38602487215 succeeded. Production protocol 1 and 2 probes passed. Headless Chrome on macOS decoded 50 compact snapshots in a twelve-cycle arena, entered from the menu and verified solo Return skips countdown, with no page errors. The first game-entry check timed out at 60 seconds; a diagnostic retry with a 90-second limit passed. Sustained real-player smoothness remains unmeasured.

Multiplayer motion between simulation ticks — October 14

  • [x] Remove whole-tick quantization from multiplayer presentation prediction. Keep integer ticks for input scheduling and pending turns, and advance the fractional remainder for bikes, attached trail endpoints and the following camera. Preserve server simulation and collision timing.
  • [x] node --test tests/multiplayer.test.js tests/multiplayer-audio.test.js: 18 tests pass, including 2 ms presentation steps, no early future turn, unchanged authoritative state, trail endpoint alignment and stale-state bounds. npx vite build passes with existing script/font/chunk warnings. node tests/multiplayer-browser.mjs passes in headless Chrome on macOS: two rendered clients, twelve cycles, fourteen connections, queue and restart lifecycle checks, no browser errors.
  • [ ] Measure live frame pacing and snapshot correction jumps. Snapshot arrival still resets the prediction baseline; this change addresses quantized motion, not all potential multiplayer stutter. Subjective smoothness requires playtesting. Included in the October 14 production release below.

Multiplayer low-latency hosting plan — October 14

  • [x] Record the selected multiplayer migration plan: compact-protocol production baseline, existing WebSocket authority on a measured Google Cloud VM, then loss-tolerant WebTransport with WebSocket fallback and a same-server comparison.
  • [x] Preserve 120 Hz simulation; specify reliable trail/input recovery, explicit sequence acknowledgments, baseline repair, shared motion prediction and bounded tick validation. Mark the earlier browser-host proposal as historical.
  • [ ] Measure production latency/jitter and costs, validate packet loss/reordering and browser fallback, then stage an explicitly authorized rollout. Protocol 2 is included in the October 14 release; no VM or WebTransport service has been provisioned. Documentation changes do not constitute deployment approval.

Multiplayer focus, team sizes and HUD — October 13

  • [x] Disable automatic blur/visibility pause and any-key resume in multiplayer. Clear held inputs and send neutral controls while unfocused; preserve Escape confirmation and single-player pause behavior.
  • [x] Cap teams at three cycles. Use two to four teams, expanding during countdown when more humans join without delaying launch; up to twelve humans can play.
  • [x] Preserve race and cycle object identities between multiplayer snapshots so engine loops and launch cues do not restart every frame. An audio regression verifies continuous engine ownership and a real reset on the next round.
  • [x] Put C / CONTROLS below multiplayer status rather than on the same line.
  • [x] All 511 unit tests plus the multiplayer audio regression, production build and Worker dry run pass. Headless Chrome verifies no blur pause, three-cycle teams and non-overlapping controls/status, plus both renderers.

Multiplayer local prototype and human stripes — October 13

  • [x] Add LIGHT CYCLES MULTIPLAYER with one authoritative twelve-cycle room, AI vacancy filling, randomized teams, FIFO spectators and individual survivor seat retention.
  • [x] Share fixed-step simulation with the server; sequence and bound inputs, stream trail deltas, predict client motion, and leave collision outcomes with the server. Stop empty rooms and keep multiplayer code out of the single-player loading path.
  • [x] Mark human cycles with a thick diagonal half-black, half-white stripe in both renderers and the roster; remove provisional dots and floating markers. Preserve transparent eliminated roster interiors.
  • [x] Remove grid clouds from gameplay loading and extended model credits; retain archived asset provenance.
  • [x] Validation: 510 unit tests pass, build and Worker dry run pass. Headless Chrome on macOS verifies two rendered clients with fourteen total connections, queue overflow, shared state, no local match reset and no cloud asset request. Both ray-cast and fallback stripe shaders compile without browser errors; inspected both racing captures.
  • [x] Authoritative Worker deployed and production-origin WebSocket snapshots verified; static client release follows.
  • [ ] Real-world latency/cutoff playtests. No rollback, reconnect identity or measured hosting budget yet. See multiplayer.

Wheel reflections after player death — October 13

  • [x] Preserve each cycle’s reflection clock across AI random-state changes; reset only on a new round or simulation time rewind. Surviving cycles continue their speed-dependent flicker after the player dies.
  • [x] Verified with node tests/home-menu-order.mjs in headless Chrome on macOS: ray-cast renderer stays active, all surviving reflection phases advance after player death, and the dead cycle has zero reflection strength. Initial sandboxed Chrome launch aborted; rerun outside the sandbox passed.

MCP game-grid transfer and search — October 13

  • [x] Add bounded native Gemini function calls: send_to_light_cycles is the only game destination, allowed before spoken text; Brave web_search runs only on the relay with its private credential, at most once per turn. Preserve Gemini thought signatures through tool results. Require a newline after every spoken sentence.
  • [x] Reveal the animated face full-screen at announcement audio start, wait for speech completion and one additional second, then dissolve directly into the prepared cycle scene. Fade the MCP music over the same 1.1 seconds and stop/reset it; lower its normal level by 30% (0.60 to 0.42). Escape invalidates pending transfers.
  • [x] Show CONNECTING TO CORE... immediately while MCP audio/resources prepare. Cache its music Blob in a dedicated tron-mcp-music IndexedDB store, keyed by the asset URL; release Blob URLs when leaving.
  • [x] P toggles a smooth first-person cycle camera; hide the player’s cycle in the cockpit and restore it on exit. First-person mode is limited to a living player, with the normal spectator camera after death.
  • [x] Add immediate two-note confirmation feedback to Return Home, allowing 200 ms before navigation so the beep is not cut off. Honor main-game mute.
  • [x] Restrict the gray window return to the projecting rear cut face, excluding the roof lip. Give that downward-facing panel a small reflected-light floor while retaining the underbody pigment and the rest of the cycle’s deep shadows.
  • [x] Validation: 504 unit tests pass; headless Chrome on macOS passes tests/mcp-game-launch.mjs (audio timing, face, one-second hold, direct scene transition and music-fade trigger) and tests/exit-confirm.mjs (CLU/cycles/BIT confirmation and cancellation). Inspected the normally lit rear-window render in test-results/cycle-window-rear-solid.png. tests/cycle-first-person.mjs passes cockpit toggling, height and hidden-player checks; tests/mcp.mjs passes microphone permission, speech timing and music continuity checks. A live relay search returned an answer. These automated checks do not establish subjective sound quality.

Cycle attack tactics and cockpit fade — October 13

  • [x] JEV favors closing on observed enemies, intercepting ahead, cutting escape lanes and coordinated boxing-in, with self-preservation and friendly escape routes retained. Clearance score is not attack value. Local collision avoidance and observation limits remain authoritative.
  • [x] Separate materialization color coverage from cockpit opacity so entering first person fades the cycle transparently without changing its colors.
  • [x] Validation: 23 JEV/protocol/Worker unit tests passed; production build passed; headless Chrome on macOS passed the first-person entry/exit and hidden-player check. Tactical effectiveness still needs live play assessment.

Multiplayer proposal: Multiplayer light cycles compares timing, authority, hosting cost and staged acceptance checks. The public server-authoritative arena is deployed; compact protocol 2 remains local, and real-network latency testing and the staged hosting migration remain pending.

MCP transfer reliability and panel activity — October 13

  • [x] Require the real light-cycle transfer tool when the user asks to enter the grid or MCP sentences them to it; forbid dialogue-only promises of a transfer. Require the announcement to end with “END OF LINE.”
  • [x] Animate the six existing ENCOM badge lamps while listening, awaiting Gemini or generating speech. Stop the animation for playback, cancellation and errors; reduced motion uses a steady brightness change.
  • [x] Remove completed cycle-smoothing, soundtrack-cue and mobile-warning items from TODO.md; retain partially completed projects and clarify the remaining spoken dialogue clip.
  • [x] Validation: real Gemini initially returned only a promise, then returned the actual cycles action and END OF LINE with the revised prompt. MCP unit checks and production build pass. Headless Chrome passes STT/LLM/TTS lamp states, face/audio timing, one-second hold and direct game transfer. Inspected the enlarged badge capture.

Project cleanup proposal: Project organization plan. Inventory and migration stages only; no folder moves have been performed.

Project documents

Light cycle arena asset preparation — September 23

  • [x] Isolate Daniel Preti’s arena architecture from the supplied OBJ; preserve source scale and retain original files.
  • [x] Add a runtime film-reference edge treatment: near-black walls with blue-gray outlines and deep purple symbols with violet borders. Inspect the Chrome preview; retain original model materials in the GLB.
  • [x] Remove the dense modeled floor and render a separate white-on-black procedural grid with the existing game grid spacing, antialiasing and fade. Use this in both the arena preview and the game.
  • [x] Reload the 447 KB, 8,349-triangle standalone GLB in Chrome and inspect rendered overview/interior captures. Geometry excludes the original floor tiles, bikes, trails and exterior scenery.

Hit-centered Recognizer explosions — September 24

  • [x] Use the projectile impact as the world-space blast center. Each detached section receives an outward impulse from that point in all three dimensions, without a shared directional bias or added upward kick.
  • [x] Preserve vehicle momentum, existing impulse magnitude tuning, Earth gravity, section timing and debris cleanup. Explosions without a recorded hit use the vehicle origin.

Film-style cycle explosions — September 24

  • [x] Replace the expanding crash ball with a white-blue needle burst, two staggered red semicircular arcs, tumbling bright chips and wheel rings, and fragment ground silhouettes.
  • [x] Use the supplied references/images/cycle explosion frames as the visual reference. Assuming consecutive captures at 24 fps, the main rays occupy nine frames (0.375 s); fragments fade out by one second. Effect animation uses 24 fps samples without changing gameplay simulation cadence.
  • [x] Pool six bursts, derive motion from crash age and stable IDs, orient arcs using the crashed cycle's heading, and retain the existing independent three-second trail hold/flash/lowering sequence.

Cycle trail and lighting follow-up — September 24

  • [x] Give opaque trails 18 cm thickness, a grounded curved recess around the rear wheel (with tire clearance, not an axle-height taper), brighter blue, periodic vertical bands and highlighted edges.
  • [x] Keep a destroyed cycle's barrier for three seconds, flash and settle over 0.24 seconds, then lower it to zero over 0.7 seconds. Release only that cycle's collision cells when the trail disappears.
  • [x] Keep sharp right-angle turns independent of the decorative floor grid. Remove the floating arena scoreboard; matches continue internally.
  • [x] Repair duplicate/quantized model surfaces, preserve authored smooth normals, and replace cracked hub caps with smooth geometry at measured source dimensions.
  • [x] Add a compact shadow tile per cycle for self-shadowing and reduce ambient wash on cycle materials. Dispose the atlas with the arena scene.

Arena visual refinements and uninterrupted inspection — September 24

  • [x] Make trail walls fully opaque with saturated amber/deep-blue bodies, a soft vertical gradient and a pale flare behind each bike. Match their height to the bike body (1.5 m). Interpolate and trim trail ends to the rear of each bike; brightness follows distance along the trail through corners.
  • [x] Darken the blue bike's painted body and trim while retaining white/silver components and original source materials in the GLB.
  • [x] Double arena grid-line width, reduce cell spacing by 10% to 4.32 m, and add a subtle navy floor tint. Cycle movement uses independent 4.8 m decision lanes so turns need not coincide with the 4.32 m floor grid.
  • [x] While free-camera inspection is active, protect Clu from bullets, stomps and debris damage and suppress end-screen transitions. Leaving inspection restores damage; restart clears inspection. This keeps running spectator matches from being interrupted by Clu's off-camera death.

Light-cycle competition and arena patrol — September 24

  • [x] Extract gold, blue and red bikes into standalone GLBs; use gold and blue for two teams of three inside the arena. Separate authored dimensions, simulation and rendering. Use 3.6 m bikes at 38.4 m/s on independent movement lanes.
  • [x] Use deterministic local steering with bounded free-space search, forward clearance, friendly-lane avoidance and opponent interception. All bikes share the arena map and visible trail occupancy; this race does not call JEV.
  • [x] Resolve each grid crossing simultaneously. Arena bounds, own trails, friendly trails and opposing trails eliminate bikes; head-on same-cell collisions eliminate both. Trails persist until the round resets. Last surviving team wins; after two minutes compare survivors, otherwise draw. Keep team scores, a three-second starting countdown and six-second result interval.
  • [x] Render imported bikes, team-colored trail walls and crash flashes. Cap trail geometry by maximum round travel. The race uses the fixed simulation timestep and resets with the game.
  • [x] Add one Recognizer circling above the arena wall with original flight dynamics. Sightings, radio contact and audible threats interrupt patrol; stale target knowledge returns it to the perimeter. The routing works in classic/local/JEV modes without querying JEV for routine patrol.
  • [x] In free-camera mode, Space runs/pauses the world while retaining camera control; camera keys do not drive or fire Clu. C/Home/Space provides a quick way to watch the arena.
  • [x] Enemy tanks clone Clu's colors and materials without the former enemy recoloring; materials remain independently owned.
  • Race obstacles and participants are confined to their own simulation: cycles do not fight Clu or become Recognizer targets yet. Source texture limitation is recorded in Models. Browser captures establish initial rendering; human play and Safari review remain pending.

Loading terminal — September 24

  • [x] Show a static LOADING... terminal before application initialization; keep the access terminal and start controls hidden until assets, physics, scene setup, and the first rendered frame are ready. Initial HTML supplies the loading text, with the shared terminal typography and ENCOM logo. Three fixed-position dots appear successively on a 1.8-second CSS opacity cycle; reduced-motion preferences show static dots. This is an activity indicator, not measured progress.

Arena placement and inspection camera — September 23

  • [x] Make the light-cycle floor grid five times denser (4.8 m cells), scale its line width down proportionally, and dim the lines. Preserve subpixel line coverage so distant grid lines do not expand into a glowing field.
  • [x] Place the arena east of the central labyrinth, grid-aligned with a narrow gap; avoid overlap with maze bounds for alternate layout seeds. Retain the imported scale, colored wall outlines, and white-on-black floor.
  • [x] Cut the arena footprint out of the main ground shader to remove overlapping floor surfaces. Add a continuous exterior enclosure behind the imported decorated inner walls, using the same near-black surface color and blue-gray edge outlines.
  • [x] C toggles a free inspection camera during play or pause. Freeze simulation and JEV planning while inspecting; restore the previous running/paused state on exit. WASD moves, Q/E descends/ascends, drag or arrow keys looks, Shift moves faster, Home frames the arena, C/Escape returns to Clu.
  • [x] Chrome browser regression verifies startup, arena loading, camera movement with frozen simulation, and restoring both running and paused states. Inspect the rendered arena/labyrinth overview. Production build passes.
  • Arena architecture is scenery to Clu and the main-world enemies; their wall collision and arena entrances are not yet implemented. The separate light-cycle race enforces its own arena bounds and solid trails. Safari visual review remains pending.

Current direction — open-ended simulation

Central labyrinth placement and population — September 23

  • [x] Fix its beam to the measured center of the blueprint’s circular courtyard (pixel 724, 514), instead of choosing a random central navigation cell.
  • [x] Scatter eight tanks and six Recognizers among interior annular sectors. Tank spawns must have a swept-clear route to the courtyard; other mazes retain their existing population.
  • [x] Separate clipped wall-shadow decals from their receivers by 0.02 m before float32 upload, retaining depth testing and stencil union. This prevents coplanar rounding artifacts without softening the shadow edges.

Central labyrinth — September 23

  • [x] Trace the supplied Big labyrinth image into 116 wall islands, preserving the circular courtyard and three enclosed openings. Share polygon extrusion/collision code with the original blueprint maze, including hole-aware roof triangulation.
  • [x] Add the labyrinth as a fifth, grid-aligned site at the center of the four existing mazes. Use 2.4 meters per image pixel and the existing 54-meter wall height. The default layout fits without moving the outer sites; placement can move overlapping sites outward if needed.
  • [x] Include a fifth beam, four transport pads and normal maze patrols. Keep authored/reference fixtures unchanged. Verify collision/roof agreement, separation across four layout seeds, courtyard route accessibility, game startup and rendered geometry.

Smarter stomps with original motion — September 23

  • [x] Preserve the earlier film-like movement: thrust 24.2 m/s², yaw cap 0.62 rad/s, yaw acceleration 0.8 rad/s², ordinary drag/braking, 1.3-second fold, and 85 m/s² powered stomp descent. Remove all close-attack performance overrides. Cruise/max speeds are unchanged.
  • [x] Improve decisions rather than physics: approach overhead before descending, retain a progressing attack lead, align for nearby walls, and allow a healthy pursuing lead to take a safe attack opportunity.
  • [x] Brake as soon as the predicted stopping path provides a valid stomp, rather than insisting on an exact waypoint or redundant final heading. Keep fresh personal sight, cooldown, drift prediction and swept wall clearance checks.
  • [x] Stomp drop/landing contact with debris cannot damage the attacker; normal flight and weapon hits remain vulnerable.
  • [x] Double horizontal cannon scatter: Clu ±1.2°, enemies ±2.4°. Level aim has zero vertical scatter; gunner shots remain exact. Deliberate vertical auto-aim to airborne targets is retained.
  • The user’s motion-fidelity correction supersedes both the universal four-second stomp deadline and the subsequent three-second full-rotation tuning. Regression cases check successful attacks from eight headings without exceeding original thrust/yaw limits, not an artificial deadline.

Pursuit attacks and JEV toggle — September 23

  • [x] Healthy lead Recognizers may commit a safe stomp while pursuing, without requiring JEV to select a separate strike maneuver. Pursuit endpoints use the wall-aligned landing pose; fresh sight, cooldown, support assignment, braking drift and full descent clearance remain mandatory.
  • [x] N toggles JEV/local tactical control during play or pause without restarting. The stats box displays ON/OFF. Disabling JEV disengages autoplay; U enables JEV when starting autoplay. Mode preference persists.
  • [x] Verify simulated JEV pursuit responses in a tight oblique corridor and a two-Recognizer encounter, plus Chrome keyboard/autoplay behavior. Full simulation suite: 260 passed. Live provider choices and actual play remain subject to review.

Progress-aware attack leadership — September 23

  • [x] Renew the lead recognizer’s twelve-second assignment after at least five meters of combined closing/descent progress. Do not rotate a progressing attacker out midway through its approach; retain blocked/dead/ineligible handoff and expiry for stalled attackers.
  • [x] Reproduce two aircraft approaching stationary Clu from opposite sides at 120 m: previously no stomp in 120 seconds; corrected local control completes the stomp in approximately 24.27 seconds with one consistent lead. Keep one active strike at a time.

Victory, surface impacts and attack support — September 23

  • [x] Add the explicitly requested win condition: complete every data beam, freeze the round, fade to the terminal and print docs/victory.txt continuously at 45 characters/second. This supersedes the earlier no-win-screen direction for this condition only; empty beam lists do not win.
  • [x] Drive victory printing from monotonic elapsed time rather than the capped simulation delta; reveal at most one character per frame as an immutable glyph element inside stable line nodes (no catch-up word bursts or DOM geometry/computed-style measurements) and skip hidden 3D rendering on the victory page.
  • [x] Use the victory typography size (min(1.5vw, 2.15vh), 1.12 line height) across opening, death, victory and credits text, without content-dependent sizing.
  • [x] Add temporary Shift+8 victory preview for end-screen review (also available while paused).
  • [x] Leave the victory page visible until Return; then play the existing credits text/music without the detachment message. Preserve death behavior and clean restart.
  • [x] Reuse the optical double-ring burst for projectile wall/floor contacts and visible vehicle armor. Orient effects to surface normals with an 8 cm offset, retain depth testing, cap active effects, freeze them on pause and dispose them on expiry/reset.
  • [x] Retain recognizer support assignments outside the old 140 m recruitment radius and when support units lose personal sight. Choose one lead attacker, one spotter and separated exit-cover positions using ground-connected map branches; use overhead slots where no branch is available. Cache formation goals until leadership/membership or recorded contact changes. Preserve radio limits, fresh target knowledge, wounded withdrawal and attack handoff.

Teleporter border placement — September 22

  • [x] Generate floor-shader pad borders from the active scenario’s maze sites, matching simulation placement. Remove the renderer’s use of the legacy authored-world pad constants. Include pad geometry in the shader cache key so different seeds/site counts cannot reuse stale positions.
  • [x] Check all 52 pads across two blueprint seeds, an authored seed and a single-site authored layout. Preserve floor-integrated borders, grid-line thickness and horizon fading.

Confined stomp positioning — September 23

  • [x] Search nearby landing positions in sixteen directions at two radii and include exact local wall-edge headings. Keep the whole aircraft clear and reserve positional tolerance inside the existing crush trigger; do not widen the damage radius.
  • [x] Settle strike approaches within 0.35 m and brake angular motion before committing to a descent. Preserve forward-only movement, collision checks, attack coordination, and fresh visual-contact requirements. This applies to Tactical/local and JEV maneuver execution; Classic behavior is unchanged.
  • [x] Verify oblique narrow-corridor and close-wall poses, a complete collision-free corridor stomp, and the full simulation suite.

Recognizer spotlight surface reach — September 23

  • [x] Extend downward search/target beams to the floor using their current projector height and direction, including the ribbon width. Preserve wall clipping and sensing limits. Do not fade the final segment when a ray ends on a surface.
  • [x] Check high-altitude ground/raised-surface endpoints and browser rendering, wall clipping, pause and state visibility.

Wall-shadow depth stability — September 23

  • [x] Increase the exact wall-overlay depth bias from slope/units −1/−1 to −2/−4. Independently rounded clipped vertices at distant maze coordinates could otherwise compete with the receiving wall and make patches flicker under tiny camera motion.
  • [x] Verify 81 perspective camera poses across 0/4/10 km offsets, wall orientations and centimeter camera movement. Keep depth testing and stencil union, and preserve exact geometric edges.

Carrier reveal panel and audio study — September 22

  • [x] Use Carrier derezed.mp4 at 2:37–2:38 to replace the carrier’s red rectangle with a softly feathered, translucent blue-white field and faint green rim. September 23 refinement: use a yellow pulsing rim, retain 0.5 base gray opacity at the center, and fade the gray fill to zero before it meets the rim. Add a 7 Hz pulse limited to 22% opacity variation, driven by simulation time so pause/reset remain stable.
  • [x] Extract 2:38.5–2:40 (the second half of the initial clip) as a stereo WAV and prepare a 120 ms crossfaded loop candidate. Record source hash, timing and filters in public/audio/carrier-derez-source.json; add both to the sound library for audition.
  • [ ] Audition the mixed-soundtrack excerpt/loop before choosing gameplay playback. No claim of isolated SFX or auditory approval; not yet loaded by the game.

Solar Sailer transit and carrier arrival — September 22

  • [x] Import the user-supplied JIHS Solar Sailer DAE locally as GLB with all seven textures. Preserve proportions at uniform 2.5× scale; use the film clip carrier and solar sailer.mp4 at 1:34–1:46 for direction, silver sails and amber beam.
  • [x] Add a fixed horizontal +X lane parallel to the carrier, at 520 m altitude and 600 m lateral offset. Traverse 12 km at 280 m/s every 180 seconds, starting three minutes into the round; fade at the distant ends. The beam fades in during the three seconds preceding each pass and fades out over nine seconds afterward, remaining invisible between passes. Pause/restart follow simulation time. This is background scenery without combat or collision participation.
  • [x] Replace the model’s short source beam with a 24 km amber beam split around the complete vehicle span; the sail end leads travel. Expose scale, altitude, speed and period in development tuning.
  • [x] Materialize the carrier at round start using the existing opening-line/rectangle, one wireframe sweep and solid fade, driven by the carrier’s 22 m/s translation (about 57 seconds for the hull to emerge, then the two-second solid fade). Reveal the +X front before the rear through a rectangle fixed in world space; its local position cancels the carrier’s translation. Sweep along the carrier’s long X axis, include existing hull seam lines in the reveal, and fade its shadow with the solids. Repeat on restart without recreating effects. Carrier wireframe ignores ground fog so it stays red at sky distances; its linear color is tuned to (1.5, 0, 0) for a softer red glow rather than the original overbright orange cast; running lights and beacons become active as they cross the reveal plane, independently of the final armor fade.

Local documentation styling — September 22

  • [x] Embed the colvmn stylesheet during npm run docs generation so Safari local-file viewing does not require a sibling-folder CSS load. Keep upstream colvmn unchanged; author Markdown/JSON and regenerate HTML with the project wrapper.

Wall rims and landing tactics — September 22

  • [x] Prevent moving aircraft shadows from exposing sawtooth strips on self-shielded maze wall rims. Use the slab face orientation and caster identity; give decorative trim explicit surface normals. Keep foreign-wall occlusion and exposed roof shadows.
  • [ ] Allow deliberate Recognizer landings as future tactical choices: block Clu’s path to give an ally a crush opportunity, or land to rest. Ground contact is not inherently a navigation failure; distinguish purposeful blocking/resting from getting stuck. No new landing maneuvers are implemented by this rendering fix.

Pursuit frame pacing — September 22

  • [x] Replace repeatedly sorted ground/air search frontiers with stable priority queues. Spread enemy ground route searches across ticks with a shared 192-node budget and 24-node round-robin slices; keep movement, sensing and collisions running every tick.
  • [x] Admit one new tactical candidate set per simulation tick across aircraft and tanks. Preserve existing maneuvers while waiting, defer expensive search-map construction to admitted planning work, and precompute search candidate rankings.
  • [x] Reject distant teleporter pads with a conservative radius check before building exact vehicle footprints. Verify exact overlap/containment behavior and lifecycle isolation.
  • [x] Record a reproducible eight-unit pursuit profile and validate bounded work, fair route completion, destination replacement and independent round budgets.

Maze tank pursuit — September 22

  • [x] Require a swept exit route when choosing blueprint ground patrol spawns; free floor inside an enclosed blueprint pocket is not a valid spawn. Cache checks per world and hull radius.
  • [x] Retain valid ground routes to stable destinations. When the ordinary pursuit search fails, try finer 8 m routing with a bounded larger search; permit wall-safe partial progress toward a recorded contact if the full destination remains unreachable.
  • [x] Verify patrol exit routes and actual radio-directed movement in Classic, local and JEV modes without revealing hidden Clu state. Preserve original observation age and physical wall collision.

Recognizer moving turns — September 22

  • [x] Remove heading-alignment stops from Classic, tactical/JEV and carrier escort flight. Preserve forward-only thrust, positional/angular inertia and level attitude while turning in flight.
  • [x] Limit approach speed by remaining distance and turn time to prevent orbiting nearby destinations. Carry speed through collinear tactical waypoints; retain braking for arrival, acquisition, deliberate holds and confined descent. Permit a settled attack from an already clear actual pose without waiting for redundant final yaw.
  • [x] Check right-angle/reversing turns, multi-location search, wall-side clearance, coordinated stomps and browser momentum/pause/reset behavior.

Aircraft shadow occlusion — September 22

  • [x] Gate Recognizer, carrier and detached-part shadows against the existing static maze light-depth atlas. Preserve shadows on exposed roofs while preventing additional dark silhouettes on obscured wall faces and covered ground.
  • [x] Apply the same visibility test to projected Recognizer/debris ground silhouettes and rebind it when reinforcement growth rebuilds the atlases. Verify pixel coverage, materialization and restart resource stability.

Gravity, aerial zoom and attack coordination — September 22

  • [x] Remove vertical damping from production debris; retain horizontal drag, angular damping and contact friction. Regression now measures actual production free-fall velocity/displacement for four seconds without disabling damping in the test.
  • [x] Restore scroll-wheel aerial zoom through CameraRig; verify both running and paused operation.
  • [x] Use one active-maze-width radio radius for enemy observations, neutralization, materialization awareness and tactical ally information. Preserve observation age/delivery delay and vertical-distance checks.
  • [x] Reserve one attack lead among nearby aircraft with compatible recorded target knowledge. Retain that lead for a bounded twelve-second approach; supporters use separated 90 m flank positions and cannot initiate a stomp. Reassign on destruction, blocked approach, lost visual contact, injury/cooldown or lease expiration. Coordination uses radio-visible allies, never unseen live Clu coordinates.

Carrier escorts and debris avoidance — September 22

  • [x] Preserve carrier escort duty in Classic, local and JEV modes when no current target/sound investigation interrupts it. Air escorts match a moving carrier slot above roof clearance; ground escorts retain separate perimeter detours, then use a bounded catch-up speed (1.4× ordinary tank speed) to regain formation. Combat movement retains its existing speed cap.
  • [x] Publish detached physical debris poses/velocities/bounds to the session. Player perception filters these by 160 m range and wall visibility; JEV receives up to 24 nearest observed pieces, never hidden wreckage.
  • [x] Autoplay checks visible falling/crossing/settled debris every tick against a 2.5-second predicted path, including turbo and braking. It can brake or steer using normal inputs and wall clearance, independent of API latency. Manual input overrides remain intact; damage remains real.
  • [x] Verify carrier rejoining after blueprint traversal, visibility isolation, turbo prediction, physics observation cleanup, and otherwise-lethal settled/falling debris encounters. Full suite: 232 passed; Chrome autoplay regression passed without provider calls. Prediction is approximate and cannot guarantee escape from unavoidable impacts.

Refactoring roadmap — September 22

Design review: Refactoring review and design. The ownership refactor is implemented locally. Keep this checklist as the plan source; the linked review now records the implementation, compatibility boundaries and remaining human checks. No deployment was performed.

  • [x] Review current world selection, simulation/control boundaries, application lifecycle, rendering/audio ownership, and JEV transport/accounting. Document composition-based OOP recommendations grounded in the code.
  • [x] 0 — Baseline: explicit blueprint/authored scenarios and seeds, failure captures and boundary contracts; preserve known unresolved third-maze navigation as a tracked defect.
  • [x] 1 — World: explicit scenario/world construction, including derived pads/beams/rosters, shared by browser and tests; support independently constructed worlds without browser globals.
  • [x] 2 — Navigation: extract route execution/cursor/arrival behavior from mission/JEV selection, preserve controller behavior and expose blocked/progress diagnostics.
  • [x] 3 — Lifecycle: compose application, session, loop, input and HUD owners; preserve fixed-step ordering and isolate debris physics from presentation ownership.
  • [x] 4 — JEV: separate typed transport, scheduling/application policy and shared protocol/cost contracts; preserve retry, quota, privacy and lifetime behavior.
  • [x] 5 — Presentation: extract camera coordination, then clarify effect/resource ownership with captures and lifecycle checks; retain current shader ordering.
  • [x] 6 — Audio/cleanup: isolate music and voice responsibilities, remove competing implementations and reconcile documentation; retain explicit default-world adapters for standalone fixtures.

Remaining acceptance work: Safari audio-unlock/listening and side-by-side visual review on the user’s hardware. Automated results are recorded in Validation; these checks do not establish artistic fidelity. The seeded replay captures three beams, then holds near 686 seconds; full multi-maze completion remains unresolved.

Debris gravity and faster panels — September 22

  • [x] Use shared Earth gravity (9.81 m/s²) for every detached vehicle part; remove the Recognizer-specific 14.7 m/s² override. Preserve inherited velocity, blast impulse, damping and collisions.
  • [x] Divide only panel formation and retraction durations by three: 0.5 s closing, 11 s enclosed hold, approximately 1.167 s opening. Total transfer is approximately 12.667 s. Camera movement rates, blast settings and animation ordering are unchanged.

Beam panels, timeout retries and request stats — September 22

  • [x] Replace transfer shafts with 16 translucent blue polygon panels, bright vertical edges and 0.2 m corner gaps. Preserve sequential closing/opening, height, timing and disabled blast. Match Recognizer contact damage to panel segments.
  • [x] Retry JEV timeouts twice (three consecutive attempts total), with 0.5/1 second minimum backoff and existing pacing. Continue local piloting during retries, reset the failure streak on a response, and disengage after exhaustion. Non-timeout errors/budgets still disengage immediately. Pause cancellation is not a timeout.
  • [x] Display this round’s total player/enemy request attempts, rolling 10-second requests/sec and USD cost in a bordered box beneath the top-left U / autoplay control. Count retries, preserve totals across pause/autoplay toggles, reset for a new run. Reported billable input usage replaces conservative request estimates; prefix cost with ~ while estimates remain. This round’s display is separate from the persistent hourly relay budget.

Pad horizon and carrier spotlights — September 22

  • [x] Bound pad-border shader anti-aliasing footprint and fade unresolved pads instead of letting grazing floor derivatives expand red borders across the horizon. Keep borders on the floor surface.
  • [x] Default CARRIER.searchlightsEnabled to false, clearing light tracking/illumination and stopping spotlight-derived radio reports. Recognizer spotlights remain independent.

Post-transfer damage bubble disabled — September 22

  • [x] Default DATA_BEAM.blastEnabled to false. Skip post-capture wave damage and hide its expanding sphere/ring. Keep capture, healing, color transition, camera sequence and transfer-shaft contact behavior. Retain the effect behind this flag for later re-enabling.

Corner arrival stall — September 22

  • [x] Reproduce a motionless stall at about 147 seconds after the first blueprint beam: waypoint distance about 0.5 m, next segment occluded, throttle and steer both zero.
  • [x] Distinguish intermediate corners from final destinations. Keep steering to 2 cm at intermediate points and creep at up to 2 m/s within 2 m, instead of applying final-stop/steering dead zones. Preserve final beam stopping behavior.
  • [x] Extend the actual-blueprint regression through departure and capture of a second beam, rejecting prolonged motionless/no-steering stalls between transfers.
  • [ ] A longer exploratory run encountered a separate hold/route-failure near the third maze around 689 seconds. Full multi-maze completion remains unverified.

Blueprint route correction — September 22

  • [x] Reproduce hold at the enemy-free browser-default blueprint spawn. Prior autoplay simulation fixtures used the historic authored layout and missed this failure.
  • [x] Search outward from the constrained beam destination using an 8 m grid and larger bounded search/detour allowance, then reverse the swept route for Clu. Keep coarse open-grid routing as fallback. Default enemy route-search settings remain unchanged.
  • [x] Add permanent blueprint coverage asserting a collision-clear route from the actual spawn and capture of its local beam. Browser autoplay coverage now begins at the blueprint opening before the separate empty-grid control fixture.

Post-combat autoplay — September 22

  • [x] Distinguish visible contacts from maneuver threats: enemies within 100 m, or within 250 m approaching Clu faster than 2 m/s. Include both visible contacts and threat IDs in player snapshots; no private enemy pursuit state is read.
  • [x] Replan immediately when threats appear/disappear, clear route-failure cooldowns on that transition, and reject delayed escape choices once threats are gone. Resume the beam mission after destroying pursuers.
  • [x] While red beams remain and no threat is present, a missing route permits maze-entry recovery or hold/retry, never unrestricted open-grid exploration. Verify five destroyed pursuers, nonapproaching distant contacts and temporary route failure.

Autoplay cornering and turbo — September 21

  • [x] Preserve waypoint progress when JEV confirms the current option. Consume visible route waypoints continuously and brake/turn in place for sharp headings; approach occluded corners closely enough to see the next segment instead of stopping at the waypoint acceptance radius.
  • [x] Prioritize uncollected beams within 2 km over previously selected distant destinations. Once local beams are blue, travel to the next maze remains intentional.
  • [x] Activate turbo through normal simulation input only when aligned, moving, and a clear route segment exceeds the full boosted run plus braking distance. Regulate boosted speed; avoid automatic activation during manual driving overrides. Expose turbo cooldown and duration in player snapshots.

Background autoplay — September 21

  • [x] Keep autoplay running on window blur or hidden-tab transitions. Clear held manual inputs on focus loss. Preserve explicit pause and pause unattended play when autoplay is disabled or JEV fails.
  • [x] Use one scheduled loop: animation frames while visible, a 250 ms timer while hidden. Retain fixed 60 Hz simulation steps with bounded one-second catch-up; skip hidden rendering. Cancel both scheduling paths on disposal. Browser/OS suspension can still reduce background progress.

Autoplay beam navigation — September 21

  • [x] Expose all beam colors with distance in meters and hull-relative bearing in radians (positive right), plus the active destination. Remove the 500 m objective cutoff.
  • [x] Retain a selected uncollected beam across replans; advance when it becomes blue. Without visible enemies, offer the mission route rather than unrelated short wandering moves. Preserve combat maneuver options and hold during transfer.
  • [x] Connect local swept maze routes with long open-grid legs around maze bounds; retain route waypoints across replans and recheck clearance. Retry failed objectives after a bounded delay. Verify two captures in different authored mazes during a 600-second enemy-free simulation. Full combat completion remains unverified.

Local JEV request pacing — September 21

  • [x] Pace local client calls at least 650 ms apart in wall time, including across restarts, to respect the relay’s 600 ms minimum. Distinguish busy, short-interval and hourly-cap warnings; include retry delays. These limits are independent of purchased provider credits. Replace the request-count allowance with a $1 USD rolling-hour local spend budget. Configure server-only JEV_HOURLY_BUDGET_USD in .env.local; restart Vite after changes. Persist reservations and settled usage in ignored .local/jev-spend.json. Public Worker quotas remain separate.

Beam camera and persistent autoplay — September 21

  • [x] Animate a presentation-only aerial rise and L-direction orbit during beam transfer, at half keyboard speed. Rise and descent each take 2.4 seconds; descent starts at 10.1 seconds and reaches Clu at 12.5 seconds as the ring opens. The beam continues its color transition during opening. Freeze with simulation pause, skip automatic motion for reduced-motion users, and allow V/P to cancel. Do not turn the weapon.
  • [x] Keep autoplay selected until U or its HUD toggle is used, or JEV becomes unavailable. Service errors/timeouts/rate limits disengage the pilot and clear its plan; no automatic re-enabling after recovery. Retain the warning while off. Held driving/aim controls override their own channels, and Space/mouse fire combines with automatic firing without interrupting navigation. Release returns held channels to the pilot; existing cruise/aim-lock modes retain their normal behavior.
  • [x] Verify camera timing/pause/return and persistent manual overrides in simulation and headless Chrome.

Beam objective, longer hold and teleport audio — September 21

  • [x] Make turning every red data beam blue explicit in the player Jev prompt and snapshot. Include remaining/total counts, red/transitioning/blue state, remaining transfer time and the stop-and-wait activation rules. Keep survival and the open-ended simulation; no win screen. Candidate routes remain bounded, so successful completion of all sites is not guaranteed.
  • [x] Extend the closed ring hold from 6 to 11 seconds without changing the 1.5-second closing or 3.5-second opening sweeps. Total transfer is now 16 seconds. Visual color progress, healing and release use the same total; only the hold duration is extended.
  • [x] Add original synthesized teleport audio: descending phase collapse and rising resonant reassembly, with a short digital snap and stereo echo. Trigger only on completed relocation. Nearby vehicles produce spatial cues at departure/arrival; Clu hears one continuous 0.78-second cue at arrival. Master mute/pause and reset cleanup apply. Source: src/audio/teleport.js.

Autoplay driving continuity — September 21

  • [x] Treat temporary route endpoints as handoffs: request a new feasible route before the braking zone, roll through straight intermediate waypoints, and skip already-passed waypoints after delayed decisions. Use a turn/distance speed target instead of an all-or-nothing angular throttle cutoff; retain braking at obstacles and data destinations.
  • [x] Steer the turret toward the active visible target or along the driving route when there is no contact. Retain a tracked target across replans unless another is substantially nearer, to reduce camera swings. Keep the ordinary turret motor limits and temporary manual overrides.
  • [x] Verify sustained cruising above 19 m/s after acceleration in a clear 20-second route, momentum through collinear waypoints, stopping at a data destination and reorienting a sideways turret. Browser/build validation is recorded in Validation.

Optional Clu autoplay — September 21

  • [x] Add an off-by-default U key and HUD button to let Jev choose Clu maneuvers. Keep the enemy AI mode independent. Movement/turret/fire input temporarily overrides the corresponding pilot controls; pause suspends requests and motion. Label Jev/local fallback on the button.
  • [x] Supply Clu's own pose, health, heading/speed, nearby visible enemies, static walls/data destinations, recent positions and bounded feasible maneuver routes. Use a distinct server-owned player prompt. No hidden enemy positions, memories or tactical plans enter its snapshot. Local motor code steers/brakes and only fires through the existing observed target/aim-cone checks.
  • [x] Share one serial Jev client, rate/cooldown budget and alternating player/enemy opportunities. Reject stale or pre-teleport replies; local tactics continue during failures. Check moving inputs, information isolation, selection, pause and temporary manual overrides. A live local-relay player request returned an accepted decision; encounter quality and long autonomous runs still need human review.

In-game service warnings — September 21

  • [x] Add a compact top-right warning area below the health/turbo meters, available in production as well as development. Show JEV OFF for deliberately selected Classic/local modes, JEV LIMIT for rate/budget failures, and JEV UNAVAILABLE for service/network failures. Explain the reason and continuing local AI. Keep warnings through pause, resets and retries until a successful response; normal idle/low-confidence decisions are not service failures. Allow other named warning/error notices to share this area, and announce changes politely to assistive technology.

Public Jev hosting — September 21

  • [x] Keep the game/assets on GitHub Pages and add a Cloudflare Worker for the fixed Jev decision contract, with a server-side secret and public build-time API URL. Preserve the local Vite relay.
  • [x] Enforce body size, timeout, per-IP pacing and durable global daily request/input-byte limits before calling Jev; bound concurrency and honor Retry-After with local AI fallback. Anonymous access is intentional; CORS is not authentication and shared IPs share limits. See Jev design and README for limits, disabling and deployment.
  • [x] Verify quota persistence/rollover, concurrency, invalid requests/answers, secret isolation and client cooldown with Node tests; dry-run the Worker and check its SQLite budget in the actual local Cloudflare runtime.
  • [x] Deploy the Worker and server-side secret; verify a real provider decision and the production build in headless Chrome at the public origin. Website publication uses its pinned TRON checkout and public API-base build setting.

Carrier shadow edge correction — September 21

  • [x] Increase the moving carrier's shadow tile from 1024 to 4096 pixels over its 1500 m light-space span (about 0.37 m per texel). Use a compact 6×6 Gaussian-weighted depth-comparison filter at texel centers, retaining receiver-plane correction; never interpolate packed depth values. This supersedes the first four-tap refinement and softens the remaining fine edge serrations. Reduce the carrier-specific depth bias for its long depth range. Keep maze/Recognizer tile sizes unchanged and preserve the floor grid and emissive materials.
  • [x] Compare shadow edges against independent ray/box intersections for stationary and translated casters, check the actual carrier on walls/floor, and inspect before/after captures. This remains a finite-resolution filtered dynamic shadow, not exact vector geometry; the larger tile increases GPU memory/render cost. See validation for browser results.

Optional tactical movement and Jev — September 21

See Jev enemy control for the implemented architecture, input/output examples, scheduling, validation, and current limits.

  • [x] Start the browser in Tactical + Jev with the full enemy population (small encounter disabled), and retain Classic/local tactical modes in Shift+T tuning, with an explicit Apply/restart button and persisted preference. Optional comparison roster: two Recognizers and one ground tank. Tactical modes suppress pursuit reinforcements; Classic restores the original roster/controller. Tactical run seed is 1982; page-local maze layout remains stable for comparisons.
  • [x] Replace the tactical stomp's circular clearance rejection with conservative oriented aircraft bounds, triangle-level wall checks, and bounded swept tests for translation, rotation and descent. Generate staged climb/turn/travel/align approaches and orientation-aware low-corridor routes. Follow them with the existing inertial forward-thrust/lift/yaw dynamics. Recheck movement and separation corrections against geometry; a blocked maneuver replans rather than driving through walls.
  • [x] Give airborne and ground units choices for withdrawal, regrouping, pressure, cover/ambush and attacks. Wounded units prefer retreat; ground units cease firing while withdrawing. Preserve committed movement, but invalidate stale routes and react to injury. Coordinated choices see nearby allies' intentions within radio range; no hidden live Clu state enters planning or requests.
  • [x] Use Jev only for units with a fresh recorded Clu position within one maze length (horizontal distance); distant or unaware units use local tactics. Never gate using hidden live Clu coordinates. Send structured self state, dated target memory, nearby allies, local static wall geometry and candidate pose sequences to Jev. Include precomputed travel distance, visibility relative to the last known target and supporting-unit counts. Jev chooses only a supplied candidate ID; local collision/controller code remains authoritative. Inspect recent requests, probabilities and real elapsed latency in the tuning panel.
  • [x] Connect the ignored server-side credential file or environment key through a local Vite dev/preview endpoint. Bound request size/rate/hourly total and timeout; label fallback explicitly. Abort/discard stale answers on pause/reset/mode changes and reject invalid IDs or low-confidence choices. Protect credential files from Vite static serving and Git.
  • [x] Check provider browser access: CORS preflights from local origins are rejected, so direct browser calls are not viable in the tested setup. Keep the same-machine relay; initial real end-to-end calls measured 317 ms and 292 ms. This was initially a local-only service; the public Cloudflare relay above now supports static production clients.
  • [x] Replan on sight loss/reacquisition, newly received or expired contact, an observed velocity change of at least 8 m/s, or target displacement of at least 45 m. These events bypass the normal commitment gate with a 0.65-second event cooldown. Preserve momentum and committed attack phases; reject Jev answers based on superseded observations/revisions. Healthy units actively follow the bounded last-known path, then inspect nearby branches instead of favoring passive ambush. Search hypotheses never become sightings or authorize blind attacks. Ground route refresh follows a new tactical plan.
  • [ ] Human comparison of encounter quality, retreat behavior and longer Jev sessions. The planner is bounded and conservative, not a globally optimal flight/attack planner. A geometry-valid maneuver is not a guaranteed successful strike on a moving target; some narrow spaces remain inaccessible. Choosing better actions than the local policy remains an experimental question.

September 21 hearing: aircraft and ground enemies receive bounded, expiring acoustic observations for engines, cannon fire, impacts and explosions. Use distance attenuation, wall muffling and deterministic bearing/range error; never copy a sound into confirmed sighting memory. Unknown sounds permit local investigation and nearby Jev requests with target: null; friendly sounds are context only. Hearing is independent of player audio volume and pauses with simulation. Range controls are available in development tuning. See Jev enemy control for the report format and limits.

September 21 connected-search follow-up: persist whether the last-known location has been checked, so moving into a branch cannot re-enable a return-to-origin maneuver. Build a bounded graph of tank-passable corridors from the predicted contact point (8 m steps, 160 m path budget, swept wall checks); use its reachable locations instead of nearby open cells across arbitrary walls. Retain completed checks for the search episode, advance both ground and air units on arrival, and share search progress plus each candidate's searchPath with Jev. Aircraft already above the roof search from above instead of descending at every checkpoint; feasible low search routes remain available to settled low aircraft. Regression checks cover an L-shaped route, disconnected pockets, continuous aircraft search and ground progression.

September 21 opening-pursuit correction: above-roof aircraft proceed toward the travel waypoint while turning/climbing, rather than returning to the route origin after inertial drift. Healthy units receive a pursuit/support maneuver and no longer prefer regrouping simply because allies are spread out. Reserve attack spacing only for a nearby strike or active stomp; retain local swept collision checks and knowledge-limited target prediction. A moving-opening regression requires all five pursuers to close distance and exceed Clu’s normal speed.

Design references: the Tetris example measures reachable action outcomes and avoids conflicting directional hints; the Doom example uses structured observations, selected maneuvers and local motor control. This implementation is independently written; no external game code or assets were copied. API shape follows the TypeSafe quick start.

September 21 grid alignment: maze-site origins now snap to the 24 m world grid, with seeded rotations restricted to 0°, 90°, 180° or 270°. The initial maze stays at the origin and unrotated. Rendering, collision, patrol locations, data beams and teleport pads derive from the same site transforms. Preserve the authored diagonal wall ends and blueprint shapes within each site.

Spatial teleport pads — September 21 (supersedes the timed transfer)

  • [x] Preserve four grid-aligned 48 m square borders outside each maze and their links to other sites. Extend each invisible portal volume from the floor to four maze-wall heights; aircraft above that volume do not transfer.
  • [x] Clip vehicle solids and their shadows inside the volume, drawing glowing edge wireframe only on those portions. Partial entry/exit is spatial, independent of time. Clu, ground tanks, folding aircraft, turrets, projected floor shadows and aircraft depth-atlas shadows share the same clipping planes. No sweeping rectangle or fade is used for teleportation; reinforcement materialization remains unchanged.
  • [x] On full conservative hull/turret/vertical containment, transfer instantly with the same local pad offset, altitude, heading, linear/angular motion, turbo and player controls. Continue driving normally while entering/leaving. Block an occupied destination without freezing the vehicle; process transfers atomically to avoid overlapping arrivals. Require complete 3D exit before rearming. Pulse the source/destination borders briefly; snap camera/interpolation history at transfer.
  • [x] Replan arriving enemies and synchronize nearby recorded awareness immediately, without inventing live Clu coordinates. Vehicles remain subject to ordinary movement, visibility and weapon/collision rules during the spatial effect.
  • [x] Verify partial/complete entry, turret and ceiling bounds, altitude exit, offset/momentum, occupied/simultaneous arrivals and awareness in simulation. Drive through in Chrome; inspect half-wireframe entry, full-wireframe arrival and solid exit, with paused simulation and no browser errors. Preserve separate reinforcement animation checks.

Wireframe rezzing and pursuit reinforcements — September 20

September 21 awareness correction: on completing reinforcement materialization or an enemy teleport arrival, synchronize with active airborne and ground allies within the existing 304.8 m three-dimensional radio radius. Copy the freshest recorded sighting and alert state, retain observation timestamps, and share confirmed target destruction. Exclude unconfirmed spotlight acquisitions. Fresh pursuit knowledge suppresses searching spotlights; arriving units still need their own visual observation to set canSee.

  • [x] Reveal a vehicle with one front-to-back wireframe sweep. The rectangle starts as a horizontal line and expands vertically for 0.6 seconds, then travels for 1.8 seconds from 6 m ahead of the nose to 6 m beyond the tail. After the wireframe sweep, fade the whole solid vehicle in over 0.35 seconds while the rectangle and temporary edge overlay fade out. Activate the vehicle immediately when that fade finishes (2.75 seconds total). This supersedes the earlier two-pass design at the user's request. Animation follows simulation time, including pause. The supplied Homeworld Hyperspace clip is a motion reference, not a shipped game asset.
  • [x] Use one shared continuous-pursuit clock for airborne Recognizers. Every twenty seconds in Classic mode, create exactly one reinforcement near one of the pursuers, regardless of pursuer count. Continue repeating while pursuit persists; reset the clock when no Recognizer is actively spotting/pursuing Clu or Clu is destroyed. Choose a clear nearby air position above the maze and copy only the summoning observer's recorded sighting.
  • [x] Hold the incoming vehicle stationary, silent and intangible during materialization. After completion it independently senses, navigates, reports and attacks. Give new aircraft IDs separate from ground tanks; extend visual, spotlight and audio pools and reuse them after reset.
  • [x] Hide shadows during the wireframe sweep, then fade ground shadows and dynamic atlas attenuation with the solid vehicle. Rebuild shadow receiver bindings without stacking shader hooks. Keep the dynamic aircraft atlas bounded to the twelve nearest visible aircraft; other aircraft retain projected floor shadows. There is no reinforcement-count cap; very long uninterrupted pursuits still increase simulation, geometry and audio work.

September 21 interval follow-up: the shared reinforcement period is now 20 seconds (previously 15). Tactical modes continue to suppress reinforcements. The browser now defaults to Tactical + Jev with the full enemy population; earlier experimental preferences are superseded once, and subsequent explicit selections persist.

  • [x] Fix phantom square/diamond shadows after reinforcement shadow-atlas rebuilds. Evict the receiver material's cached GPU program bindings when attaching replacement shadow uniforms, even when the generated shader key stays the same. Otherwise Three can retain uniforms pointing at a disposed atlas. This preserves the actual vehicle silhouettes on roofs and ground; the materialization rectangle remains excluded from casting.

Tuning lives in src/game/materialization.js and src/simulation/reinforcements.js. The reusable materialization presenter is first connected to incoming Recognizers; starting vehicles still appear normally. The user endorsed carrier launches, data-beam arrivals and reverse-sweep recalls as further uses; those remain future work.

September 20 moving-target interception: add the observed target velocity along the approach direction to the Recognizer's distance-based arrival speed. Previously, an aircraft approaching from behind settled into speed-matched pursuit short of a valid landing prediction. It now continues closing until folding/fall time and residual braking drift permit a committed stomp. Navigation still uses only its own sighting memory; the committed drop does not track subsequent evasive movement.

September 20 tuning: increase Recognizer cruise speed by 10%, from 27 to 29.7 m/s. The existing pursuit multiplier requests 34.155 m/s, compared with Clu's normal 22 m/s and turbo 55 m/s. Raise forward thrust authority from 22 to 24.2 m/s² so drag does not cap flight below the new pursuit speed. Turning, lift, drag and braking settings remain unchanged; carrier formation speed retains its carrier-relative setting. Verification: npm test passes all 132 checks; a 60-second fixed-step straight-flight calculation reaches 34.155 m/s. Browser driving feel has not been rechecked for this tuning change.

The user's latest direction supersedes the structured chase roadmap below. The purpose is the feeling of being in the 1982 maze: free exploration and independently simulated Recognizers, without an assigned objective or tuned encounter sequence. Goal and ../AGENTS.md record the active requirements.

Maze and shared geometry

  • [x] Replace the one-dimensional route with connected branches, loops, dead ends, open courts and four exterior openings.
  • [x] Correct the initial square layout into long oblique slabs with diagonal clipped tips. Use the supplied overview as a visual reference; distinguish reconstruction from unseen/inferred layout.
  • [x] Share convex prism geometry among rendering, hull collision, camera obstruction, projectile blocking and three-dimensional sight tests.
  • [x] Preserve a fixed seed/layout for repeatable comparison. Allow travel onto the surrounding grid and turning in place in narrow passages.

Autonomous Recognizers

  • [x] Spawn five persistent aircraft outside the maze, with independent patrol destinations, headings and motion.
  • [x] Limit vision by range, field of view and actual wall occlusion.
  • [x] Maintain timestamped local sightings and share immutable observations through delayed, range-limited radio messages. Relays retain the original timestamp/source.
  • [x] On losing sight, investigate a bounded projection of the last observed velocity, then search plausible nearby passages. Expire stale knowledge and resume wandering.
  • [x] Keep navigation separate from live-player perception so unseen Clu motion cannot steer an aircraft.
  • [x] Halve the old model scale to put upright legs at roughly the user's 30-foot estimate. Match physical hit volumes, roof clearance and aircraft spacing.

Presence and controls

  • [x] Remove mission progress, capture zones, waves, victory and defeat. Keep exploration running until paused or reset.
  • [x] Keep a level, independently controlled turret and vertical-only assistance for aligned, unobscured targets.
  • [x] Render and spatialize all five aircraft. Muffle their sound when walls obstruct the listener.
  • [x] Hide instruments by default; add optional H instruments, Tab survey and V aerial view. Keep pause, mute, reduced motion and lower quality.
  • [x] Import the user-supplied arabinowitz tank and Shriker1 Recognizer GLBs, preserving proportions, turret yaw, muzzle alignment and reduced aircraft scale. See Models.
  • [x] Add a fixed reference studio for side-by-side film comparisons; iterate on tank trim, gold shoulders, highlights, shadows, floor visibility and oblique maze views.
  • [x] Apply the renamed film references and new wall-detail study: thin seams, sparse panels and shallow angled ledges, with a fifth reference-studio view.
  • [x] Trace the supplied blueprint and use it as the default game maze, retaining the original at /?maze=authored. Preserve concave notches in roofs, collision and sight; provide a top-down overlay and editable outline coordinates.

Verification and fidelity review

  • [x] Unit checks cover connected branching topology, diagonal-tip openings, hull sweep/sliding, occlusion, sighting memory, radio delay/expiry, independent hidden-player counterfactuals, weapon behavior, resets and fixed-step consistency.
  • [x] Complete browser controls, multi-agent lifecycle, production preview and sustained traversal checks for this revision; record their actual outcomes in Validation.
  • [ ] User review of diagonal forms, scale, patrol presence and sound. Exact film topology and final visual approval remain unresolved.

Run npm run dev and visit http://127.0.0.1:5173. Supporting documents: Assets · References · Validation.

Superseded turn-speed experiment — September 23

Historical experiment, now superseded by restoring original motion above: maximum yaw rate is 120°/s (one revolution per three seconds at full speed), with 240°/s² acceleration/braking and the normal smooth heading response. All flight uses the same limit, including close attacks. Close-attack speed reduces when a turn needs a tighter radius, avoiding repeated orbits. A turn from rest includes acceleration and settling time, so a backwards-facing attacker can exceed the four-second stomp target. Eight-heading tests verify bounded yaw rate/acceleration and successful stomps; aligned attacks retain the four-second check.

Helicopter-style Recognizer translation — September 23

Recognizers can thrust sideways and backward independently of yaw, in local/JEV navigation, Classic navigation and carrier escort flight. The acceleration vector shares the original 24.2 m/s² budget across all directions (no diagonal bonus); drag, braking, speed caps and angular inertia remain unchanged. Tight-corridor planning includes lateral/reverse translations with swept hull clearance. A wall-aligned hull can slide into position without first turning broadside. Existing pursuit-to-stomp opportunity checks and support assignments remain active.

ENCOM terminal signature — September 23

  • [x] Add a local SVG ENCOM mark based on the supplied MCP terminal reference, with pale lavender glow at the lower right of the shared terminal overlay. Opening, detached/credits, victory and victory credits share the mark, and it fades with the opening transition. Typed text is unaffected.

Lead and intercept approaching Clu — September 23

  • [x] Choose a reachable crossing ahead of observed motion, accounting for approach, normal acceleration/braking, folding and fall time. Bounded prediction uses recorded position/velocity and stops at mapped obstructions.
  • [x] Hold the chosen crossing while sightings follow the predicted path, instead of continually moving it farther ahead. Changed velocity, lost sight, injury or an expired interception still permits replanning. JEV candidate facts include approach time and predicted impact time.
  • [x] Keep the lead's attack plan when only supporting positions change. Supporting units still refresh their own routes.
  • [x] Preserve a useful wall-aligned facing during overhead translation. Start folding while Clu approaches; commitment still requires fresh personal sight and a physically clear descent, and a committed drop cannot track an evasive maneuver.
  • All existing speeds, accelerations, fold/drop timing and health rules remain unchanged.

Stored shots and extended credits — September 24

  • [x] Add a three-segment stored-shot meter beneath health. Keep CLU’s normal cannon cooldown at 1.14 seconds. Restore one stored shot per ten seconds without firing, up to three; firing resets the next-shot timer but preserves banked shots.
  • [x] Follow the normal credits with credits_extended.txt, in bounded terminal pages, before the final END OF LINE. Preserve normal credits pacing; print the longer acknowledgments faster.
  • [x] Archive all four arena signature/date inscriptions in a separate GLB instead of loading their geometry with the arena.

Carrier and maze ground-shadow overlap — September 24

  • [x] Stop cutting moving ground shadows with the coarse maze visibility atlas where the floor already receives exact geometric maze shadows. This removes mismatched sawtooth boundaries at overlaps; ground layers multiply smoothly. Keep atlas occlusion for maze walls and vehicle receivers.

Optional outer mazes — September 24

  • [x] Default browser gameplay to the central labyrinth only. Restore all four smaller mazes with ?outerMazes=1; authored/reference scenarios keep their existing layouts.
  • [x] Filter disabled placements before constructing walls, collision data, open cells, patrols, beams, pads, geometry and shadow maps. Build the blueprint wall source lazily only when enabled; retain lightweight layout metadata for stable placement and opening coordinates.
  • [x] Preserve the central labyrinth’s position and retain the original outer placement/spacing algorithm. Reindex active sites consistently for navigation. With one maze, connect each of its four teleport pads to the opposite pad.

Tank-to-cycle progression and deferred scenery — September 24

  • [x] Completing the central labyrinth beam transfers the player to the middle gold cycle, with a three-second countdown. The arena race remains inactive beforehand. A/D or left/right queue 90-degree turns; forward motion is automatic. V offers an aerial view, Escape pauses.
  • [x] A destroyed player cycle waits for the team result. A gold-team win opens the victory terminal; losses/draws consume one of three match chances and reset the match after six seconds. Exhausting all three chances opens the existing loss terminal. Tank combat/JEV planning stop during the cycle stage.
  • [x] Defer the arena/cycle module and assets until tank play begins. Wait safely with a loading message if the beam finishes before they are ready. Load the solar sailer after 30 simulation seconds, before its first pass at 180 seconds. Dispose late arrivals if the app has closed.
  • [x] Move the initial tank position south of the central labyrinth, preserving the previous south-edge approach distance (about 1,338 m), with opening Recognizers translated by the same offset.

Cycle testing, turbo and audio — September 24

  • [x] Temporarily start new browser games in the cycle arena. CYCLE_TESTING.startInArena in src/game/light-cycles.js owns this switch; ?cycleStart=0 restores the maze-first game, ?cycleStart=1 explicitly selects the test start. Entry waits safely for deferred arena assets, skips the opening pursuit/camera fly-in, and starts a three-chance player match without marking the beam collected.
  • [x] Hold I for player-cycle turbo, including partial charge. Releasing I immediately preserves remaining charge and resumes recharging. Capacity is 10 seconds, refill 60 seconds, speed 2.5×; no automatic boost or full-charge prerequisite. Holding an empty tank stays at normal speed until released, avoiding repeated boost/recharge pulses. Each retry resets charge. T remains the tank-only turbo key.
  • [x] Per-cycle movement progress and chronological cell crossings keep boosted movement, trails, camera and collision checks aligned. Other cycles retain their normal speed. The top-right meter shows I / TURBO in the arena.
  • [x] Extract six short film-mix sound candidates (startup, launch, drive loop, turn, crash, trail deactivation) and connect them to spatial cycle playback. Reproduce with python3 scripts/extract-cycle-sfx.py; timestamps, source hash, filters and attribution are in public/audio/cycle-source.json. These are picture-selected extracts, not isolated stems; auditory review remains pending.
  • [x] Arena entry stops music and clears queued transitions. Tank gameplay music cannot requeue during the match; terminal credits music remains available. Cycle audio stops on pause, death, reset and disposal, and resumes engines without replaying launch events.

Cycle arena patrol and sample corrections — September 24

  • [x] Keep the live arena Recognizer on its perimeter flight route during cycle matches, including countdowns and retries. The cycle-stage simulation previously suspended this guard along with the tank encounter. Clear its obsolete tank attack/spotlight state, unfold gradually and retain normal patrol flight constraints; destroyed guards stay destroyed. Other tank enemies remain paused. Restore the guard's spatial flight sound during cycle play.
  • [x] Replace the driving-loop source with the user-selected 0:47–0:48 video interval (0.1-second seam crossfade, 0.9-second finished loop) and the turn cue with 0:51–0:52 (one second, short edge fades). Version the two URLs to bypass stale cached WAVs. Other sound selections remain as before.
  • [x] Extend the cycle explosion to 2.0 seconds (75.85–77.85), preserving its tail. Add a separate player cabin loop from 1:36–1:38 (1.9 seconds after seam crossfade), retaining 0:47–0:48 for other cycles.
  • [x] Preserve stereo source channels through paired HRTF emitters 0.6 m apart. Drive, launch and turn emitters follow their cycle; explosions/trail collapse stay at the crash position. Apply smoothly changing Doppler from source/listener radial velocity to other cycles, keeping the player's cabin pitch stable apart from turbo. Camera motion supplies listener velocity.

Loading diagnostics and cycle spectator flow — September 24

  • [x] Print plain-text [TRON loading] phase timings and complete copyable reports. tronLoadingReport() returns the current report in Safari's console, including browser, viewport, navigation-to-app delay, maze setup, enemy placement, physics wait, model fetch/decode/adaptation, rendering-world creation, first render submission, opening readiness and deferred arena/player entry. Parallel model durations are labeled non-additive; first render submission is not a GPU completion measurement.
  • [x] With the temporary cycle-testing start enabled, begin loading the arena and launch its countdown automatically, without Return. Normal ?cycleStart=0 maze play still uses the opening terminal. Browser audio gesture restrictions may still require a click/key before sound can play.
  • [x] On player-cycle destruction, enter a movable spectator camera while the team match continues: WASD, Q/E, drag/arrows, Shift, Home and Space pause. Restore the follow camera and clear spectator inputs at the next automatic round. Victory or exhausted chances exits spectator mode so end screens are not blocked.
  • Collision timing and trail-ending changes were withdrawn after the user's correction; behavior remains unchanged.

Cycle camera stability — September 24

  • [x] Translate the follow camera and its look target with the exact visible cycle pose; smooth only the relative orbit and height. Easing absolute camera positions independently of fixed-step cycle movement caused vertical screen bob, amplified by turbo. Preserve eased turns and aerial changes, and clear the tracking anchor on reset.
  • [x] Add smoothed J/L left/right and I/K up/down spectator camera controls. Post-death WASD/QE movement uses 36 m/s with eased acceleration/deceleration; ordinary free inspection retains its existing speed.
  • Safari's supplied loading report isolates 19.442 seconds in initial simulation/enemy placement out of 20.849 seconds to opening readiness. Model loading is comparatively small; startup placement optimization remains outstanding.

Startup search acceleration and cycle glances — September 24

  • [x] Accelerate ground-route obstruction tests by stopping at the first wall hit when only a clear/blocked answer is needed. Preserve nearest-hit queries for projectiles and other callers. Reject triangle bounds conservatively, including the extended corners of padded acute triangles; skip stale A* entries instead of expanding them repeatedly.
  • [x] Hold J/L in cycle follow view for a fast, smooth 120-degree left/right rear-quarter glance. Release to return forward; both held cancel. The camera turns in place without steering the bike. Post-death spectator J/L remains free-camera steering.
  • [x] Shorten full player-cycle turbo capacity to five seconds; retain 2.5× speed, partial-charge use on I and 60-second recharge.
  • Local WebKit initial placement fell from the earlier 1,820 ms to 529 ms; opening readiness from 3,202 to 2,246 ms. Reload measured 506 ms placement / 2,146 ms opening. These are local Playwright WebKit measurements, not a new run of the user's actual Safari (previously 19,442 ms placement). Actual Safari confirmation remains pending.

Cycle motion and level-horizon glance refinement — September 24

  • [x] Run cycle matches at a 1/120-second fixed timestep; retain 1/60 second in tank mode. Catch-up budgets cover the same elapsed duration and render alpha follows the active step size.
  • [x] Interpolate live cycle poses and trail endpoints between simulation steps, with the follow camera using the same presentation pose. Preserve right-angle paths through corners and leave collision state untouched. Destroyed cycles use their collision pose immediately.
  • [x] Make J/L glances faster (28/s response), rotating around world-up to keep the horizon level. Release returns smoothly to forward view. No camera banking.
  • [x] Keep tank combat suspended during cycle matches and avoid starting the solar-sailer background load there. Retain the arena Recognizer patrol.
  • Actual Safari 26.6.2 user confirmation: initial placement 2,995 ms (previously 19,442); opening ready 4,463 ms (previously 20,849); arena ready 5,048 ms (previously 21,398), same reported 1262×1424 viewport / DPR 2 at startup.

Cycle pedals and repeatable materialization launch — September 24

  • [x] W is cycle turbo; S is a half-speed pedal. Both approach their targets with 8/s exponential response (about 0.38 seconds to 95%), including return to cruise and boost depletion. S takes priority when both are held, without spending turbo. Preserve five-second turbo capacity, 2.5× maximum speed and partial charge use. Engine pitch follows actual speed; tank controls are unchanged.
  • [x] Temporarily disable cycle win/loss endings via CYCLE_TESTING.endingsEnabled=false. Player death permits free-camera spectating; Return starts a fresh match immediately. Completed team matches wait for Return, with no attempt limit. The original ending rules remain available through the session setting.
  • [x] Replace the three-second countdown with a 0.3-second hidden-to-wireframe-to-solid materialization using the carrier's translucent scan panel/yellow border treatment, then launch immediately. Each bike owns reveal materials/uniforms; reset repeats the effect and disposal releases depth resources.
  • [x] Extract the materialization beat at 26.7–27.4 seconds from the supplied TRON light cycles video. Play one team cue during the reveal, with its sound tail continuing into launch; avoid stacking six identical copies. This is a picture-selected film-mix extract, not an isolated stem, and listening review remains pending. Keep the camera steady.

Breakable cycle arena enclosure — September 24

  • [x] A cycle striking intact arena enclosure dies and leaves a jagged, full-depth opening. Subsequent cycles can pass through beside the fallen cycle's persistent trail; trail collisions retain their separate timing.
  • [x] Subtract the opening from actual inner-wall, symbol and exterior-shell mesh triangles at runtime, preserving material groups and regenerating outlines. Add exposed fracture surfaces through the wall thickness. The original GLB stays unchanged; each new match restores its original geometry.
  • [x] Share the opening profile and dimensions between collision and presentation. Keep intact wall portions solid, store trail occupancy beyond the arena grid, and retain collisions with maze geometry outside. Escape continues into the outer world for now; no transition or JEV control is added.
  • [x] Perform mesh surgery only for new breaches, not every frame. Restore/dispose replacement geometry and exposed surfaces on restart/disposal.

Motorcycle handling after arena escape — September 25

  • [x] Once a cycle fully clears the enclosure, stop extending its trail and switch to continuous road handling outside. Arena reentry restores racing behavior as of September 26. Retain the existing trail and its collision/death lifetime. Preserve exit speed and displayed position; remove queued arena turns.
  • [x] Outside: W throttle, S brake (priority over throttle), A/D or arrows steer. Releasing throttle coasts with rolling/aerodynamic drag. Acceleration tapers with speed; braking can stop the bike without reversing. Speed-dependent steering limits lateral acceleration and the bike leans into turns, easing upright afterward. The follow camera remains level.
  • [x] Share interpolated road poses with the model and camera; engine pitch/Doppler use actual speed and heading. Replace the turbo meter with a km/h speed display outside. Retain swept wall, maze, trail and live-cycle body checks. Road riding continues when the arena match reaches a result; Return after death restores the original arena match.
  • Tunables live in ROAD_CYCLE: 18 m/s² nominal drive acceleration, 26 m/s² brake deceleration, 14 m/s² lateral acceleration limit, with drag and steering/lean response. These are an initial superbike-inspired approximation, awaiting driving-feel review.

Breach interior finish — September 25

  • [x] Apply the same arena styling adapter to exposed fracture surfaces: near-black wall faces and blue-gray edge outlines, including edges along the passage through the wall. Dispose both edge and face materials on rebuild/reset.
  • Crack shapes currently use one fixed authored jagged profile translated to each impact, not random generation. Collision clearance and the mesh cut share that profile.
  • [x] End the arena grid at the inner wall boundary; use a continuous dark teal floor through the wall thickness, visible in breach passages. Keep the existing outer-world ground beyond the enclosure.
  • [x] I/K also operate cycle turbo/slow alongside W/S, with slow taking priority. Outside the arena they also mirror throttle/brake. Spectator I/K camera controls remain available.
  • [x] Hide the sweeping rectangle and its border for cycle materialization only. Preserve the fast wireframe/solid reveal and the carrier materialization plate.

Film-inspired arena crack — September 25

  • [x] Replace the short opening with a tall, kinked central split and five tapered splinter branches radiating from the impact, based on the supplied film close-up. Retain the driveable base, dark passage and colored edge outlines. The authored pattern remains deterministic.
  • [x] Cut branches through the wall and remove buried lining faces where they intersect. Reject disjoint/coplanar polygons before subdivision to avoid duplicate geometry at shared profile boundaries.
  • [x] Remove spurious coplanar outline seams after fracture cuts: split collinear outline fragments at shared endpoints and cancel paired overlaps, preserving true silhouette/crease edges. This runs when geometry changes, not per frame.
  • [x] Temporary escape-testing setup: CYCLE_TESTING.startWithBreach opens the far wall straight ahead of the player’s starting lane in each player match, including Return restarts. Set it to false to restore intact starts.

Cycle escape testing and progressive steering — September 25

  • [x] Temporarily disable the middle opposing cycle in player matches via CYCLE_TESTING.hideMiddleOpponent, including its occupied starting cell; retain stable cycle IDs and restore other cycles normally on restart.
  • [x] Reuse the cycle shadow atlas for both the procedural arena floor and outer-world ground, preserving materialization clipping and cycle self-shadows.
  • [x] Road steering builds continuously with held A/D input. Full input takes approximately 0.6 × (1 + speed / 35 m/s) seconds; release eases upright. Apply this normalized demand to the speed-dependent cornering limit, avoiding immediate saturation of lean at high speed.
  • [x] Retain W/I turbo outside the arena with the same charge/recharge timings; it doubles drive acceleration and raises the speed ceiling from 100 to 140 m/s. S/K braking overrides turbo. Keep the charge bar, with speed also shown in its label; release coasts and recharges.

Outside-arena cycle impact damage — September 25

  • [x] Replace unconditional road collision death with normal-impact-speed response. Direct impact at 18 m/s (64.8 km/h) or accumulated health depletion destroys the cycle. Below 2 m/s normal speed, bumps do no damage; intermediate damage increases quadratically. These are gameplay tunables, not a real-world safety model.
  • [x] Nonfatal contacts retain 80% of tangential speed and bounce with 0.15 normal restitution; very small residual motion stops. Keep the bike at its last safe position and deflect its heading before the next swept step. Arena racing collisions retain their previous lethal behavior.
  • [x] Show remaining cycle health outside the arena. Initialize full health on escape/new match.

Low-speed cycle steering — September 25

  • [x] Blend low-speed kinematic steering (yaw rate = speed × tan(steering angle) / wheelbase) into the existing progressive cornering controller between 3 and 12 m/s. Low-speed input reaches full steering in 0.18 s; faster riding retains speed-dependent hold buildup. No pivoting at rest.
  • [x] Derive lean from actual lateral acceleration: atan(speed × yaw rate / gravity). This allows small-radius slow turns with modest banking, rather than imposing a fixed lean per key press. A simplified steady-turn approximation; it does not simulate rider countersteering, tire deformation or balance.
  • Research: Georgia Tech / GDOT, curve analysis, pp. 38–40 relates speed, radius and equilibrium lean. MSF Motorcycle Operator Manual distinguishes slow tight-turn rider counterbalancing. Input-response/blend thresholds are game tuning choices, not values taken from these sources.

Escape simulation handoff — September 25

  • [x] On player escape, pause arena competitors and match progression, stop their engine loops, and continue the player’s road handling. Existing destruction effects finish and expired trails release their collision cells.
  • [x] Resume carrier sensors, Recognizers, ground tanks, reinforcements, projectiles and hearing against the current cycle position/speed. Outside enemy damage feeds cycle health and the cycle explosion/spectator flow; no tank controller or beam/teleport objectives run. Allow enemy JEV requests and deferred solar-sailer loading again.
  • [x] Return restart clears the handoff and pauses outside combat while the next arena match runs.

Road reverse, orbit glances and wall clearance — September 25

  • [x] S/K brakes forward travel to zero, then accelerates slowly in reverse up to 3 m/s; release stops reverse motion. W/I brakes reverse motion before driving forward. Small unpowered residual speeds settle to zero, with no stationary steering pivot.
  • [x] J/L glances orbit around the cycle, keeping it in frame and the horizon level. Outside the arena the glance/return response is 4/s versus 28/s inside.
  • [x] Road cycle maze collision sweeps the authored perimeter segments with the cycle radius instead of expanding triangulation half-planes, avoiding oversized acute-corner wedges. Contacts permit movement away from a slightly overlapping wall boundary.

Looking into road turns — September 25

  • [x] Outside the arena, bias camera position and look-ahead toward the intended bend as steering builds (up to 36 degrees), smoothing with a 4/s response. Ease back on release, fade anticipation at walking pace/rest, and retain a level horizon with the cycle visible. Deliberate J/L glances take priority; aerial view does not add turn anticipation.

Road driving control revision — September 25

  • [x] Outside only: W/S taps change held target speed by 5 m/s (18 km/h); key repeat does not add steps. X held brakes and clears the target to zero. A fresh X press at rest latches 3 m/s reverse. W/S leave reverse (W sets 5 m/s forward, S stops). I remains held turbo. Arena controls remain unchanged.
  • [x] Smoothly approach target speed rather than applying full turbo whenever accelerating. Normal acceleration 8 m/s², turbo multiplier 1.6, normal/turbo ceilings 55/80 m/s. Roll-off drag increased; turbo release returns gradually toward the selected speed. These supersede the earlier road acceleration/maximum settings.
  • [x] At road speed derive turning rate from developing lean, so the visible bike and path respond together. Preserve quick low-speed steering and progressive hold input.
  • [x] V now uses Clu’s aerial height, trailing offset, transition blend and wheel zoom for cycles, replacing the separate 40 m overhead view.

Patrol recovery after player destruction — September 25

  • [x] Confirmed player destruction clears committed tactical attack/search routes, attack assignments, threat holds and hearing investigations. Recognizers finish any required stomp recovery and resume their normal patrol or escort behavior. Preserve visual confirmation and delayed, range-limited destruction reports.
  • [x] Return from cycle spectating clears old destruction reports and allows enemies to detect the next player again.
  • Validation: node --test tests/tactical.test.js tests/cycle-player.test.js tests/simulation.test.js — 83/83 passed. Covers stale tactical choices, road-cycle destruction/radio propagation, continued patrol simulation during spectating, and restart awareness. Node simulation checks only; no new browser or visual review.

Direct road-cycle testing start — September 25

  • [x] Temporary automatic cycle entry starts stationary, facing away from the arena, 20 m beyond its far outer wall. Road handling is active immediately; arena competitors stay paused. Return after death repeats this position with full health and turbo.
  • [x] Gate this shortcut through CYCLE_TESTING.startOutsideArena; set it false to restore the arena testing start. ?cycleStart=0 still preserves normal maze-first entry.
  • Validation: inline Node assertions using GameSession checked outside road mode, zero initial speed, maze-wall clearance, forward acceleration and repeatable Return restart. Browser driving-feel review remains pending.

Cycle tire contact with the floor — September 25

  • [x] Replace the fixed 8 cm cycle elevation with the actual supporting floor height and the repaired model's measured bottom. The arena floor is at +2 cm; outside ground is at −6 cm. Select by rendered position within the arena floor footprint so returning through a breach also restores the correct height.
  • Validation: node /tmp/tron-cycle-grounding.mjs in headless Chrome on local macOS verified model bottoms at +0.02/−0.06/+0.02 m for inside/outside/inside positions, checked the running game's outside player height, and rendered an inspected low-angle capture at /tmp/tron-cycle-grounding.png. Lean dynamics are unchanged.

Return to arena racing — September 26

  • [x] Once the whole road cycle clears the inner wall, restore cardinal turns, normal arena speed, W/I turbo, S/K slow, lethal arena collision rules and trail emission. Clear road lean/steering/reverse state and queued turns. Join the nearest cardinal lane over the first short span without teleporting the bike; sweep that span before reserving its collision cells.
  • [x] Start a separate trail section at reentry; preserve older trails without drawing a wall across the outside drive. Resume paused arena competitors and suspend the outside combat handoff. Repeated exits/reentries remain supported; reentry after a completed round reopens racing with a fresh round timer.
  • Validation: node --test tests/cycle-road.test.js tests/cycle-player.test.js tests/light-cycles.test.js tests/cycle-camera.test.js — 46/46 passed. node tests/cycle-reentry.mjs — headless Chrome on local macOS, 1280×800, passed actual breach traversal, restored keyboard controls and trail-render checks with no page errors. Inspected test-results/cycle-reentry.png. Manual driving-feel review remains pending.

Steadier player-cycle drone — September 26

  • [x] Remove the repeated opening swell from the player cabin sample by narrowing the existing 1:36–1:38 source selection to 1:36.7–1:37.8. Apply a 0.2-second equal-power seam overlap and circular, stereo-linked 100 ms RMS leveling; the finished loop is 0.9 seconds. Match the previous integrated loudness (RMS approximately 0.118) and version its URL to refresh cached audio. Preserve speed-related pitch and the separate external-cycle loop.
  • [x] Keep extraction reproducible through python3 scripts/extract-cycle-sfx.py; record processing and source/use constraints in public/audio/cycle-source.json and the sound catalog.
  • Validation: node tests/cycle-audio.mjs passed in headless Chrome on local macOS. Decoded cabin-loop level spread is 0.507 dB across 100 ms windows; stereo loading, event counts, pause/resume and reset cleanup passed with no sample/page errors. This measures playback and level stability; listening approval remains pending.

Remove recorded pitch wobble — September 26

Rejected in listening review: the user found the synthesized tone terrible and irritating. The September 26 rollback below supersedes this experiment.

  • [x] The volume-only correction above did not satisfy listening review: the recording still changed pitch at constant speed. Replace the cabin recording loop with stationary harmonic resynthesis from its averaged stereo spectrum, implemented in scripts/cycle_drone.py. Use fixed 367.5 Hz harmonics and exact 120-sample waveform periods, retaining source spectral balance, stereo differences and RMS 0.118. This is a synthesized approximation of the film timbre, not an isolated original engine stem.
  • [x] Loop whole waveform periods with no crossfade, and update the asset cache version. Speed-related playback pitch remains; player Doppler remains disabled.
  • Validation: node tests/cycle-audio.mjs passed in headless Chrome on local macOS. Every decoded waveform period matches exactly; 120 playback updates at constant player speed keep pitch at 1× despite listener motion. Level spread is 0.018 dB; loading, event counts and pause/reset cleanup pass. Listening review of the revised timbre remains pending.

Restore film cycle sound — September 26

  • [x] Remove harmonic resynthesis and restore the preceding film-derived cabin loop, retaining its seam crossfade and volume smoothing. Refresh the audio URL cache version. Frequency steadiness remains unresolved; do not treat objective periodicity as proof of acceptable sound.

Road tire traces and cycle dynamics window — September 26

  • [x] Outside the arena, leave a faint 13 cm rear-tire trace that fades over eight seconds of simulation time. Sample the rendered contact path every 45 cm into a bounded 8,192-segment pool. Marks follow the supporting floor, stop during arena racing/death, do not bridge teleports, clear on restart, and never affect collision. Pause freezes their age; disposal releases geometry/material resources.
  • [x] In development builds, Tab while controlling a cycle opens the Cycle dynamics window; Escape or Close returns to play. Pause while editing, preserve an existing pause, retain normal Tab navigation within the window, and isolate all game keyboard/mouse controls while it is open. Tank Tab retains the survey map.
  • [x] Expose road speed/acceleration/braking/drag, steering buildup and release, wheelbase, low-speed blending, cornering and lean limits, reverse, and contact response with labeled units, sliders and numeric fields. Keep Earth gravity fixed. Validate positive denominators and related thresholds before changing settings. Speed hold compensates drag; drag adjustments are most apparent under turbo.
  • [x] Own road settings per GameSession, retain them over restarts, and save valid changes locally in this browser. Provide Reset defaults and Copy settings. Arena dynamics remain separate. Defaults moved to src/game/cycle-road.js, with the existing simulation-module export retained for compatibility.
  • Validation: npm test — 337/337 passed; npm run build passed (existing large-chunk advisory). node tests/cycle-tuning.mjs — headless Chrome on local macOS, 1440×1000, passed tire-trace rendering, dialog opening/closing, input isolation, pause restoration, settings changes, reload persistence and defaults reset. Inspected test-results/cycle-tuning.png and the close driving-camera test-results/cycle-tire-traces.png. Driver preference for trace intensity and tuned handling remains subject to play review.

Tire trace attachment and transparency — September 26

  • [x] Replace the guessed 1.05 m rear-wheel offset with the repaired model's measured rear contact (approximately 1.23 m behind the origin). Transform that contact with the displayed bike pose, after applying its yaw and lean. Keep a live final segment attached between the 45 cm history samples; this removes the changing gap at the tire.
  • [x] Reduce peak opacity from 24% to 6%. Add derivative-based edge coverage with an expanded transparent envelope to reduce subpixel shimmer, and strengthen floor depth bias with a 15 mm surface offset. The live segment ages while stopped instead of refreshing forever; its buffers dispose with the history.
  • Validation: node --test tests/cycle-tuning.test.js tests/cycle-camera.test.js — 11/11 passed, including live endpoint placement between samples and fade at rest. node tests/cycle-tuning.mjs passed in headless Chrome on local macOS at 1440×1000; inspected the updated close driving-camera capture test-results/cycle-tire-traces.png. User confirmation of flicker on their display remains pending.

Road-bike performance and shorter enemy radio — September 26

  • [x] Profile live road riding versus post-death spectating. Browser CPU samples identify enemy route planning and wall-intersection queries as the dominant live-bike work. The whole outside enemy world had inherited the arena's 120 Hz step; the bike's isolated motion/collision cost was very small.
  • [x] Keep arena simulation at 120 Hz; restore the outside world's normal 60 Hz cadence. Road movement and swept collision retain their bounded 120 Hz internal substeps and shared render interpolation. Reentry restores the arena cadence.
  • [x] Wall queries copy only endpoint coordinates, rather than whole unit/search-node objects. Compute the world-space query bounds once, and stop on the first wall hit for boolean ground-clearance and line-of-sight checks. Nearest-hit projectile queries retain their behavior.
  • [x] At the user's additional request, halve enemy-to-enemy communication range from one maze width to half a maze width, including vertical separation. Use the shared radio-range configuration for aircraft, tanks, tactical allies, carrier reports and arrival synchronization; retain report delays and observation timestamps.
  • Validation: npm test — 339/339 passed. node tests/cycle-performance.mjs profiles headless Chrome on local macOS at 1280×800 with layout seed 1982. Approximately five-second live-bike samples: simulation CPU 1,572 ms before → 177.5 ms after the combined changes; median step 2.6 → 0.4 ms, p95 4.5 → 0.7 ms. Post-death CPU 639 → 216 ms. Both baseline and updated runs maintained roughly 60 fps locally; this measures CPU headroom, not an established user-device framerate gain. Final measurements ran without the test suite competing for CPU. JSON and CPU profiles are in test-results/cycle-performance.json and test-results/cycle-{alive,dead}.cpuprofile. User-browser confirmation remains pending.

Stronger road brakes and arena pedal isolation — September 26

  • [x] Double default road braking from 18 to 36 m/s² and downward held-speed response from 2 to 4 /s. Keep acceleration response separate. Expose braking response in Tab tuning. Upgrade previously saved default braking without replacing custom handling settings.
  • [x] Route W/S/X directly through cycle controls. Inside the arena, S/X/K request the existing half-speed minimum and override turbo; road braking and reverse commands are empty. Update the control hint. Ordinary arena wall/trail collisions remain lethal.
  • Validation: npm test — 342/342 passed, including twice-strength braking at low/high speeds, saved-default migration, and S/X arena survival. node tests/cycle-reentry.mjs passed in headless Chrome on local macOS at 1280×800: breach reentry, cardinal turn, turbo, S/X slowing and survival, and trail rendering. npm run build passed (existing large-chunk advisory). The originally reported S/X destruction was not reproduced; its specific cause remains unconfirmed.

Closer aerial zoom — September 26

  • [x] Halve V-mode's minimum zoom scale from 0.25 to 0.125, bringing the closest camera position twice as close to the vehicle. The shared wheel control applies to both tank and cycle aerial views.
  • Validation: node --test tests/cycle-camera.test.js passed. In-browser framing at the new closest distance has not been reviewed.

Local sighting response — September 26

  • [x] Reduce shared enemy radio radius from half to one quarter of the active maze width (about 334 m in the default blueprint world). This halves the previous range and reduces its horizontal coverage area to one quarter.
  • [x] Broadcast only firsthand sightings. Receiving a radio report still starts pursuit, but does not forward that report to another neighborhood. A recipient that independently spots Clu may broadcast its own sighting. Preserve report delays, timestamps and destruction notifications.
  • Chase size remains emergent: multiple direct observers and tightly grouped units can still respond together. No fixed pursuer cap is imposed. User play review of encounter density remains pending.
  • Validation: npm test — 343/343 passed, including 3D radio boundaries and a three-unit chain that stops at the firsthand observer's neighbors while allowing a new direct sighting to recruit locally. Updated the tank-radio fixture to place its receiver within the reduced range. npm run build passed with the existing large-chunk advisory. No browser encounter-density playtest performed.

Gentler low-speed cycle steering — September 26

  • [x] Reduce the road bike's low-speed steering limit from 0.65 to 0.45 radians. At full steering below the blend threshold, this widens the nominal turn radius from approximately 2.8 m to 4.3 m (about 36% less yaw rate at the same speed). Preserve input buildup and the high-speed steering branch; blend smoothly between 3 and 12 m/s.
  • [x] Upgrade the previous saved steering default so existing browser tuning receives the change; retain other customized values. The limit remains adjustable in Tab's Cycle dynamics window.
  • Validation: node --test tests/cycle-road.test.js tests/cycle-tuning.test.js passed, including the revised low-speed radius and continuity at both blend boundaries. Driving feel awaits user play review.

Home game selection — September 27

  • [x] Show Space Paranoids and Light Cycles on the home terminal using FilmTerminal, with a > beside the selected choice. Arrow keys select and Return starts; native buttons support mouse, touch, focus and keyboard activation. Update the displayed controls for the selected game.
  • [x] Default to Space Paranoids and wait at the menu. Space Paranoids starts the normal Clu maze/pursuit. Light Cycles enters the arena as gold player 1, with two gold teammates, all three blue opponents, and no initial wall breach. Preserve this setup when restarting a match.
  • [x] Keep the explicit ?cycleStart=1 road-testing shortcut separate from menu entry. Update road browser fixtures to request it explicitly. Ending terminals hide the menu.
  • Validation: npm test — 344/344 passed. node tests/home-menu.mjs passed in headless Chrome on local macOS at 1280×800 with touch enabled: home waits, arrow selection, Return, mouse click, touch tap, normal maze start, six-bike intact arena and match restart. Inspected test-results/home-menu.png with the terminal font and selection marker. Touch verification uses browser emulation, not physical mobile hardware. npm run build passed with the existing large-chunk advisory.

Plain ENCOM home terminal — September 27

  • [x] Replace the home access request with ENCOM SYSTEM, USER ACCESS GRANTED, and SELECT PROGRAM. Remove controls, navigation help, objective copy and project-notes link from the home screen.
  • [x] Match both choices to the terminal text's font size, line height and letter spacing. Remove boxes, padding and extra row spacing; retain the > selection indicator and keyboard/click/tap behavior.
  • [x] Show the Clu access request only after selecting Space Paranoids. Keep it visible briefly even with reduced motion, then enter the game without a camera transition in that mode. Returning home restores the ENCOM greeting.
  • Validation: node tests/home-menu.mjs passed in headless Chrome on local macOS, including matching computed typography, no button outline/border, removed help, the post-selection access message, keyboard/mouse/emulated-touch activation and both game starts. Inspected the updated 1280×800 home capture. npm run build passed with the existing large-chunk advisory.

Uppercase terminal typography — September 27

  • [x] Apply uppercase text presentation to the shared terminal content, including home choices, loading/access messages, victory and credits. Keep source strings and typing cadence unchanged.
  • Validation: shared terminal selector reviewed; git diff --check passed.

Program selection cursor — September 27

  • [x] Replace the > marker with the terminal's blinking block cursor beside the selected program. Arrow-key selection moves it between entries. Hide the heading cursor on the home screen; retain access and ending cursors. Honor reduced-motion preference with a steady selection cursor.
  • Validation: node tests/home-menu.mjs passed in headless Chrome on local macOS (reduced-motion mode), covering arrow selection, keyboard/mouse/emulated-touch activation and both game starts. git diff --check passed.

Typed Clu access and shared game font — September 27

  • [x] Space Paranoids prints its access message one glyph at a time with variable 45–145 ms keystroke spacing, extra space pauses and a longer carriage return. Retain the previous screen's top margin and opaque background. Hold the complete message for two seconds, then enter the Clu game. Inputs do not skip this sequence; simulation, enemy decisions and gameplay audio remain stopped during it.
  • [x] Use FilmTerminal for all game HUD text and controls, including paused screens, while retaining existing text sizes. Keep Light Cycles' direct start and the victory printer's uniform cadence.
  • Validation: npm test passed 344/344 before adding the new printer-specific check; node --test tests/victory.test.js then passed 3/3, including human timing, line-break pause and reset. node tests/home-menu.mjs passed in headless Chrome on local macOS: equal terminal top position, partial then complete text, at least two-second hold, frozen simulation time and computed FilmTerminal HUD font, plus keyboard/mouse/emulated-touch entry and intact six-bike arena restart.
  • npm run build passed with the existing large-chunk advisory; git diff --check passed.

Explicit uppercase program titles — September 27

  • [x] Correct the mixed-case menu titles shown in Safari: store SPACE PARANOIDS and LIGHT CYCLES directly in the markup and explicitly apply uppercase styling to the buttons rather than relying on inherited terminal styling.
  • Validation: confirmed both uppercase strings in index.html; git diff --check passed.

Access cursor and controls visibility — September 27

  • [x] Hide the program menu with display:none during access typing, preventing its selected cursor's explicit visibility from leaking through. Retain the single text cursor beside the access message.
  • [x] Keep the HUD hidden until the typed access screen and two-second hold finish. Only running gameplay reveals the control hint. This also prevents explicitly visible HUD children from appearing over the terminal.
  • [x] Apply FilmTerminal and uppercase directly throughout game/pause controls and both tuning panels, including native form controls.
  • Controls validation: node tests/home-menu.mjs passed in headless Chrome on local macOS, including exactly one visible cursor during typing, hidden HUD/control elements until gameplay, and computed uppercase FilmTerminal control labels. npm run build and git diff --check passed.

Clu cannon elevation limit — September 27

  • [x] Cap manual and mouse elevation at 45 degrees above horizontal. Exclude assisted intercepts requiring more than 45 degrees, and clamp assisted-shot spread to the same ceiling. Targets within the allowed elevation retain normal lead assistance.
  • Elevation validation: npm test passed 346/346; targeted gunner/mouse checks and production build passed. Regression coverage verifies manual 45-degree saturation, no overhead assisted lock, and retained assistance below the limit.

Teleporter pads disabled — September 27

  • [x] Disable pad creation in live simulation and presentation through TELEPORTERS.enabled=false. There are no active transfer volumes or rendered floor borders. Keep layout generation, transfer behavior and rendering implementation for possible future use.
  • [x] Skip floor shader injection for an empty pad layout. Existing isolated teleport tests explicitly supply pads so the retained implementation remains covered.
  • Teleporter removal validation: npm test passed 348/348, including pad-free normal runs and no floor shader modification for an empty layout. Retained teleport behavior passes with explicit test pads.

Credits dismissal — September 27

  • [x] Any fresh key press, mouse click or touch-generated click on victory or post-death credits returns to program selection. Consume the dismissal event so Return or a click cannot also start a game. Reset credit printing, music, input, simulation and ending state through the same path used by the automatic credits exit.
  • Credits validation: headless Chrome menu checks passed for keyboard, click and emulated-touch dismissal, returning to the greeting without starting a game.

Restore tank-camera opening — September 27

  • [x] After typed access and its two-second hold, restore the original 1.1-second terminal dissolve and 5.5-second camera approach to the tank. Keep controls hidden until the approach completes. Reduced-motion mode retains the direct transition after the hold.

Big-maze music footprint — September 27

  • [x] Use each maze instance's own basis and floor dimensions when detecting exploration. The previous shared small-maze footprint excluded most of the larger central labyrinth. Preserve pursuit priority and the existing beam music progression.
  • Validation: node --test tests/music-selection.test.js passed 7/7, including all four big-maze edge entries with outer mazes enabled and disabled, plus rejection just outside its boundary.
  • Music browser validation: node tests/maze-music.mjs passed in headless Chrome at the large labyrinth edge, then through exploration, hidden approach, visible beam, entry, afterglow and pursuit playback transitions.

Readable, incremental extended credits — September 27

  • [x] Preserve the existing left margin and set the credit column's right margin to match, including the mobile breakpoint. Wrap long text within that column.
  • [x] Append immutable glyphs and retain completed line nodes instead of replacing the entire credit text every frame. Reuse the victory printer's incremental rendering and line isolation. Clear nodes only when changing entries.
  • [x] Display one authored credit at a time. Use credits_display.txt for 27 concise entries, all five lines or fewer (below the requested eight-line limit). Keep URLs and the full dependency inventory in the unchanged archival credits_extended.txt; omit them on screen. Retain a two-line Cloudflare credit.
  • Validation: node --test tests/victory.test.js passed 5/5, covering entry boundaries, URL filtering, a brief Cloudflare mention, and line/length limits. node tests/extended-credits.mjs passed in headless Chrome on local macOS: complete credits progression, immutable retained glyphs with no removed nodes while typing, desktop/mobile equal margins and no horizontal overflow. The longest entry rendered within eight lines. Early/late mean append work measured about 0.018/0.017 ms per frame; this does not measure total GPU painting or establish performance on the user's device. Inspected test-results/extended-credits-layout.png.
  • Final browser verification: node tests/home-menu.mjs passed with the restored terminal fade and changing camera coordinates before gameplay controls appear, plus keyboard/click/tap credits dismissal and pad-free game state. npm run build passed with the existing large-chunk advisory; git diff --check passed.
  • Final simulation verification: npm test passed 351/351 when rerun without concurrent browser/build work. The earlier concurrent run failed one ground-tank patrol-distance assertion; no unrelated simulation code was changed for that retry.

ENCOM loading copy — September 27

  • [x] Replace LOADING with ENCOM REMOTE ACCESS, DIALING HOST, and AWAITING CARRIER. This is a text-only change; retain the existing terminal presentation and loading behavior.
  • Validation: reviewed loading markup; git diff --check passed.

Cycle lineups at their walls — September 27

  • [x] Start gold and blue lineups at the nearest safe grid row to their respective arena walls, facing inward. Derive the row from the inner wall position, bike length and a named minimum clearance rather than a fixed interior position. Apply on initial entry and round restarts; preserve the explicit outside-road test spawn.
  • Validation: node --test tests/cycle-player.test.js tests/light-cycles.test.js tests/cycle-road.test.js passed, covering round resets, arena movement/collisions and road transitions. Updated the collision fixture to assert displacement relative to its starting row.

Faster Clu access typing — September 27

  • [x] Halve Clu access keystroke delays, including space and line-break pauses, while retaining their natural variation. Preserve the two-second completed-text hold and subsequent camera opening.
  • Validation: node --test tests/victory.test.js passed 5/5, including the revised typing delays and unchanged victory printing.

Confirm Clu entry and start music with the opening — September 27

  • [x] Replace the automatic two-second access-screen countdown with an indefinite wait after typing. A fresh key press, click or tap starts the original terminal dissolve/camera approach; input during typing is consumed. Keep simulation frozen while waiting and prevent the confirming input from firing the cannon.
  • [x] Start music directly in that confirming user gesture and enable audio during the camera approach, rather than waiting until the approach ends. Do not restart music when the camera arrives. Preload the opening track during access typing, restoring it after terminal/credits music, and avoid reassigning an already-loaded initial track URL.
  • Clu-entry validation: node tests/home-menu.mjs passed in headless Chrome, including waiting beyond the old countdown with frozen simulation, key/tap/click confirmation, music playback during the camera approach and no forced restart at camera arrival. Production build and whitespace checks passed.

Clu aerial keyboard zoom — September 27

  • [x] While Clu uses V-mode aerial view, hold I to zoom in and K to zoom out continuously. Share the wheel's 0.125–4 scale limits through named zoom configuration. Preserve other modes and cycle pedal controls. Switch the displayed I/K hint from aim to zoom in Clu aerial view.
  • Validation: node tests/home-menu.mjs passed in headless Chrome, including I zooming in, K zooming out, updated aerial hint, and unchanged zoom when holding I outside V mode. npm run build and git diff --check passed.

J + L turret recenter shortcut — September 27

  • [x] Pressing J while holding L, or L while holding J, invokes the same center, level and lock action as F in the Clu game. Register both held keys so their steering inputs cancel during centering. Preserve cycle glance and free-camera controls. Update the control hint.
  • Keep the chord latched until both keys are released, so staggered releases do not cancel centering; clearing input also clears the latch. Browser verification passed in both key orders. Targeted gunner/refactoring tests passed, including staggered release followed by normal manual aiming. Production build passed before the final input-clear refactor, followed by targeted tests and git diff --check.

Beam completion returns to Clu victory — September 27

  • [x] Completing the central labyrinth beam now wins the Clu game rather than entering Light Cycles. Normal layouts without a central labyrinth retain the all-beams win condition. Arena asset readiness cannot delay the victory.
  • [x] Restrict cycle entry to explicit requests from the Light Cycles menu/testing path; preserve its gold-team lineup and independent restarts. Update cycle fixtures to enter explicitly.
  • Validation: npm test passed 353/353, including exactly one victory event after central-beam completion, no arena handoff/wait, and continued explicit cycle entry.

Charged cannon reserve and Recognizer behavior — September 27

  • [x] Start Clu with all three stored shots available. Recharge each spent slot in five seconds (previously ten), with continuous HUD fill; firing still resets the next slot's timer and pause freezes recharge. Chrome node tests/cannon-reserve.mjs verifies full startup, real key consumption, progressive fill, paused fill, and all three natural recharges.
  • [x] Show Recognizer searchlights only during search/investigation without a confirmed visible enemy. Patrol, pursuit and visible contact suppress even existing projector phases immediately; observation confirmation and information-limited aiming remain intact.
  • [x] Limit sideways/backward desired flight speed to half forward speed using a hull-relative elliptical envelope. Preserve momentum, bounded acceleration, and normal turning toward travel; expose both speed ratios in development tuning. Intercept travel estimates account for directional speed. Wider crossings can escape slower lateral correction; near-head-on interception remains covered.
  • [x] Beam-to-victory follow-up: Chrome node tests/home-menu.mjs and production build passed for direct victory without entering the cycle match.
  • [x] Validation: npm test passes all 355 tests, including directional flight speed, near-head-on interception, searchlight suppression and reserve timing; npm run build passes (existing chunk-size warning). Recognizer flight feel still needs human play review.

Continuous chase-camera zoom — September 27

  • [x] Holding I/K zooms Clu's normal chase camera in/out continuously as well as the V aerial camera. Chase zoom scales distance and height around the tank anchor from 0.5× to 4×, retaining wall clipping and smoothing. Each camera retains its own zoom across mode switches; resetting the view restores chase zoom.
  • [x] Preserve first-person gunner I/K elevation and cycle driving inputs; suppress chase zoom while paused or using free camera. Update the HUD hint for chase mode.
  • [x] Validation: 27 camera/gunner tests pass; Chrome node tests/home-menu.mjs verifies held I/K in both chase and aerial views, independent zoom settings, and preserved gunner elevation. npm run build passes with the existing chunk-size warning.

Installable Space Paranoids PWA — September 27

  • [x] Add a relative manifest scoped to the deployed game path, standalone launch, dark startup colors, and project-authored T icons (192/512 PNG, maskable, 180-pixel Apple touch icon, editable SVG). Keep the existing desktop keyboard/mouse gameplay.
  • [x] Generate a content-versioned production service worker and complete local game asset list during build. Cache 88 files / 48.8 MiB, including models and music, for offline starts after installation completes. Support audio byte ranges, exclude remote APIs and documentation, and scope cache cleanup to this game. Development does not register a worker.
  • [x] Wait for old game windows to close before activating a new release; never force-refresh a running game.
  • [x] Validation: production build passes. node tests/pwa.mjs passes in headless Chrome with a temporary persistent profile: no installability errors, correct subdirectory scope and PNG dimensions, offline Clu and light-cycle launches, ranged cached audio, and a waiting update while gameplay continues. Physical home-screen installation on iOS/Android remains untested.

Faster victory terminal — September 27

  • [x] Triple victory typing from 45 to 135 characters per second. Allow several characters per rendered frame so the speed is attainable at 60 Hz, with bounded catch-up after frame stalls. Clu access typing and credits retain their separate timing.
  • [x] Validation: node --test tests/victory.test.js passes all five tests, including two seconds of 60 Hz typing and a simulated two-second frame stall.

Matched terminal speed and model attribution — September 27

  • [x] Supersede the 135-character/second victory setting: win text now shares the extended credits' 18 ms per character timing (about 56 characters/second).
  • [x] Label each imported model artist's displayed credit explicitly as 3D MODEL or 3D MODELS. Remove adaptation/behavior wording from these pages so the credit clearly identifies the supplied artwork. Preserve full provenance in the archival credits.
  • [x] Validation: all five tests/victory.test.js checks pass, including shared typing speed and the eight-line credit limit.

Top-centered terminal text — September 28

  • [x] Center the first line of the home, loading and Clu access text horizontally, with a shared top margin of 12vh bounded to 64–140px. Keep subsequent lines and the program menu left-aligned under the first line; fixed character-width offsets prevent the typing animation from moving the text block. Existing victory and credit layouts retain their margins.
  • [x] Validation: Chrome node tests/home-menu.mjs passes. Inspected the 1280×800 menu capture: the first line is centered and the remaining text stays left-aligned below it.

BIT program integration and terminal correction — September 28

  • [x] Restore TRON home/loading/access text to its previous left-offset position and top margin. The top-centered request was intended for the separate Bit application; retain that layout only in the integrated Bit program.
  • [x] Copy the Bit project into public/bit, preserving its MIT license, legacy renderer, models, animation and sounds. Add BIT as the third program, with keyboard, mouse and tap selection. Escape unloads Bit and returns to the home menu.
  • [x] Remove obsolete copied code variants, the standalone server/TLS files, key-entry UI, duplicate font/logo assets and separate service worker. Reuse the host assets and PWA cache. Extend the shared budgeted Jev protocol with bounded yes/no/unsure questions; retain server-side credentials and quotas. The public worker requires its corresponding update when deploying.
  • [x] Use the existing ENCOM logo for all PWA icon sizes, with dark square backing and mask-safe padding; generate directly from the shared SVG source.
  • [x] Validation: all 357 simulation tests pass; Chrome tests/bit.mjs verifies keyboard/mouse/tap selection, rendered Bit, mocked yes/no/unsure responses and repeated Escape returns. tests/home-menu.mjs passes with restored terminal positioning. Production build and Worker dry-run pass; tests/pwa.mjs validates installability, icons, offline Bit entry/Escape, offline tank/cycle starts, audio ranges and waiting updates. Speech was mocked; live microphone/provider responses were not exercised.

Bit activation and microphone permission — September 28

  • [x] Add a blinking block cursor to the activation prompt. Query microphone permission silently on entry: granted permission launches Bit immediately; prompt/denied/unsupported permission queries show activation text and wait for a gesture. Keep the prompt hidden while checking to avoid a flash for returning users.
  • [x] Activation requests microphone permission before constructing Bit; release the temporary permission-check stream before speech recognition starts. Denial keeps Bit unlaunched with a clear retry instruction. Escape remains available throughout.
  • [x] Validation: Chrome tests/bit.mjs passes with mocked granted/prompt/denied/unsupported permission cases, deferred permission resolution, cursor visibility, track release, activation and Escape. Production build passes. No live microphone or paid provider calls were used.

Center Bit's changing heading — September 28

  • [x] Measure the current Bit instruction text instead of centering a fixed 12-character label. Recenter after heading changes, font loading and window resizing; keep question/answer lines at the same left edge.
  • [x] Validation: Chrome tests/bit.mjs passes, including centering within one pixel at 1280px and 390px widths for activation, running and permission-denied headings, with aligned following lines.

Bit exit hint — September 28

  • [x] Display ESCAPE KEY TO EXIT using the same responsive font size, line height, spacing and glow as the top instructions. Fade both together over 0.5 seconds when the first accepted spoken question hides the instructions.
  • [x] Validation: Chrome tests/bit.mjs passes, checking exact hint wording, equal computed font sizes and both elements fading to zero after simulated speech.

Bit hint and answer timing — September 28

  • [x] Hide the Escape hint until Bit launches, then fade it with the top instructions on the first accepted spoken question.
  • [x] Hold YES, NO, unsure and unavailable response text for two seconds, then fade over 0.5 seconds. Cancel the previous fade when a new question starts so an old timer cannot hide THINKING or a newer response; clear the timer on exit.
  • [x] Validation: production build and Chrome tests/bit.mjs pass. The browser check verifies hidden-before-start/visible-after-start hint behavior, each answer still opaque after 1.6 seconds and subsequently fading to zero, and the hint/instruction fade on simulated speech.

Light Cycles arena opening — September 28

  • [x] Cover the canvas with a black loading terminal while the arena loads, preventing the Clu tank scene from appearing when Light Cycles is selected.
  • [x] Add a 4.5-second smooth camera descent from 600 meters above and 680 meters behind the arena to the player's cycle view. Hold the race for the first 65% of the move, then begin the countdown/race as the camera approaches the cycle inside the arena. Suppress driving/view inputs and HUD during the move; Escape pauses and resumes the camera.
  • [x] Reduced-motion preference skips the descent. Explicit road-test entry keeps its existing immediate camera behavior.
  • [x] Validation: 28 cycle camera/player tests pass; Chrome tests/cycle-opening.mjs verifies loading coverage, hidden tank mesh, descending camera, held race time, pause/resume, race handoff and reduced-motion bypass. Inspected the arena approach capture. Production build passes.

Film-reference cycle entrance and sound — September 28

  • [x] Replace the earlier overhead zoom with a shallow approach, a bank over the rear arena rim, and a low grid arrival based on the supplied Enter Cycle Arena.m4v. Travel takes 13 seconds; the complete entrance lasts 20 seconds to accommodate the dialogue/transport/startup cues and a smooth handoff. Wall crossing stays above the 50 m rim; the race releases at 92% of the entrance.
  • [x] Extract “Prepare to transport to light cycle grid” and “We have transport” from the 5.1 center channel, plus stereo transport and cycle startup effects. Named cue times, local preloading, master mute, pause/resume offsets, reset/disposal, and suppression of duplicate materialization/launch cues keep playback tied to the entrance. Reduced-motion mode skips the cinematic and its timed audio.
  • [x] Validation: 30 camera/player/audio lifecycle unit checks pass, including wall clearance, exact camera handoff, and mid-cue pause/resume. Chrome entrance checks and rendered approach/bank/grid captures pass. Dialogue boundaries were located using local transcription; effects were selected against the film frames, not isolated production stems. Subjective sound balance remains for user audition.

Cycle entrance reference correction — September 28

  • [x] Re-read the supplied film clip frame by frame and replace forward flight with a backward, maze-facing descent over the west wall. Keep camera viewing direction independent of travel: reveal the broad ledge, drop past the decorated inner wall with a restrained bank, then turn across the grid and ease into the player's view. The existing arena placement already presents this wall to the labyrinth; no world rotation is required. Preserve the 20-second entrance, audio cues, pause/resume and reduced-motion bypass.
  • [x] Give the arena's horizontal crest surfaces the reference's muted blue-violet (#343548) while preserving the dark vertical faces and symbols. Apply in the presentation material so existing breach cuts and restores retain the treatment.
  • Validation: on local macOS, 33 camera/player/audio/breach unit checks pass. Headless Chrome node tests/cycle-opening.mjs passes for loading coverage, descent, frozen race, pause/resume including mid-dialogue, audio loading, race handoff and reduced-motion bypass. Inspected rim, bank and grid captures against extracted film frames. The reconstruction preserves the existing authored maze and arena geometry; subjective motion and sound review remains with the user.
  • Production build passes with the existing chunk-size advisory; git diff --check passes.

Recreate only the first sixteen seconds — September 28

  • [x] Supersede the previous entrance with a timed 00:00–00:16 camera study: retreat from the maze, descend along the wall while panning right and pitching down to 65 degrees, then accelerate across the floor and lift the view at the far staging area. Separate timed position, yaw and pitch tracks; remove aircraft roll and the invented blend toward the player during the film shot. Preserve the blue-violet wall crest.
  • [x] Hold the race throughout the sixteen-second shot. At its end, cut back to the existing gameplay camera; later film shots and player/cycle formation are outside this pass. Existing audio cues remain tied to elapsed time; the later startup cue lies outside this shorter shot.
  • Validation: 30 camera/player/audio unit checks pass, including wall clearance, steep downward pitch, rightward pan, accelerated traverse and the sixteen-second duration. Browser and rendered review results follow below.
  • Headless Chrome node tests/cycle-opening.mjs passes on local macOS, including pause/resume, held countdown, audio loading and reduced-motion bypass. Inspected 3/7/10.5/14-second captures; the 10.5-second view is dominated by the downward-facing grid and the arrival faces the opposite wall. Production build passes with the existing chunk-size advisory; whitespace checks pass. Film-motion fidelity still needs the user's review.

Cycle launch timing and continuous entrance — September 28

  • [x] Fix accelerated race startup: the fixed-step loop accumulated the entire cinematic hold and replayed it after release. Discard accumulated time when simulation is held, including holds triggered within a step. Preserve the normal 38.4 m/s cycle speed and turbo tuning.
  • [x] Remove the centered arena-loading wording; retain a plain black cover until assets are ready. Hide cycle control hints throughout the cinematic.
  • [x] Keep the sixteen-second reference study, rightward/downward pan and fast floor traverse, but spread forward travel through the turn instead of slowing almost to a stop before accelerating. Regression checks require continuous motion through the turn as well as faster travel across the grid.
  • Validation: 41 camera/player/audio/loop checks pass, including a sixteen-second hold followed by one second of real-time simulation and a hold triggered inside a simulation step. Browser and production results follow below.
  • Headless Chrome node tests/cycle-opening.mjs passes on local macOS, including normal simulation time versus wall-clock time after launch, hidden entrance hints, loading text removal, pause/resume and reduced-motion bypass. Inspected updated turn and downward-grid captures. Production build passes with the existing chunk-size advisory; git diff --check passes. Subjective motion matching remains for user review.

Wall clearance, overhead patrol and Recognizer face tints — September 28

  • [x] Correct the entrance's assumed wall height from 50 to the imported model's actual 60 meters. Raise the crossing, retain clearance over the wall's full thickness, and descend only after entering the arena. Check the swept camera path against the source GLB triangles.
  • [x] Move the arena patrol's initial position to the west ledge beneath the cinematic crossing, facing along the perimeter. Preserve autonomous patrol after the cinematic hold; the camera passes above its crown with clearance.
  • [x] Add a per-Recognizer tintColor override and createRecognizer(template, {tintColor}) presentation parameter. Default and arena-patrol colors have separate development-panel color pickers with black, green, blue and red presets. Arena patrol uses muted green; other units retain the original dark default. Only solid face materials change; trim and damage flashes remain independent, as do cloned vehicle materials. Tuning reset/export includes the colors.
  • Validation: headless Chrome on local macOS checked 960 swept camera segments against the actual arena GLB with no intersections, all four tint colors, unchanged trim and independent clone colors. Inspected the green patrol crossing capture. Final tests/build results follow below.
  • Final validation: 39 camera/player/patrol/audio tests pass, including full patrol traversal and camera-over-crown clearance. Chrome tests/cycle-opening.mjs also passes tint picker/preset/reset checks, verifies independent default and arena colors, and retains normal launch timing, pause/resume and reduced-motion coverage. Production build and whitespace checks pass (existing chunk-size advisory).

Compact ENCOM E app icon — September 28

  • [x] Replace the full ENCOM wordmark on the PWA icon with its E and wrapping curved outline. Adapt the existing SVG lettering and border into a square mark, preserving pale lavender strokes, dark backing and maskable padding. Keep the terminal's full wordmark intact.
  • [x] Store the editable mark in public/images/encom-app.svg; regenerate public/icons/icon.svg and the 180/192/512 PNG sizes with node scripts/generate-app-icons.mjs. Inspected the rendered 512-pixel icon in Chrome on local macOS.
  • Icon validation: production build and whitespace checks pass; verified PNG dimensions at 180, 192 and 512 pixels.

Match Light Cycles and Clu HUD typography — September 28

  • [x] Share one typography rule for Clu's control hints and Light Cycles' control/status text: 9 px, 1.8 line height and 0.6 px letter spacing. Replace Light Cycles' larger 11 px text. Both modes already share the same turbo indicator and FilmTerminal font.
  • Validation: reviewed the shared CSS rule; production build and whitespace results follow below.
  • Production build passes with the existing chunk-size advisory; git diff --check passes.

Terminal-sized resume prompt — September 28

  • [x] Replace the two-part STAND BY / ANY KEY TO RESUME pause text with only ANY KEY TO RESUME. Share the terminal's responsive font-size variable, typeface, line height and letter spacing. Keep the existing top-centered placement and resume behavior.
  • Validation: reviewed the markup and shared responsive CSS; production build and whitespace checks pass (existing chunk-size advisory).

Simplify initialization copy — September 28

  • [x] Remove AWAITING CARRIER from the initial loading terminal and attach the existing animated three dots directly to DIALING HOST. Preserve ENCOM REMOTE ACCESS and the cursor.
  • Validation: reviewed loading markup; production build and whitespace checks pass (existing chunk-size advisory).

Moving arena entrance patrol — September 28

  • [x] Advance the arena patrol at the fixed simulation timestep throughout the sixteen-second entrance while keeping cycle countdown, racers and tank combat held. Pause freezes the camera and patrol together; race release remains free of simulation catch-up.
  • [x] Start the green Recognizer already traveling south along the west ledge, toward screen-left in the maze-facing shot. Offset its initial position by three seconds of cruise travel so the camera still crosses above it. Continue the normal perimeter patrol afterward.
  • Validation: 40 camera/player/patrol tests pass, including moving-patrol crown clearance, patrol direction during the entrance, unchanged racer state and unchanged other enemies. Browser/build results follow below.
  • Moving-patrol browser validation: Chrome entrance checks pass, including leftward patrol movement while racers remain held and normal timing after release. Production build passed before the subsequent flight/HUD changes.

Forward cruise and slow Recognizer maneuvering — September 28

  • [x] Cap desired sideways and backward travel at a named 3 m/s maneuver speed. Preserve forward cruise, bounded acceleration and momentum through turns; do not snap existing velocity to the new limit. Expose the maneuver-speed cap in development tuning.
  • [x] At open-flight altitude, tactical navigation faces its travel direction. Retain wall-aligned hull orientation for low-speed corridor positioning. A wider lateral crossing can now escape; preserve head-on interception without restoring high-speed strafing.
  • Validation: 133 camera/player/patrol/tactical/simulation/interception tests pass. Updated previous half-cruise strafe expectations to the requested slow-maneuver behavior, retaining acceleration, obstacle clearance, head-on interception and continuous turn checks.

Solid carrier for Light Cycles — September 28

  • [x] Show the carrier fully materialized for explicit cycle entry and cycle play, including the arena entrance. Preserve Clu's carrier materialization.
  • Validation: Chrome entrance test confirms full solid opacity and hidden materialization panel during the opening; normal entry, moving patrol, pause/resume and race release still pass.

Terminal-sized gameplay text — September 28

  • [x] Supersede the previous 9 px hint-only match: all HUD text in Clu and Light Cycles now shares the terminal's responsive font-size variable. Include health/turbo/shot labels, hints, status/warnings, sight text, map text, pause prompt and development panels. Widen meter labels for the larger type.
  • Browser layout and production verification results follow below.
  • Final verification: headless Chrome tests/home-menu.mjs passes and confirms computed HUD/control font sizes match the terminal in both modes. Inspected desktop label/control captures; production build and whitespace checks pass with the existing chunk-size advisory. The earlier Chrome entrance run also verifies the solid carrier and moving patrol. Human flight-feel review remains pending.

Detectable PWA icon revisions — September 28

  • [x] Generate content-versioned icon filenames and update manifest, favicon and Apple touch icon URLs whenever artwork changes. Preserve the app's manifest identity, launch URL and scope. Keep stable icon copies for existing references. This fixes replacing icon bytes without changing the manifest's icon entries, which Chrome 144+ treats as unchanged.
  • Deployment and installed-device status remain unconfirmed: local updates alone cannot update an installation from the public site. Chrome may offer Review app update for identity changes. Reference: https://developer.chrome.com/blog/improvements-to-web-app-updates .

Automatic Clu entry after access typing — September 28

  • [x] Remove the confirmation wait after REQUEST ACCESS TO CLU PROGRAM finishes typing. Automatically start the existing dissolve/camera approach and music; reduced-motion mode enters directly. Keep the initial menu selection gesture and consume input during typing.
  • Update menu, offline PWA and cannon-reserve browser checks for automatic entry. Verification results follow below.

Exterior-to-aerial Clu zoom — September 28

  • [x] Make normal-view I/K zoom continuously from the existing exterior tank camera up to the same high aerial framing available in V mode. The closest setting is exactly the normal exterior distance and height; remove the previous closer-than-normal endpoint. Blend the look target down toward the tank as the camera rises instead of scaling a shallow chase angle. Preserve V as an aerial shortcut, gunner elevation, and cycle pedal controls.
  • Verification results follow below.
  • Automatic-entry and icon validation: Chrome home-menu checks pass, including no confirmation gesture and uninterrupted opening music. Production PWA checks pass with content-versioned icon URLs, correct dimensions, offline automatic Clu entry and waiting updates. Installed-device icon acceptance is unverified; installation URL/platform was requested but not supplied.
  • Zoom follow-up: V-mode zoom also reaches the normal exterior endpoint. Share the effective aerial blend with fog and floor presentation so zoomed-out terrain remains visible. Camera endpoint and gunner/cycle controls are covered by unit tests.

Assisted Recognizer targeting marker — September 28

  • [x] Display a red downward V above the crown of the Recognizer selected by Clu's upward assisted cannon solution. Use the same narrow-cone, obstruction and lead constraints as firing. Project the marker into screen space; hide it off-screen, behind walls, during manual gunner view, cycle play, pause/opening or after target loss/destruction.
  • [x] Use a small SVG graphic with no input handlers or GPU allocations. Reuse one projection vector; keep simulation targeting unchanged.
  • Verification results follow below.
  • Validation: 34 camera/gunner/marker tests pass, including visible assisted acquisition and rejection of blocked targets. Chrome tests/assist-marker.mjs passes acquisition, lost alignment, manual gunner and destroyed-target cases; inspected the red V capture. Reserved extra HUD space beside the wider meters. Production build and whitespace checks pass (existing chunk-size advisory).

One-second completed Clu access hold — September 28

  • [x] Hold the fully typed Clu access terminal for one second before its existing dissolve/camera approach. Continue automatically; no extra input is required, and input cannot shorten the hold. Apply the hold before reduced-motion entry too; reset its timer on a new session or return to program selection.
  • Installed-icon diagnosis: the local Chrome app is ~/Applications/Chrome Apps.localized/Space Paranoids.app, launching http://localhost:5173/. Its app.icns already contains the new E artwork; the Dock's ENCOM TERMINAL entry points to this same bundle. Restarted Dock to refresh its displayed icon. Use localhost when opening this installed app's origin; 127.0.0.1 is a separate origin.
  • Verification results follow below.

Subtler targeting chevron — September 28

  • [x] Compress the targeting V from 18 to 12 CSS pixels tall while retaining its 30-pixel width. Set overall marker opacity to 0.5, including glow; let the SVG stretch vertically so its width stays unchanged.
  • Validation: reviewed SVG sizing and CSS opacity; production build and whitespace checks pass. Chrome home-menu checks also pass with the one-second completed-access hold and automatic transition.

Smaller marker with acquisition flashes — September 28

  • [x] Halve the targeting V to 15 × 6 CSS pixels, retaining 0.5 steady opacity. A newly acquired Recognizer lock flashes three times at a 400 ms period, then holds steady. Losing the lock cancels the animation; acquiring a different target or reacquiring after loss starts a fresh sequence. Ordinary updates to the same lock do not restart it.
  • Use the browser animation timeline with named timing values; no timers or recurring callbacks are added.
  • Validation: Chrome tests/assist-marker.mjs passes exact 15 × 6 sizing, three on/off flashes, steady 0.5 opacity without retriggering, fresh flashes after reacquisition, and disappearance on manual gunner/destruction. Production build and whitespace checks pass with the existing chunk-size advisory.

Automatic Bit microphone request — September 28

  • [x] Selecting Bit now requests microphone access on entry without an extra activation key/click. Show REQUESTING MICROPHONE ACCESS while the browser prompt is pending; launch after approval and stop the temporary permission-check stream. Already-granted permission still launches directly.
  • [x] On denial, remain unlaunched and offer an explicit retry after microphone permission is enabled. Preserve Escape during pending permission and avoid launching after leaving. The browser's own permission prompt remains authoritative.
  • Update integration tests and README to describe automatic activation. Browser requests and speech remain mocked during verification.
  • Validation: Chrome tests/bit.mjs passes automatic entry, microphone approval/denial, temporary stream release, heading alignment, answers and Escape return. Production build and whitespace checks pass with the existing chunk-size advisory. No real microphone recording or paid provider requests were used.

Arena opening carrier and faster target flashes — September 28

  • [x] Stage the carrier beyond the maze on the right of the 16-second cycle entrance, using the supplied original-film still. Preserve model scale, expose the open bow on the right, and move along its heading. Keep this cinematic placement scoped to the opening; ordinary world transit resumes at the gameplay cut. Extend the cycle camera far plane to retain the distant ship.
  • [x] Double the targeting V blink rate: three 200 ms flashes (600 ms total), then steady at 0.5 opacity. Size and reacquisition behavior stay unchanged.
  • Validation: Chrome tests/assist-marker.mjs passes the exact 200 ms period, three flashes and steady state. Chrome tests/cycle-opening.mjs passes entrance, wall clearance, moving patrol, pause and gameplay handoff; inspected opening and carrier-angle captures. Full film-motion fidelity remains subject to visual review.

Gold-team formation and active Clu approach — September 28

  • [x] After the 16-second cycle camera move, hold its exact endpoint for a 2.75-second materialization of the three gold cycles, then cut immediately to the player's cycle view. Keep racers frozen throughout; skip the second countdown reveal. Use the actual gold starting row on the north side with 14.4-meter spacing, facing into the arena, and team-colored reveal lines. Reduced-motion entry keeps its existing shortcut.
  • [x] Use I/K to zoom in/out consistently inside and outside the arena, from normal cycle follow framing to the aerial range. Reserve T for turbo in both modes; retain W turbo and S/X slow in the arena, and W/S speed control plus X brake/reverse outside. Update control help and meter labels. This supersedes the earlier I/K speed aliases.
  • [x] Enable keyboard driving, turret and firing controls during Clu's camera approach, plus mouse firing. Start the approach at normal maximum forward speed with the same persistent cruise flag as Shift+W. Camera-mode selections can leave the approach immediately; terminal typing and its one-second hold still complete automatically before controls activate.
  • Validation: 33 camera/player simulation checks pass. Chrome entrance checks pass the stationary three-cycle formation, paused race, immediate handoff and I/K zoom. Further browser and build results follow.
  • Final validation: all 365 npm test checks pass. Chrome tests/home-menu.mjs verifies maximum-speed cruise, steering, turret movement and firing during Clu's approach; tests/cycle-player.mjs verifies the north-side start, turning, turbo and restart. Target marker and entrance browser checks pass. Production build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS; rendered carrier-angle, entrance and formation captures inspected. Human driving/sound and exact film fidelity still require review.
  • Commit review: newly staged imported Bit sources/assets retain upstream whitespace, which git diff --cached --check flags. The earlier whitespace check covered tracked edits; these vendor-format warnings do not affect the passing build/browser checks.

Close angled cycle formation — September 28

  • [x] Ease the final two seconds of the arena approach into a low, close view from the formation's right: 8 m right, 5 m forward, 1.6 m high, with a 38-degree vertical field of view. Hold that framing during materialization, then retain the immediate player-camera cut.
  • [x] Tighten the actual gold starting row to 4.8 m spacing so all three cycles compose a close group. Accelerate materialization by 50% (1.5× playback rate), reducing its duration from 2.75 to 1.833 seconds.
  • Validation: 34 camera/player tests pass; Chrome entrance check passes swept wall clearance, stationary three-cycle formation, paused race, camera handoff and zoom controls. Inspected the angled formation capture. Production build and whitespace checks pass; the existing chunk-size advisory remains. Chrome headless on macOS.

Progressive arena speed changes — September 28

  • [x] Slow the arena's speed response from 8/s to 2/s: turbo acceleration, S/X deceleration, and return to cruise now complete 95% of the requested speed change in about 1.5 seconds. Preserve top speeds, half-speed slowing, boost charge timings, and bounded collision substeps. Road riding already uses acceleration/braking limits.
  • Update movement checks to measure fractional cell progress during the gentler acceleration, and verify that both turbo and S remain partway through their speed changes after short key holds. Correct the road tuning help to show T for turbo.
  • Validation: 43 player, arena-race and road-dynamics tests pass. Chrome tests/cycle-player.mjs confirms gradual turbo/S response with real key events, plus charge, release, pause and restart. Its turning fixture clears the neighboring teammate's trail to isolate controls from the tighter formation's collision. Production build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS; final driving feel remains for hands-on review.

Clu camera clearance and continuous zoom return — September 28

  • [x] Apply camera collision constraints after approach/zoom/gunner positioning, including transitions that previously overwrote or bypassed the follow-camera wall check. Sweep between rendered positions against padded wall prisms, including roofs; slide along a safe axis when a direct move crosses a wall. Keep aerial ascent possible over intervening walls.
  • [x] Replace minimum-fraction camera clipping with a 5 cm contact margin and 1.2 m follow-camera clearance (20 cm in gunner mode). A long camera boom must not force the camera beyond a nearby wall. Free/reference cameras remain explicit inspection views.
  • [x] Keep encounter pitch tracking active throughout I/K zoom and blend overhead Recognizer framing continuously near the follow-camera end. Reaching minimum zoom no longer restores stale follow pitch or abruptly enables encounter framing.
  • Added deterministic wall-corner, roof, approach, aerial, gunner and minimum-zoom regression tests. Chrome home-menu checks pass active Clu entry and zoom controls; final wall/browser validation follows.

Two target flashes and less precise auto aim — September 28

  • [x] Flash the target V twice at the existing 200 ms period, then hold at 0.5 opacity until lock is lost.
  • [x] Increase locked auto-aim shot scatter to ±2.4 degrees horizontally and ±1.2 degrees vertically around the predicted intercept. Preserve seeded shot variation, existing lead/acquisition, level-shot behavior and exact manual gunner aim. Tests check the wider bounds and reproducibility.
  • Final validation: all 372 npm test checks pass. The long-range firing test now requires both hits and misses across deterministic assisted shots instead of assuming one shot always hits. Chrome tests/assist-marker.mjs verifies two flashes; tests/camera-walls.mjs records 389 clear rendered frames through actual maze-wall zoom/turn/gunner transitions. Production build and whitespace checks pass, with the existing chunk-size advisory. Chrome headless on macOS; final camera and shot feel still require human review.

Recover camera following after wall contact — September 28

  • [x] Fix the wall-avoidance dead end: axis-only moves toward the desired camera could leave it pinned while Clu kept driving. Detect stalled progress and enter a swept recovery path above the wall, then track the moving tank and return to normal follow as soon as the tank is visible. Recovery moves at a bounded 100 m/s and resets with the camera.
  • Add a moving-tank regression: start the camera stranded across a wall, drive Clu continuously at 22 m/s, and require clear camera sweeps, bounded separation and return to normal follow height. Extend the real-maze Chrome check to drive while zooming back in and verify the camera keeps up.
  • Validation: 40 camera/gunner tests pass, including recovery while Clu keeps driving. Chrome real-maze check passes 483 rendered frames of clear sweeps, driving during zoom return, bounded camera/tank separation and gunner transitions; inspected its final follow-view capture. The browser fixture now requires a clear 90 m driving lane so a tank-wall collision cannot invalidate the follow check. Production build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS; driving feel remains for user review.

Arena cycle camera clearance and front-facing patrol pass — September 28

  • [x] Apply final camera constraints and frame-to-frame sweeps to cycle follow, side glances, aerial zoom and arena entrance views. Include the arena's four 60 m wall prisms as well as maze walls, with independent collision geometry and the existing recovery path if blocked.
  • [x] Keep breach passages usable by subtracting openings derived from the authored breach profile. Test intact walls, roofs, breach passage, all four starting-wall sides, moving side glances and return from zoom.
  • [x] Start the arena patrol 24 m farther back along its existing route. Preserve its forward motion and green tint; the entrance camera now passes in front of the Recognizer instead of directly over its center, exposing its front.
  • Validation: 44 arena/cycle/camera/player tests pass, including padded wall clearance, roof crossing rejection, breach passage and front-facing patrol visibility. Chrome tests/cycle-opening.mjs passes entrance, patrol motion, formation, pause, handoff and zoom checks; inspected the rim flyby capture. Production build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS; final game feel remains for hands-on review.

Keep the wall-constrained camera out of the cycle — September 28

  • [x] Raise the cycle camera's collision anchor from bike-body height to 7 m, while retaining the normal unobstructed 4 m follow height. When the bike fits closer to the arena wall than the camera's padded volume, inset the anchor onto the arena side. Wall correction can shorten the horizontal boom without pulling the camera down into the cycle.
  • [x] As the boom shortens, blend the look point from forward driving focus toward the cycle itself, producing an overhead view with the bike still visible. Preserve the authored formation shot.
  • Regression tests park the cycle against all four walls and a corner, checking camera height, wall clearance and on-screen bike position through side glances. Browser reproduction uses the actual gold model at the closest legal wall placement.
  • Validation: 24 arena/cycle/camera tests pass. Chrome tests/arena-camera.mjs verifies clearance above the actual gold model during normal follow and both side glances; inspected the close-wall capture showing the complete cycle from above. Production build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS; final driving feel remains for hands-on review.

Formation materialization pacing — September 28

  • [x] Shorten the gold formation's wireframe sweep from 1.2 to 0.933 seconds and lengthen its solid fade from 0.233 to 0.5 seconds. Retain the initial 0.4-second opening and total 1.833-second hold before the player-camera cut. Give formation timing its own configuration while retaining other materialization defaults.
  • Validation: 13 cycle-camera tests and Chrome tests/cycle-opening.mjs pass, including the formation hold and race handoff. Production build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS; pacing remains for user review.

Restore gunner sight typography — September 28

  • [x] Restore the original monospace zoom label and sight-green color by exempting it from the global terminal color-font override. Keep its original 30 px SVG font size.
  • Validation: Chrome headless on macOS reports monospace, 30 px, and matching green text/fill (RGB 86, 214, 51) while playing.

JEV driving with player-controlled firing — September 28

  • [x] Shift-U toggles Clu autoplay with automatic firing disabled. JEV retains driving and turret aiming; Space and mouse firing remain player-owned. Shift-U switches full autoplay into manual-fire mode or turns manual-fire mode off. U retains its existing autoplay toggle.
  • [x] Show MANUAL FIRE in the autoplay HUD and describe Shift-U in its tooltip. Keep the firing restriction through pilot replanning and reset; disabling/re-enabling ordinary autoplay restores automatic firing.
  • Validation: 26 autoplay/input tests pass, including an aligned enemy that full autoplay fires at while manual-fire autoplay preserves movement/aiming but emits neither firing channel. Production build and whitespace checks pass (existing chunk-size advisory).
  • Chrome tests/autoplay.mjs passes Shift-U activation, full-to-manual mode switching, manual Space firing while driving, and disabling, plus existing autoplay lifecycle checks. Provider responses were mocked; no paid requests. Updated an existing text assertion to accept the uppercase HUD and waited for its render before checking the mode label. Chrome headless on macOS.

Soundtrack credits — September 28

  • [x] Add on-screen and archival music credits for Wendy Carlos (composer; gameplay excerpts from We've Got Company and Tower Music - Let Us Pray) and Journey (Only Solutions, ending/credits). Record artist/album source links in the archival credits.
  • Validation: Chrome headless on macOS tests/extended-credits.mjs passes the complete tribute-to-signoff sequence and eight-line page layout checks. Whitespace checks pass.

Cycle glance horizon at every zoom — September 28

  • [x] Keep the J/L orbit angle when blending into the I/K elevated view. During a glance, ease downward pitch to at most one quarter of the vertical field of view, leaving the horizon within frame. Release returns to the chosen zoom framing. Apply the look adjustment after collision correction without moving the camera through walls or into the cycle.
  • Validation: 25 camera tests pass across arena/road, both glance directions and zoom scales 1–128, including release recovery and tight-wall clearance. A deliberate glance now prioritizes the horizon over keeping the bike centered; ordinary close-wall follow retains its overhead bike framing. Production build passes (existing chunk-size advisory).
  • Chrome headless on macOS tests/arena-camera.mjs passes model clearance and real K/J zoomed-horizon checks; inspected the rendered horizon capture. The preview server stopped during the first capture attempt and was restarted before the successful run. Whitespace checks pass.

Consolidated validation — September 28

  • All 379 npm test checks pass before committing the camera, driving, targeting, manual-fire autoplay, credits and presentation changes. Updated the credits page-count bound for the two requested soundtrack pages and explicitly assert both music credits. Prior targeted Chrome checks and production build results are recorded above.

Trim the first second of cycle entry — September 28

  • [x] Begin the authored cycle entrance at 00:01, leaving 15 seconds of camera travel before formation. Keep camera, carrier and audio on the same authored clock; advance the arena patrol through the skipped second using bounded simulation steps. Preserve formation timing and reduced-motion entry.
  • Validation: 14 cycle-camera tests, Chrome tests/cycle-opening.mjs (including the 1-second starting offset, patrol, audio, pause and handoff), production build and whitespace checks pass. Chrome headless on macOS; existing build chunk-size advisory remains.

Shared BIT JEV relay configuration — September 29

  • [x] Confirm BIT uses the same /api/jev/decision relay, upstream JEV endpoint, model configuration and budget as Clu. Fix development config so BIT receives VITE_JEV_API_BASE just like the main client; production already embeds that shared setting. The config response contains only the public base URL. Light-cycle race opponents currently use their local planner.
  • Validation: 17 local/public relay tests pass, including BIT upstream/response compatibility, custom-base configuration and credential isolation. Chrome tests/bit.mjs passes replies, menu/exit and microphone-permission paths with mocked API responses; no paid requests. Production build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS.

Live BIT relay and character context — September 29

  • [x] Deploy the Worker separately from the website: the stale live protocol rejected BIT questions with HTTP 400. After deployment the same request returned HTTP 200.
  • [x] Supply explicit BIT identity facts and interpret second-person questions as addressed to the TRON character. Reserve UNSURE for unknown or non-binary questions instead of uncertainty about roleplay identity.
  • Validation: 17 relay tests and Worker dry run pass. Deployed Worker version 0fa10ec9-be17-4d31-8e14-30ac45073287; live Are you a bit? returned m0 (YES), confidence 1. This was a real provider request.

Smooth cycle formation handoff — September 29

  • [x] Replace the post-materialization camera cut with a 1.2-second eased move into player follow. Track the launching cycle, blend orientation and field of view, and lift the path over the bikes while retaining final wall constraints. Pause holds transition time; reset clears it.
  • Validation: 19 cycle/arena camera tests pass, including first-frame position/orientation/FOV continuity, bounded motion, pause and completion. Production build and whitespace checks pass (existing chunk-size advisory).
  • Chrome tests/cycle-opening.mjs passes the entrance, held formation, handoff and zoom controls. Inspected the midpoint capture after changing the aim blend to follow a moving look point with world-up orientation. Chrome headless on macOS; final motion feel remains for user review.

Confirm Escape before returning home — September 29

  • [x] Escape pauses Clu, Light Cycles and BIT and opens a shared modal with Continue Playing and Return Home. Continue receives initial focus; Escape cancels. Block gameplay keys behind the modal, preserve pause during tuning close, and reset game state on confirmed return. BIT suspends audio, listening, requests and rendering while the panel is open. Include the shared script in the offline cache through the existing BIT asset inventory.
  • Validation: Chrome tests/exit-confirm.mjs passes all three games, frozen simulation, input blocking, microphone pause, cancellation/resume and home navigation. tests/bit.mjs passes reply and microphone lifecycle checks with confirmed exit. Mocked provider requests; Chrome headless on macOS.

Keep the cycle forward view near walls — September 29

  • [x] When wall clipping would shorten the follow boom below 7 m, choose a clear 10 m lateral offset along the wall. Prefer the side nearest the previous camera, retain wall sweeps, and reduce look-ahead during this side view to keep the bike visible. Apply the same destination during the materialization handoff.
  • Validation: all 382 npm test checks pass. Tight-wall tests now require viewing distance and shallow downward pitch on all four sides and a corner. Chrome tests/arena-camera.mjs passes and its inspected capture shows the complete cycle with the forward arena visible. Production build passes (existing chunk-size advisory); final driving feel remains for user review.

Wall-connected starting trails and direct launch cut — September 29

  • [x] Seed each active arena cycle trail from the nearest inner arena wall at launch. Fill the intervening grid collision cells and preserve the wall endpoint as the first segment grows. Initial render trimming attaches the trail to the rear axle without losing the wall connection.
  • [x] Restore the fixed formation shot through materialization and direct cut to player follow at launch; remove the 1.2-second transition and its lift/field-of-view blend. Preserve the newer near-wall side view.
  • Validation: 382 full-suite checks passed, followed by 24 focused tests including the new starting-trail regression and direct-cut camera check. Production build and whitespace checks pass (existing chunk-size advisory).
  • Chrome tests/cycle-opening.mjs passes the held formation, launch handoff, audio and zoom checks; inspected its post-launch follow capture. Chrome headless on macOS.

Arena palette, carrier framing and launch hold — September 29

  • [x] Darken the green Recognizer face preset to #1c3825 (used by the arena patrol). Brighten arena purple symbols to #61249b with #9c6bbe outlines.
  • [x] Set the entrance carrier 800 m back along its heading while retaining its altitude, orientation and forward speed. Inspect its first frame at 1250×1000 to ensure the entire vessel fits.
  • [x] Hold the fixed formation shot for one second after materialization as the cycles launch. Release race simulation while retaining the shot, then cut directly to follow. The inspected late-hold capture shows gold trails with the bikes out of view.
  • Validation: all 383 npm test checks and production build pass (existing chunk-size advisory). Chrome entrance checks cover fixed camera during launch, moving race, patrol tint, pause, audio and handoff. Whitespace checks pass.

Follow surviving cycles after death — September 29

  • [x] Show the requested top-of-screen death message: CYCLE DETROYED - ARROW KEYS TO FOLLOW - ENTER TO RESTART. Replace automatic free-flight spectator entry with a surviving-cycle follow camera. Left/Right wrap through live cycles, skip destroyed cycles, and leave player identity unchanged. Select another survivor if the followed cycle dies; Enter retains match restart.
  • [x] Latest launch-hold tuning is 0.6 seconds, shortened in two requested 0.2-second steps.
  • Validation: 383 full-suite checks pass, followed by 16 camera tests including selected-survivor tracking. Chrome tests/cycle-follow-spectator.mjs passes message, both arrow directions, wraparound, target death and restart; inspected the rendered message. Build and whitespace checks pass (existing chunk-size advisory). Chrome headless on macOS.

Finite light-cycle trails — September 29

  • [x] Cap each cycle's trail at the arena's inner perimeter: 8 × 409.06 m = 3272.48 m. Advance the oldest endpoint as new wall appears, discard exhausted segments, preserve active-segment references, and release expired collision cells. Retain stripe placement as the tail recedes. Account for rear-wheel attachment, fractional movement and discontinuous arena reentry.
  • Validation: all 386 npm tests pass on the final run. The first full run had a crossing-Recognizer shooting failure; that test passed in the 69-test focused rerun and final full run. Production build passes with the existing chunk-size advisory. Chrome headless on macOS: tests/cycle-trail-limit.mjs verifies rendered length against the cap, reports no page errors, and produces an inspected aerial capture. Unit checks cover corner trimming, reclaimed cells, other cycles' ownership, active-segment remapping, fractional advance, death and reentry.

Cycle death overview — September 29

  • [x] After player-cycle death, smoothly pull up over three seconds to a fixed view above the nearest arena wall, aimed at the center. Rise clear of the wall before translating outward. Fit the full arena with an inset margin based on window aspect ratio. Left/Right still select surviving cycles to follow; Enter restarts.
  • Validation: 21 cycle/arena camera tests pass, including smooth initial motion, vertical wall clearance, full-arena framing at three aspect ratios, center aim and reset. Chrome headless on macOS: cycle-follow-spectator.mjs passes overview entry, survivor selection, wraparound, target death and restart; inspected cycle-death-overview.png. Production build passes with the existing chunk-size advisory.

Lower cycle death perch — September 29

  • [x] Replace the high, whole-arena overview with a fixed perch 6 m above the 60 m arena wall, at its inner edge. Retain the three-second pullback, completing the vertical rise before moving across the wall. Smoothly point at a surviving cycle and select another if it dies; use the arena center when none remain. Arrow keys still enter normal survivor-follow views.
  • Validation: 21 camera checks pass for bounded height, clearance during ascent, a fixed perch while tracking a moving survivor, replacement targets and reset. Chrome spectator lifecycle checks pass; inspected the lower perch capture. The original whole-arena framing requirement is superseded by this lower tracking view.

Shared cycle turbo and rechargeable arena brakes — September 29

  • [x] Give autonomous cycles use of their own turbo reserves: boost on clear arena straights, and brake when the lane ahead closes. Road agents can also use their existing turbo on clear routes. All arena cycles share the same gradual speed response and resource rules.
  • [x] Add a per-cycle arena brake reserve: five seconds of braking, sixty seconds to recharge fully when released, partial-charge reuse, and no repeated pulses when holding an empty brake. Brake requests take priority over turbo. Reset restores both reserves. Show S/X brake charge beneath the turbo meter using the terminal text scale. Road speed-hold controls retain their existing braking behavior.
  • Validation: all 389 npm tests pass, including autonomous turbo/brake use, empty-brake hold, release/recharge, partial reuse and reset. Chrome headless spectator lifecycle checks pass; inspected the additional brake HUD in the rendered capture.

Spectator resource meters — September 29

  • [x] Bind cycle HUD meters to the watched cycle: selected survivor in follow mode, or the survivor tracked from the wall perch. Turbo/brake fills and active states, road health and speed now use that same bike; ordinary play still uses the player bike.
  • Validation: Chrome headless on macOS, cycle-follow-spectator.mjs passes with distinct turbo/brake reserves per bike. Checks cover wall-perch meters, both arrow directions, wraparound, active-state changes, automatic replacement after target death and restart. Whitespace checks pass.

Partial-charge Clu turbo — September 29

  • [x] Allow Clu to trigger turbo whenever some reserve is available. Convert the recharged fraction into boost duration (25% gives 2.5 seconds), spend that available reserve and restart its recharge timer. Prevent stacking during an active boost; retain the existing ten-second full boost, sixty-second recharge timing, teleport/transfer restrictions and destruction reset.
  • Validation: 89 simulation, autoplay and ground-tank checks pass. Added coverage for empty charge, partial recharge, proportional duration, immediate reuse of newly available charge and tiny partial reserves. Existing full-duration, braking and destruction checks also pass.

Clu autoplay temporarily disabled — September 29

  • [x] Disable player autoplay through the application feature flag and an unavailable Autoplay instance. U, Shift-U and button activation cannot enable driving, aiming or firing assistance. Hide the autoplay button and Clu JEV statistics; retain the implementation for later reactivation. Enemy AI and the other programs retain their existing behavior.
  • [x] Track the three newly supplied film-reference clips with Git LFS, including the 194 MiB clip that exceeds normal GitHub file limits.
  • Validation: all 391 npm tests pass. Chrome headless on macOS: tests/autoplay.mjs verifies hidden/disabled UI, U and Shift-U, synthetic button activation, no player API requests and no page errors.

Clu keyboard zoom restricted to aerial mode — September 29

  • [x] I/K no longer changes Clu's normal following-camera distance. Only V aerial mode accepts keyboard zoom for Clu; hide the zoom hint outside that mode. Gunner aiming and light-cycle keyboard zoom retain their existing controls.
  • Validation: extend the Chrome autoplay-disabled check to exercise I and K in normal view, zoom out/in in V mode, and verify zoom remains unchanged after returning to normal view.

Home-screen credits — September 30

  • [x] Add CREDITS after BIT in the program menu, with the same keyboard selection and click behavior. Reuse the existing standard and extended credit sequence with terminal music, omitting the detached-from-Clu header. Any key or click returns to program selection.
  • Validation: Chrome headless on macOS, tests/home-credits.mjs passes keyboard and mouse entry, absence of the header, progression from standard to extended credits, and return/reentry. Inspected home-menu and credits captures; whitespace checks pass.

Clu menu naming — September 30

  • [x] Rename the home menu's SPACE PARANOIDS option to CLU. Replace the old masthead branding and home-link accessible name with ENCOM TERMINAL; the browser title and PWA names already use ENCOM TERMINAL.

Clu startup cruise cancellation — September 30

  • [x] Remove the separate startup-throttle override and use the same cruise latch as Shift-W. S/Down cancels cruise instead of temporarily overriding it, so releasing the brake does not resume forward acceleration. Plain W releases cruise; Shift-W enables it again.
  • Validation: 48 simulation/input checks pass. Chrome headless tests/cruise.mjs passes startup cruise, both brake keys, no forward reacceleration after release, Shift-W reenable and plain-W cancellation. Whitespace checks pass.

Quiet JEV fallback and scalable meters — September 30

  • [x] Restore JEV as the browser default, superseding older stored AI-mode preferences once (preference version 4). Keep manual Clu autoplay disabled. Log local/classic AI selection to the console instead of showing a persistent HUD warning. On JEV failure, show JEV unavailable for four seconds with a fading final portion; retain local fallback and suppress repeat notices during a continuous outage.
  • [x] Stack vehicle meters at the top left in a shared grid with font-relative widths, bar heights and row gaps. Wrapped labels grow their rows; position controls beside the stack on desktop and below on narrow screens.
  • Validation: Chrome headless tests/system-warnings.mjs passes default migration, simulated outage/fade, console-only local selection and non-overlapping meters in Clu and light cycles at enlarged font sizes. Inspected rendered captures. The crossing-target shooting regression now uses a fixed seed and asserts damage, since authored spread does not guarantee a lethal hit location.
  • Final verification: all 391 npm tests and production build pass; existing bundle-size advisory only.

Smaller vehicle meter labels — September 30

  • [x] Reduce Clu and light-cycle meter-label text to 80% of the terminal font size. Retain the existing meter widths, spacing and other HUD text sizes.

Restore meter position — September 30

  • [x] Return both games' vehicle meters to the top right, preserving the stacked spacing and 20% smaller labels. Reserve space for them on the right of the control hints.

Consistent smaller game text — September 30

  • [x] Use the meter-label size (80% of terminal text) for Clu and light-cycle HUDs, controls, notices, pause/exit prompts, camera help and tuning panels. Keep terminal/home/credits text at its existing size. Preserve the gunner typeface and colors. Meter and hint spacing share the game text scale.

C controls pause — September 30

  • [x] Replace C's free-camera shortcut with a controls panel that pauses Clu or light cycles. Show controls appropriate to Clu, arena cycles or outside-arena driving. Any fresh keypress, tap or click dismisses the panel and resumes; consume that event so it cannot fire, steer or open the exit panel. Update the in-game control hints.
  • Validation: Chrome headless tests/controls-help.mjs passes frozen simulation and resume via Space, Escape, C, mouse and touch in both games, with no leaked firing or exit prompt. Inspected the controls panel capture; whitespace checks pass.

Brief controls hint and reliable V transitions — September 30

  • [x] Replace automatic full control lists with a centered C / CONTROLS prompt for the first five seconds of active play. Keep loading/death/result messages and the C pause panel. Count from gameplay after the cycle introduction and exclude paused time.
  • [x] Release a stale follow-camera wall-recovery path when an aerial movement has a clear swept path. Ignore repeated V keydown events, and restore aerial scale when enabling V after zooming down to the follow-view limit.
  • Validation: all 29 camera checks pass, including a regression with an occluded tank, stale recovery and clear aerial movement. Browser controls coverage includes the timed hint and V key repeat behavior.

Grouped controls panels — September 30

  • [x] Remove the M mute shortcut and its control hint. Group Clu controls into Driving, Weapons, Camera and Game, and cycle controls into Driving, Camera, After Death and Game. Remove the final any-key/tap/click instruction while retaining that dismissal behavior.

Recover stale offline installations — September 30

  • [x] Add an uncached update.html entry that checks for a new worker, explicitly activates the downloaded update and returns to the game. This works even when an older worker serves cached entry HTML and its old registration code.
  • [x] Future clients activate waiting updates from terminal/home screens and reload after controller replacement. Preserve running games and credits until they return home; keep ordinary offline caching.
  • Validation: Chrome tests/pwa-update.mjs reproduces old cache-first HTML and a worker without update messaging, then verifies migration through update.html into the current playable game. Production build and whitespace checks pass.
  • PWA lifecycle verification also passes: offline Clu/cycles/BIT, audio ranges, installability, waiting during play, and applying the waiting update after returning home.

Credits navigation — September 30

  • [x] Space skips directly to the next credit page, including extended credits, resetting the current typing/fade state. Only Escape, Return/Enter, click or tap returns to the home screen; other keys are ignored. Ignore repeated keydown events.
  • Validation: Chrome tests/home-credits.mjs passes Space progression into extended credits, ignored unrelated keys, Escape/Return/numpad Enter exits and click/tap exits. Whitespace checks pass.

Teammate turbo discipline — September 30

  • [x] Teammates conserve turbo at launch and on uncontested straights. Use it with a clear lane when a live opposing cycle is nearby, in a neighboring lane and traveling in the same direction; release after establishing a lead. Use separate engage/release lead thresholds to avoid rapid toggling. Apply the same policy to teammate road driving; preserve player controls and opponent behavior.
  • Validation: all 49 cycle/player/road tests pass, including launch conservation, enemy use, a nearby rival, release after pulling ahead, and no boost for oncoming or destroyed rivals. Whitespace checks pass.

Terminal-style exit choices — September 30

  • [x] Use stacked, borderless choices in all three games' Escape confirmation panels, matching the home menu's blinking block cursor. Default to Continue Playing on every opening. Arrow keys, Tab and pointer focus move the selection; Enter/Space or click activates it, and Escape resumes. Respect reduced-motion preferences. Remove the panel fill and border so only the text and cursor appear over the dimmed game.
  • Validation: Chrome headless on macOS, node tests/exit-confirm.mjs passes Clu, cycles and BIT pause/resume, cursor selection and blink timing, keyboard navigation/confirmation and click return home. Inspected the Clu panel capture; syntax and whitespace checks pass.

JEV light-cycle maneuver selection — September 30

  • [x] Include autonomous arena cycles from both teams in the existing shared JEV scheduler and transport, excluding the human-controlled cycle. Rotate requests among eligible bikes with a four-second per-bike replan interval and existing global quotas, cancellation and fallback.
  • [x] Supply bounded, unobstructed cycle observations and clear corridor destinations in arena-local meters. A cycle-specific shared relay prompt selects a strategic destination; local steering rechecks cells and available space each crossing. Goals expire after six seconds; reject late, uncertain, dead/escaped or previous-round replies. Keep local turbo/brake rules, including teammate conservation. Outside-arena road driving retains its local controller.
  • Validation: all 398 npm test checks pass. Chrome headless on macOS, node tests/cycle-jev.mjs verifies mocked API requests, accepted arena decisions, human exclusion and paused scheduling. Unit checks cover round changes, visibility, stale replies, local fallback and blocked-cell overrides. Live-provider tactical quality remains unverified. Public deployment must include the updated Worker prompt alongside the client.

Social sharing preview — October 1

  • [x] Add static Open Graph and large-image Twitter Card metadata for the public TRON URL, with ENCOM TERMINAL title, game description and image alternative text. Use the user-supplied arena screenshot, converted without cropping to a 1080×720 JPEG for sharing compatibility (public/images/encom-social-preview.jpg). Source: user attachment encom-terminal-v0-uxv6f49c6ssh1.png.webp; supplied for this site's preview, no broader license asserted.
  • Validation: production build passes; built HTML contains both sharing-image tags and the large-image card type, and the built JPEG matches the source asset with verified 1080×720 dimensions. Platform-specific preview rendering remains controlled by each social service.

Encrypted repository credential — October 1

  • [x] Initialize git-crypt and encrypt credentials/** before adding the JEV key. Allow only credentials/Typesafe.txt through Git's ignore rules. Export an owner-readable recovery key outside the repository; document unlocking and secure backup. Keep Cloudflare production secrets independent.
  • [x] Ignore git-crypt ciphertext when loading a locked development checkout, retaining local fallback rather than sending encrypted bytes as an API credential. Preserve development-server file denial.
  • Validation: staged credential has the git-crypt header and contains no plaintext key; a separate temporary repository successfully unlocks the staged blob with the exported key. A locked server fixture reports JEV unconfigured. All 11 JEV tests and the production build pass. Prior history scan found no copy of this JEV key.

Meshy shuttle reconstruction trials — October 2

  • [x] Add a server-side Meshy generation/download script using ignored local credentials, persistent task IDs, reference hashes and explicit submissions. Download GLBs and previews locally; preserve the original and remeshed outputs for comparison.
  • [x] Try original four-view film input (carrier contamination), focused two-view input (incorrect closed shell), and tight detachment-only input (fragmented geometry). Three completed jobs used 105 credits total. Keep the existing default shuttle unchanged; comparison links are available in the model studio.
  • [ ] Produce a reference-faithful replacement shuttle. None of these Meshy outputs meets the supplied film references. Further generation needs clearer, isolated views or a different reconstruction approach.
  • Validation: macOS Chrome headless loads and exports the four-view and detachment-only models, including the original detachment mesh; six rendered angles captured and the reference-angle capture inspected for the detachment failure. Credentials remain ignored; no signed URLs or keys recorded in task manifests.

Shuttle smoothing and symmetry — October 2

  • [x] Use the two-view Meshy shuttle's user-accepted silhouette for cleanup. Smooth welded geometry, planarize broad panels, and mirror one quadrant across width and height. Use a neutral surface material to remove baked texture noise. Make this the default standalone shuttle preview and export a separate GLB, retaining raw trials.
  • Validation: Chrome on macOS captures six views and checks exact X/Y mirror correspondence for every mesh vertex plus GLB export. No extra Meshy credits used; small inferred surface details remain provisional.

Shuttle hard-surface correction — October 2

  • [x] Replace the rejected smoothing pass with explicit flat orthogonal panels. Quarter-circle front corners are the only curved or non-right-angle regions. Preserve width/height symmetry and straight detail strips; restore a clean green inset. Use this as the default studio model, preserving earlier comparisons.
  • Validation: geometry invariant test passes for X/Y world-space mirror correspondence and no angled faces outside front corners. Chrome renders six views and exports the 1,532-triangle GLB. Visual proportions still require user review.

Preserve shuttle structural details — October 2

  • [x] Supersede the oversimplified planar reconstruction with the detailed two-view Meshy source. Disable global smoothing and retain its material maps, ribs and recess geometry. Restrict planarization to tightly grouped near-axis-aligned surfaces and keep X/Y symmetry. Export a separate detailed GLB and make it the studio default.
  • Validation: Chrome six-view captures, symmetry checks and GLB export pass (38,008 triangles). Reference/top views inspected. Exact hard-surface reconstruction remains unresolved; do not claim the simplified panel model satisfies the reference.

Provider-balance-controlled public JEV usage — October 2

  • [x] At the user's request, set the public relay's shared daily request/input quotas and per-IP daily/minute quotas to explicit unlimited. Preserve request size validation, timeout, short pacing and concurrent-request controls; no cumulative site usage cap remains. Existing usage counters do not block requests under the new configuration. TypeSafe account balance and provider limits govern total usage.
  • Validation: all seven Worker tests pass, including requests succeeding with counters far above the former caps. Invalid settings still fail; explicitly configured numeric limits retain their semantics.

CLU variation, sound, shadows and victory cadence — October 2

  • Normal CLU starts now choose a fresh run seed so maze patrol tank/Recognizer placements vary. Opening pursuit Recognizers and carrier escorts retain their formation; explicit runSeed and reference runs remain repeatable.
  • Bullet surface-hit tones now use HRTF positioning at the impact point, with inverse distance attenuation (18 m reference distance). Mono source tones become directional stereo at the listener.
  • Maze shadows on vehicles use a 2048-pixel tile and four-tap bilinear depth-comparison filtering instead of unfiltered 1024-pixel tiles. Exact floor/wall shadow geometry is unchanged; atlas memory increases fourfold.
  • Victory typing retains the extended-credit 18 ms character interval, allowing 250 ms of catch-up so low frame rates no longer throttle it to two characters per frame. Human access typing retains its single-character limit. Text source: docs/victory.txt.
  • Validation: npm test passed 402 tests, including seeded patrol placement/formation preservation and victory cadence at 5–30 fps. Desktop Chrome: node tests/surface-audio.mjs verified left/right channel energy and distance attenuation; node tests/tank-wall-shadows.mjs produced inspected before/after tank captures without shader errors; node tests/wall-shadow-edges.mjs retained zero incorrect pixels in the exact wall fixture. Audible balance and the precise screenshot location still need user play review.

Extended-credit model previews and horizontal camera recovery — October 2

  • Extended model credits now show a locally rendered tank, Recognizer, carrier, Solar Sailer, grid cloud, light cycle, or authored shuttle beside the text. The transparent preview requires at least 260 pixels of free width and 220 pixels of height; narrow windows keep text only. Model fade-in begins with printing, and fade-out follows the credit's opacity. Space, return-home, resize and reset dispose obsolete model resources; the preview shares the existing frame loop and respects reduced motion.
  • CLU's normal follow camera now tries a swept horizontal detour around wall corners before rising. A bounded local path search covers 64 meters in each horizontal direction, with a 512-node budget; if it finds no route it retains the roof escape. Manual aerial, gunner and cycle cameras keep their existing behavior. Camera orientation continues tracking CLU throughout recovery.
  • Desktop Chrome: node tests/credit-models.mjs passed seven model loads, fade synchronization, narrow-window hiding, reset during loading, disposal, and actual home-menu credit navigation. Inspected model and in-game captures in test-results/credit-model-*.png. node tests/camera-walls.mjs passed 483 rendered frames without wall crossings. node --test tests/camera-collision.test.js passed 10 tests including constant-height two-corner recovery, following a moving tank, and upward fallback with no bounded horizontal route. Victory printer tests also passed.

Light-cycle wall connection — October 2

  • Rounded the upper edge of the 1.2 m bike-to-wall connection into a quarter-ellipse, dropping toward the rear tire as in the user's CycleWallCurve reference. Sixteen short sections resolve the curve; the tire cutout, floor contact, and long wall sheets remain intact.
  • Space is an additional cycle turbo key in arena and road modes; control help and meter labels include it. Braking still overrides turbo.
  • Validation: 15 light-cycle/tuning tests passed. Chrome node tests/cycle-wall-curve.mjs rendered the 16-section connection without shader errors; inspected test-results/cycle-wall-curve.png. The older tests/light-cycles.mjs timed out in its obsolete C/Home/Space entry sequence before reaching its rendering fixture; its match check was not claimed as passed.

Session-persistent arena damage and overlapping CLU opening — October 2

  • Arena breaches survive cycle-round retries and full game/home resets in the same GameSession. A new app session (page reload) starts with intact walls. Both visible fracture geometry and collision openings retain the damage; debug starting breaches are deduplicated.
  • Removed the opening camera's first-15-percent hold. Its zoom now begins with the terminal dissolve while preserving the one-second post-typing hold and 5.5-second approach.
  • Validation: arena/session regression covers repeated resets, collision passage and a fresh session. Chrome node tests/arena-breaches.mjs confirmed the mesh opening remains on the next round, adjacent wall geometry remains solid, and an explicitly fresh empty arena restores the wall. Camera regression verifies descent in the first 5% of the opening. Updated the former Space-no-turbo assertion for the newly requested Space binding.

CLU shot accuracy — October 2

  • Bullet spread now applies only to acquired auto-aim targets. Unassisted exterior shots and manual gunner/mouse aim stay precise. Removed unused unassisted spread settings; assisted spread values are unchanged.
  • Validation: 22 gunner/mouse-raycast tests passed, including exact unassisted headings over multiple shot seeds and retained assisted-shot variation.

BIT startup audio cache — October 2

  • Preload and decode both YES/NO recordings as BIT initializes, including while microphone permission is pending. Start listening only after startup loading settles; successful first replies use the same AudioBuffers as later replies. Removed redundant HTMLAudioElement loads and clear pending load entries so failed downloads can retry. Bluetooth microphone/output handoff timing is preserved.
  • Chrome node tests/bit-audio-cache.mjs held both cold sample requests, verified BIT did not begin listening early, then checked first and repeated playback started synchronously from the decoded cache without any further fetches. Each WAV was requested once.

Destructible light-cycle trails — October 2

  • Hitting another cycle's arena trail immediately removes 1.6 m of wall to either side along its path. The older portion gets an independent normal hold/flash/lower lifetime; the newer portion remains attached to its living owner. Gaps span turns, repeated impacts retain existing death deadlines, and erased segments release their occupied cells without erasing the newer wall or reconnecting it across a gap.
  • Per-segment destruction drives both rendering and collision expiry. Surviving cycle segment references remain valid after splitting/removal.
  • Validation: npm test passed 410 tests. node tests/cycle-trail-damage.mjs rendered initial gap, half-lowered older section and surviving newer wall without browser/shader errors; inspected the half-lowered capture. Regression covers impact through the simultaneous crossing path, gap dimensions, old/new collision lifetimes, corner cuts and repeated hits.

Trail retirement at the arena crack entrance — October 3

  • A cycle moving outward into an open crack stops emitting at the inner entrance, rather than waiting to reach the far side of the wall. Its existing trail starts the standard hold/flash/lower lifecycle without killing the cycle. Travel through the wall no longer leaves extra trail or occupied trail cells. Reentry enables a fresh trail.
  • Validation: 47 arena-breach, cycle-road, cycle-player and trail-damage tests passed, including an entrance test that keeps the rider alive, confirms no added trail through the wall, and verifies delayed normal expiry.
  • Browser node tests/cycle-reentry.mjs reached its braking check but failed its existing near-instant deceleration expectation (speedMultiplier < .51); the full browser scenario is not recorded as passing. The targeted simulation lifecycle checks above passed.

Cycle follow zoom horizon — October 3

  • [x] Keep I/K cycle follow zoom shallow enough to include the horizon and bike together. Pull the camera farther back as it rises, and cap downward pitch after wall avoidance. Preserve the V aerial perspective and existing side-glance framing.
  • [x] Validation: 22 camera unit tests passed, including zoom transitions in the arena and outside it. Chrome node tests/arena-camera.mjs passed wall clearance, forward zoom horizon and side-glance checks; the screenshot contained a black 3D scene despite passing camera-state assertions, so rendered appearance and human driving review remain unverified.

Large-maze tank density and update terminal — October 3

  • [x] Triple large labyrinth ground patrols from 8 to 24, distributed three per original broad spawn sector. Retain collision clearance, 30 m spacing, connected-corridor checks and seeded placement; smaller mazes and carrier escorts retain their counts.
  • [x] Style the standalone update page with the local FilmTerminal font, home-terminal colors, placement, glow, ENCOM logo and blinking return cursor. Relative asset URLs support the deployed subdirectory; narrow screens wrap text and reduced-motion disables blinking.
  • [x] Validation: 25 enemy-start/ground-tank/outer-maze tests passed. Chrome desktop capture inspected; font loading, background, logo and mobile overflow checks passed using /tmp/tron-update-preview.mjs. Gameplay performance with the increased tank count remains subject to human review.

Double-turret boss tank — October 3

  • [x] Add two bosses alongside the 24 regular large-maze patrols, starting on opposite sides of the central light beam with seeded, separated, connected spawn checks and information-limited AI. Use 12 health versus the regular 3; Clu shots deal 3 damage to boss armor, so four hits destroy it. Cap movement at 80% of normal enemy speed. Idle patrol destinations remain within the central courtyard, 100–230 m from the beam; bosses return there after combat pursuit.
  • [x] Adapt the supplied SpringSociety double-turret GLB without changing its proportions: black armor, cool highlights, painted red contour lines, ground silhouette, articulated upper assembly, recoil and two muzzle flashes. Fire a simultaneous pair from measured barrel tips on the existing enemy cadence, with clearance checks for both shots and rotating boss hit regions.
  • [x] Record embedded CC BY 4.0 provenance in model documentation and extended credits; add the styled model to its credit preview.
  • [x] Validation: 29 focused tests passed. Full suite initially passed 417/418; the sole failure expected the old eight-tank roster. Updated it for 24 regular tanks and reran all six blueprint tests successfully. Chrome node tests/boss-tank.mjs passed startup/roster and rotated muzzle alignment checks and captured the styled adapter. The initial full-entry browser wait timed out under software rendering; corrected smoke coverage checks CLU entry plus the isolated model. Human combat balance and hardware performance review remain pending.
  • [x] Courtyard follow-up: 14 boss/spawn/blueprint tests passed, including two distinct starts, 20 seconds of active court patrols, and movement confinement. Updated browser roster check for two bosses.

Separate shuttle and maze credits — October 4

  • [x] Split local shuttle modeling and maze/level work into separate extended-credit pages, preserving the note that blueprint artists are unidentified.
  • [x] Show a live, disposable 3D miniature of the central labyrinth beside the maze credit, built from the actual wall outlines and triangles. Use an elevated view to reveal the courtyard and corridors; preserve the existing synchronized fades, narrow-window hiding and resource cleanup. The shuttle retains its own model preview.
  • [x] Visually inspected the Chrome maze credit capture. All nine isolated browser preview/fade/lifecycle checks passed; the later home-screen credit navigation check timed out waiting for the tank page (tests/credit-models.mjs:36). Production build passed.

BIT credit preview — October 4

  • [x] Add the original neutral BIT OBJ beside ControllingTransmission's credit, with its lavender flat-shaded appearance, using the existing live preview and synchronized fade. Reuse the locally supplied MIT-licensed model; no new asset or attribution source.
  • [x] Chrome node tests/credit-models.mjs --previews-only passed all ten model previews, synchronized fades, narrow-screen hiding, pending-load cancellation and disposal. Inspected the BIT screenshot. This isolated run excludes the previously recorded full-game credit-navigation timeout.

Arena wall rider-view fallback — October 4

  • [x] Enter a forward rider-height POV within 16 m of an arena wall, returning to chase only beyond 24 m to prevent repeated switching. Smooth camera position and direction; hide the followed cycle's exterior during the transition so the camera cannot look through its own mesh. J/L glances keep the horizon level.
  • [x] Preserve manual I/K and V views. Clear the enclosure roof before zooming outward and return over the interior before lowering from an exterior aerial position. Do not apply the close-wall fallback to the film entrance or escaped road cycles.
  • [x] Validation: 24 camera tests passed, covering four walls, corners, moving/glancing cycles, zoom handoff, reset, and recovery from an embedded camera. Inspected Chrome rider-view capture at test-results/arena-camera-close-wall.png. Human driving review remains pending.

Above-cycle wall fallback — October 4 correction

  • [x] Replace the close-wall POV with a camera 3 m above the floor and up to 2.5 m behind the cycle, clamped inward at the arena boundary. Keep the bike visible and look slightly down/forward while retaining the horizon. Preserve the existing entry/exit thresholds and wall/zoom recovery.
  • [x] All 24 camera tests passed, including wall and corner clearance, zoom transitions and embedded-camera recovery.

Smooth cycle spectator selection — October 4

  • [x] Preserve follow/aerial zoom when arrow keys select a surviving cycle. Replace the camera snap and inter-cycle translation jump with a 1.2-second eased position/look transition toward the moving target; rapid selections restart from the displayed view. Retain wall constraints and close-wall framing.
  • [x] Validation: 25 cycle/arena camera tests passed, including rapid reversal, moving target, unchanged zoom and settled framing. Chrome node tests/cycle-follow-spectator.mjs passed arrow selection/wraparound, zoom preservation, survivor meters, automatic target replacement and restart.

Spectator rotation smoothing — October 4

  • [x] Interpolate the displayed camera quaternion toward the destination framing over the same eased 1.2-second switch. Keep orientation independent of interpolated look-at points, which can cross the camera and cause a sudden flip. Rapid selections begin at the current displayed orientation.
  • [x] All 26 camera tests passed, including bounded frame-to-frame rotation through an opposite-heading switch, eased first frame and rapid target reversal.

Cycle crash camera hold — October 4

  • [x] Hold the displayed camera position and orientation for three seconds after the player's cycle dies, before the existing overview zoom. Hold a followed survivor's crash view for the same duration before automatically selecting another living cycle and using the smooth spectator transition.
  • [x] Pause freezes the hold timer; arrow-key selection can skip the hold. Reset clears per-cycle hold history so subsequent games behave consistently.
  • [x] Validation: all 27 cycle/arena camera tests passed, including player death, followed survivor death, frozen position/orientation, pause and manual override.

Four central-beam bosses — October 4

  • [x] Increase the light-beam court guard from two boss tanks to four. Seed one start in each angular quarter of the courtyard, preserving minimum spacing, connected-floor checks, existing courtyard patrol behavior, health, paired fire and slower movement.
  • [x] Eight boss/spawn tests passed, including all four distinct starting sectors, spacing and 20 seconds of active courtyard patrols.

Credit preview framing and darker vehicle details — October 4

  • [x] Darken the Recognizer's credit-preview faces while preserving its red trim. Fit each model to the available space beside the complete credit text, with outer margins and clearance above the logo; enlarge the carrier and solar sailer previews.
  • [x] Ten credit previews passed Chrome/SwiftShader rendering, projected framing bounds, synchronized fade, narrow-window hiding, reset during loading and disposal checks (node tests/credit-models.mjs --previews-only). Inspected Recognizer, carrier and solar sailer captures.
  • [x] Dim the boss tank's red edge material from #a32619 to #76190f in the shared model adapter.

Credit vehicle surface fidelity — October 4

  • [x] Apply the game's existing cycle surface and wheel-hub repairs to the credit preview instead of displaying the uncorrected export.
  • [x] Load the carrier through its game adapter, preserving its hull treatment, panel seams and lights; reduce preview illumination to 15% for the darker in-game appearance. Other previews retain their lighting.

Shared reference-based Solar Sailer appearance — October 5

  • [x] Use the game Solar Sailer adapter in credits so both views share materials and details. Match docs/references/images/Solar Sailor/SolarSailerRef.jpg with dark blue hull surfaces, translucent blue-gray sails, pale illuminated rigging, colored navigation lamps and a white radial beam-coupling star. Replace the amber transit beam with a warm-white core and cool halo.
  • [x] Preserve each material's base opacity during transit fades so the sail fabric stays translucent at full visibility. Preview framing excludes the hidden source guide beam.
  • [x] Validation: two transit/beam timing tests and ten Chrome credit-preview checks passed. Chrome Solar Sailer fixture verified repeated-pass resource stability, reset, beam endpoints/fades, sail opacity, beam-coupling presence and resource disposal. Inspected game and credit renders; final film fidelity remains subject to visual review.

Solar Sailer full-sail mode and credit beam — October 5

  • [x] Add a translucent cruise state and a bright opaque full-sail state based on Sailor Full.png. After twelve seconds of cruise, fill the sails over three seconds while smoothly accelerating to four times cruise speed. Integrate the acceleration for continuous position; compute beam fade timing from the shorter transit duration.
  • [x] Credits use the same sail transition and include short white beam segments on both sides, with a cool halo and the existing coupling star. Fit the complete ship and beam inside the preview margins.
  • [x] Three simulation checks cover cruise speed, full-sail speed, continuous transition distance, exact transit endpoint, repetition and beam fades.

Hide unused shuttle credit — October 5

  • [x] Remove the unused carrier shuttle from the displayed and extended credits and remove its preview mapping. Preserve the model files for possible later use; the separate maze credit remains.

Screenshot shortcut — October 5

  • [x] Change screenshot capture from B/F9 to Shift+B and update the control hint. Preserve modifier exclusions and repeat protection.

Preserve rapid light-cycle input — October 5

  • [x] Replace the single pending keyboard turn with an ordered queue. Preserve two rapid taps delivered before the next simulation step, with a combined two-turn limit across keyboard and race queues to avoid a delayed backlog. Clear queued turns on reset.
  • [x] Cycle player and application refactoring tests passed, including rapid opposing taps, queue order/capacity and reset.
  • Remaining latency: arena turns are committed only at 4.8-meter cell boundaries (up to 125 ms at 38.4 m/s cruise, 250 ms at half-speed braking), plus frame scheduling. Removing this quantization requires a separate continuous-turn/collision design; this change fixes dropped taps, not the grid delay.

Immediate arena turns and deliberate AI reactions — October 5

  • [x] Remove grid-boundary turn scheduling for all arena cycles. Store continuous positions and apply player turns on the next 120 Hz simulation step; the 4.8-meter occupancy grid remains only a route-planning approximation. Preserve exact fractional trail corners.
  • [x] Sweep cycle discs against actual visible trail segments and their end caps; check moving cycle bodies simultaneously. Preserve trail damage, length limits, crash decay, wall breaches and road transitions. Road riders use exact trail geometry once the arena has continuous trails.
  • [x] Limit autonomous steering, turbo and brake decisions to one every 0.2 seconds. The player has no AI reaction delay.
  • [x] Slow arena turbo acceleration response from 2 to 1.4 per second (about 2.14 seconds to 95% of the requested speed change); retain top speed and brake response. Reduce road turbo acceleration multiplier from 1.6 to 1.3.
  • [x] Validation: all 433 simulation tests passed. Additional continuous-turn/road/breach/trail checks passed after road collision integration. Chrome 154 with SwiftShader verified a real keyboard turn at x=0.37, z=0.0966667 grid units: the emitted trail corner exactly matched the position at keydown; inspected rendered capture and no page errors. This verifies removal of grid waiting, not total input-to-display latency on users' hardware.

CLU killer follow shot — October 5

  • [x] Record the attacker ID on fatal enemy cannon hits and Recognizer stomps. If that enemy survives, hold the game view for four seconds before the existing terminal fade. Unknown/dead killers and cycle endings keep their previous timing.
  • [x] Ease camera position, orientation and field of view into CLU's normal follow offset around the living killer over two seconds, pointing at the enemy. Follow aircraft altitude; retain wall sweeps and lateral recovery. Pause freezes the shot, reset clears it, and losing the killer holds the last view.
  • [x] Unit validation covers fatal-shot/stomp attribution, missing/dead killers, cycle exclusion, camera easing, moving targets, aircraft altitude, pause/reset and wall-safe motion.

Remove premature cycle match timeout — October 5

  • [x] Remove the legacy two-minute match limit and its survivor-count winner selection. Matches continue while both teams have survivors and resolve only on team elimination. Rendering instance capacity is a separate setting, not a gameplay deadline.
  • [x] Nineteen cycle/race checks passed, including a regression across the former 120-second boundary and at 300/1800 seconds with unequal survivor counts; eliminating the final opponent still awards the round exactly once.
  • [x] Final validation: npm test passed all 440 tests and npm run build passed. node tests/clu-killer-view.mjs passed in headless Chrome on this Mac: the killer remained framed during the four-second hold, the terminal appeared after the existing fade (measured 4.9 seconds), and no page errors occurred. Inspected test-results/clu-killer-follow.png. Earlier forced-SwiftShader runs timed out during the typed opening; the normal-renderer run completed.

Cycle match result orbit — October 5

  • [x] Smoothly blend position, rotation and field of view over 2.5 seconds into the closest normal cycle camera distance (10 meters behind, 4 meters high), then continue a slow 0.16 radian/second orbit. Keep the orbit inside arena walls and preserve collision sweeps during the transition.
  • [x] Select the surviving player first, then the followed surviving winner, then another winner. Ties use the last crashed cycle's final position. Display GOLD/BLUE TEAM WINS or TIED MATCH! in the upper middle; Enter restarts using the existing match flow.
  • [x] Unit checks cover target priority, tie selection, smooth position/orientation, orbit distance, pause and reset.
  • [x] Validation: all 442 tests passed before the additional corner-orbit regression, and all three result-camera tests then passed. Production build passed. Headless Chrome on this Mac verified gold, blue and tied banners, a rendered close orbit, and Enter clearing the result on restart, with no page errors; inspected test-results/cycle-result-0.png. An initial synthetic crash omitted its coordinates and caused an audio error; the corrected browser fixture passed.

Darker blue cycle credit preview — October 5

  • [x] Give the credit model a deeper blue body and accent color, with preview lighting reduced to 75%. These settings belong to the credits preview adapter.
  • [x] Chrome preview checks passed for all nine models, fades, responsive hiding and disposal; visually inspected the darker cycle capture (test-results/credit-model-cycle.png).

Speed-responsive cycle follow camera — October 5

  • [x] Ease the following distance in proportion to actual cycle speed: 10 meters at arena cruise, 7.8 at full turbo and 10.8 at half-speed braking. Bound the distance scale to 0.78–1.16 with a 2.5/second response. Road riding uses actual speed relative to its configured cruise limit; spectators use their followed bike's speed.
  • [x] Retain existing zoom, horizon framing, wall avoidance, launch shots and result orbit. Camera state resets with the rig. Regression checks cover smooth acceleration/braking response, road speeds and spectator selection; the zoom comparison uses equal relative cruise speeds.
  • [x] Final verification: all 445 tests and the production build passed. Chrome measured cruise/turbo/braking camera distances of 10.000/7.800/10.800 meters, with no page errors; inspected the turbo capture. Credit preview and match-result browser checks also passed for this release.

Stable light-wall connection — October 5

  • [x] Fix the curved wall end jitter introduced by continuous arena motion: the bike was interpolated between simulation steps while the emitter used the latest un-interpolated trail endpoint. Carry the visible bike's path lag into presentation-only head trimming, keeping the curved boundary fixed at the rear axle without modifying collision trails.
  • [x] Regression checks cover all four headings, braking/cruise/turbo step distances, irregular render fractions and unchanged simulation state. The browser curve fixture also checks rear-axle alignment through interpolated turbo frames.
  • [x] All 446 tests and the production build passed. Chrome's rendered curve check passed with no browser errors; inspected test-results/cycle-wall-curve.png and verified fixed rear-axle alignment.

Remove embedded cycle lettering — October 5

  • [x] Remove the 29 separately named signature/date meshes from each loaded gold and blue bike before sizing and surface repair. Apply the same filter to the credits preview. Keep source GLBs and author attribution intact.
  • [x] Production build, Chrome curve preview and all nine credit-preview checks passed. Inspected the cleaned bike capture; no browser errors reported.

Random player cycle slot — October 5

  • [x] Draw uniformly from the three live gold cycles when entering a player match and on every round reset. Select before outside-arena placement so road starts also use the chosen bike. New browser games receive fresh run seeds; explicit runSeed URLs preserve reproducible comparisons.
  • [x] Update player-control fixtures to follow the assigned ID, keeping autonomous teammates distinct from the player. A 60-match seeded regression reaches all three gold slots reproducibly; Chrome verified Enter restarts across 15 matches selected slots 0, 1 and 2 without page errors.
  • [x] All 447 simulation tests and the production build passed.

Longer CLU ending shot — October 5

  • [x] Double the killer-camera hold from four to eight seconds and its smooth transition from two to four seconds. Retain the existing terminal fade after the shot.
  • [x] All 447 tests and the production build passed. Chrome verified the game view still showing at 6.8 seconds after death and the terminal appearing after the hold/fade (8.85 seconds measured from the captured death frame), with no page errors.

Level CLU shots against tanks — October 5

  • [x] Keep assisted tank-target aim at the muzzle's height, including its intercept calculation. Apply vertical shot spread only to recognizer elevation assistance; preserve horizontal assisted spread and exact manually aimed turret shots.
  • [x] Add repeated-shot checks against a ground tank in both follow and turret views, asserting zero vertical projectile velocity. Existing recognizer spread and manual-elevation checks remain active.
  • [x] All 448 tests and the production build passed.

Game-lit cycle credit preview — October 5

  • [x] Share the game's cool hemisphere/key/fill lights and ACES exposure with the light-cycle credit shot. Share the bike's roughness, metalness and reduced ambient response so the preview has the same directional highlights and dark shaded surfaces. Retain the requested darker blue preview colors.
  • [x] Other credit models retain their existing lighting and tone mapping; switch the lighting group with the active credit.
  • [x] Production build passed. Chrome rendered all nine credit models and passed fade/resizing/disposal checks; inspected the updated cycle credit capture. The in-game cycle camera/rendering browser check also passed without page errors.

Shallow maze wall damage — October 5

  • [x] Tank bullet impacts cut angular, recessed cavities into upright maze slab faces. Nearby repeated hits enlarge/deepen the same cavity; faceted dark interiors give depth, crossed seam lines are clipped, and a small burst of solid fragments flies outward and falls. Damage lasts for the current game and resets with the view/new game.
  • [x] Keep solid collision and navigation prisms unchanged. Protect wall edges, floor contacts and roofs; cap cavities at 96, simultaneous fragments at 84, and fragment lifetime at 2.8 seconds. This is shallow slab damage, not passable breaches or general destruction of decorative ledges.
  • [x] Reuse immutable wall data and cached caster bins. Only damaged faces need new projected shadow polygons; reset restores the original mesh/shadow resources. On this Mac, a three-hit CPU check measured wall rebuilds at 18.1/5.4/4.6 ms and shadow updates at 10.8/3.2/3.1 ms (before optimization, full shadow rebuilds were about 98 ms). These are local CPU measurements, not a hardware-wide performance guarantee.
  • [x] All 451 tests passed, including recessed geometry, repeated impacts, edge/debris bounds, pause, expiry and reset. Chrome verified real Space-key shots growing one cavity, fragment expiry and new-game cleanup; inspected impact and settled captures. Existing maze-shadow browser checks passed, including unchanged overlapping-shadow coverage. JEV 503 responses are deliberately stubbed in the browser fixture and excluded from renderer errors.
  • [x] Production build passed.

Blockier wall damage and releasable CLU turbo — October 6

  • [x] Replace radial crater outlines with uneven rectangular breaks and individually chipped corners. Offset and vary the recessed back face; eject block-shaped fragments.
  • [x] Releasing the last held forward key (W or Up) stops CLU's active turbo, returns unused charge to the reserve, and uses the existing smooth deceleration to the normal speed limit. Cruise-throttle selection remains intact.
  • [x] Targeted damage/turbo simulation checks passed, including charge preservation and smooth return to cruise.
  • [x] All 452 tests and the production build passed. Chrome verified repeated real shots, the blockier rendered recess, fragment expiry/reset, and W release cancelling turbo with reserve remaining; inspected the updated settled capture.

Slightly tighter recognizer auto aim — October 6

  • [x] Reduce CLU's recognizer auto-aim spread by 20% on both axes (maximum yaw ±1.92°, pitch ±0.96°). Keep tank-target horizontal spread and exact manual aiming unchanged.
  • [x] All 31 cannon/gunner tests and the production build passed.

Jagged hallway-wall fractures — October 6

  • [x] Follow the user's oblique hallway reference with staggered angular ledges and concave notches. Vary recessed vertex depths, darken the back faces, and brighten exposed fracture shelves. Initial depth is 1.05 m, bounded by cavity radius and the existing maximum.
  • [x] Triangulate concave back faces and clip decorative seams at every polygon crossing. Preserve solid gameplay collision and bounded, resettable damage resources.
  • [x] Four geometry/lifecycle tests passed, including a raycast sweep checking that concave breaks remain sealed. Chrome verified real shots, growth, debris expiry/reset and turbo release; inspected the game capture and a close oblique geometry render. Production build passed.

Geometric prism wall cuts — October 6

  • [x] Refine damage from the second supplied film reference: overlapping rotated squares and elongated hexagons cut straight into the wall, with independently chosen flat depths. Replace the continuous stepped/tapered outline with three bounded convex prism cuts per impact cluster.
  • [x] Subtract deeper cuts from shallower floors and expose only surviving side-wall intervals. Skip disjoint polygon subdivisions; preserve radius/depth limits, collision, shadow refresh, seam clipping and reset lifecycle.
  • [x] Four damage tests passed, including raycasts across overlapping cuts verifying the deepest floor is exposed without unintended holes. Chrome real-shot/growth/expiry/reset checks passed. Inspected the close oblique render; production build passed.
  • [x] Release verification: all 453 simulation/geometry tests passed before deploying the accumulated wall-damage, turbo-release and recognizer-spread changes.

Variable wall-damage size — October 6

  • [x] Assign each new damage cluster a reproducible uniform 1×–3× footprint scale (2× average), retained for subsequent growth and its maximum radius. Keep the existing depth limit and face-edge/neighbor clearance, which can constrain the footprint near boundaries.
  • [x] Five damage tests passed, including sampled range/mean and stable growth scaling; production build passed. No browser opened.

Gold-team result text — October 6

  • [x] Show GOLD TEAM WINS in gold (#ffd45c); clear the winner class for blue wins, ties and other game states. Production build passed.

Arcade victory palette cycling — October 6

  • [x] Cycle winner text through five discrete warm gold/orange/coral colors for gold and cool cyan/blue/violet colors for blue, repeating every 1.5 seconds with a matching subtle glow. Ties retain their neutral appearance. Reduced-motion preferences use steady team colors.

Restore steady victory text — October 6

  • [x] Revert victory palette cycling and its glow at the user's request. Gold wins retain steady gold (#ffd45c); blue wins and ties return to the original blue-gray text.

Smoother cycle self-shadows — October 6

  • [x] Increase each bike's shadow tile from 512 to 1024 pixels and use the existing 36-tap Gaussian edge filter instead of four-tap bilinear filtering. Keep shadow strength and depth bias unchanged; expose the cycle-specific settings in CYCLE_SELF_SHADOW.
  • [x] Headless Chrome rendered the actual gold model with game lighting before/after the change, with no WebGL/shader errors. Inspected close-up captures: fine jagged bands along the curved body and wheel covers are substantially smoother. Added a reproducible isolated model-render check. Broader hardware performance remains unmeasured; the atlas and filtering now cost more GPU memory/work.

Reversible rear-wheel refinement — October 6

  • [x] Preserve byte-identical copies of the gold, blue and red source GLBs and the pre-refinement surface adapter in docs/models/archive/pre-wheel-refinement. Original runtime GLBs also remain unchanged.
  • [x] First experiment replaces only the separate rear tire ring with a smooth revolved surface using its measured axial/radial profile. Keep original hubs, spokes, front wheel, body, materials and proportions. Apply the same adapter in game and credits; CYCLE_REAR_WHEEL.enabled and the loader's refineWheels option allow direct comparison/reversion.
  • [x] Inspect same-camera original/refined Chrome renders: rear ring circumference and opening are smoother. Keep the scope at one component for user review before extending to other parts.

Smooth inner wheel liners — October 6

  • [x] Replace the quantized outer band of the dark front/rear wheel inserts with smooth 128-segment open cylindrical liners. Preserve the inset faces, spokes and hubs; align their outer boundary to the measured circular opening. Apply in both game and credits, leaving archived originals untouched.
  • [x] Headless Chrome checked both team models, confirmed overall bounds stay within 1 cm of originals, and rendered without shader errors. Inspected the close-up to retain the visible spokes and openings.

Four-team cycle matches and team reactions — October 6

  • [x] First player match per app session remains gold versus blue, three bikes each. Each subsequent restart or arena entry draws 2–4 teams and 1–3 bikes per team from the seeded RNG. Gold remains the player team with a random occupied slot. Returning home preserves the match counter; a page reload starts the sequence over.
  • [x] Add red on the west wall and green on the east wall, facing inward. Gold/blue retain their opposite starting walls. All four sides start connected to their nearest wall; equal rosters cover all nine size combinations.
  • [x] Expand models, trails, live tire traces and explosions to twelve bikes/four teams. Recolor cloned materials on roster changes, hide unused bike slots, recognize every surviving team in victory detection, and name red/green winners correctly. Keep the six-tile high-resolution shadow budget by selecting the nearest visible bikes.
  • [x] AI reaction intervals: gold/blue 0.20 s, red 0.14 s, green 0.30 s. Player inputs remain immediate.
  • [x] All 458 tests passed, including roster variation, four-sided trail starts, session continuity, red/green wins and reaction timing. Headless Chrome verified all four-team roster sizes and new winner labels without WebGL errors. Inspected an isolated four-color model render; production build passed. Browser not opened interactively.

Straight rear spoke and smooth silver liner — October 6

  • [x] Replace the remaining quantized rear silver spoke with a tapered straight-edged mesh and smooth circular liner. Give its side faces a small clearance over the retained dark inset to avoid the inset masking its edge. Preserve archived source models and overall bike bounds.
  • [x] Headless Chrome validated both team-source adapters and rendered the new spoke without shader errors; inspected the close-up.

Immediate home-menu access tone — October 6

  • [x] Schedule CLU/cycle access feedback directly after audio unlock, before simulation and view reset, instead of at the end of startup. Permit the access oscillator to queue during context resume; ordinary terminal typing still waits for a running context. Request interactive audio latency. Hardware/Bluetooth output latency remains outside this scheduling fix.

Stable side panels and black reflective wheel rims — October 6

  • [x] Pin the authored flat side-panel vertices during surface repair so smoothing cannot pull the shared diagonal below the window out of plane. The diagonal line also appeared without self-shadowing; it is no longer visible in the corrected close-up.
  • [x] Separate the front wheel rim faces from the team-painted shell and derive smooth normals from welded geometry. Give both rims independent near-black standard materials (roughness 0.24, metalness 0.45), preserving their finish in game/credits lighting and team recoloring. Highlights are produced by scene lights; source GLBs and archived copies remain unchanged.

Remove overlapping gray cycle-panel faces — October 6

  • [x] Source inspection found partially overlapping coplanar triangles in the gray side plates, including overlaps between FrontColor and _LightGray_1. Keep those plates planar during smoothing and subtract already-covered areas across their meshes; retain unique surface area and interpolate original attributes. Apply the repair in game and credits without modifying source GLBs.
  • [x] Geometry regression confirms single ray intersections in overlapping and unique regions, unchanged union area and repeat-repair stability. Headless Chrome rendered both source-team adapters without WebGL errors; inspected the repaired close-up. Production build passed.

Broader cycle surface overlap repair — October 6

  • [x] Extend coplanar face subtraction beyond the gray side plates to all opaque authored cycle meshes, preserving unique coverage, winding, interpolated attributes, and separate parallel layers. Compare transformed planes so mesh placement is respected.
  • [x] Split the black rear wheel liner into end bands around the silver liner instead of rendering both at the same radius over the same span. Retain the black reflective outer rim finish and original GLB backups.
  • [x] Validate partial-overlap coverage and rotated/separated layers with geometry tests. Headless Chrome renders the game-lit model from four angles without WebGL errors; captures are in test-results/cycle-surface-{front,left,rear}.png and cycle-self-shadow-smooth.png. User play review of remaining shimmer is still needed; this does not claim to remove every shadow/silhouette aliasing artifact.

Correct wheel finish placement — October 6

  • [x] Restore team paint on outer wheel shells in the game and credits. Apply the black reflective finish only to inner wheel inserts and inward-facing rim surfaces, replacing light-colored inner liner highlights while preserving silver hubs and spokes. Reflections now come from scene lighting.
  • [x] Check gold/blue outer-wheel material preservation and render four views in headless Chrome. Original source GLBs remain unchanged.

Seal rear cycle body seams — October 7

  • [x] Rebuild both narrow rear body returns between the original upper and lower boundary rows, preserving the colored shell outline and preventing the underbody showing through mismatched triangles. Keep those boundary vertices fixed during smoothing; use the same repair in game and credits for both source-team models.
  • [x] Correct winding and normals on planar gray plates on both sides. A shadow-disabled render isolated the rear diagonal from shadow aliasing; reversed sliver faces were the cause. The corrected multi-angle close-ups no longer show that diagonal. Preserve separate curved parts, wheel colors and source GLBs.
  • [x] Add regression checks for outward gray plate winding, both rear returns, and sampled surface coverage along the repaired strips. Inspect headless Chrome game-lit captures from front, rear and both sides. Remaining quantization on other curved source details is not claimed eliminated.

Remove hub-to-tire highlight strips — October 7

  • [x] User-marked gray radial strips are fake reflections, not wheel spokes. Remove the front highlight faces and rear spoke replacement in both game and credits. Add smooth black wheel faces with a small clearance over the authored inserts so the removed strips cannot reveal holes or underlying paint. Preserve silver hubs and team-colored outer shells.
  • [x] Headless Chrome model checks and four-angle captures confirm the gray radial strips are gone; original GLBs remain preserved.

Polished black inner wheel faces — October 7

  • [x] Give smooth inner wheel faces and liners a physical black finish with roughness 0.08, metalness 0.5 and a smooth clearcoat (roughness 0.04). Preserve team-painted outer tires and silver hubs. Highlights are evaluated from scene lighting, without fixed gray highlight strips or added reflection graphics.
  • [x] Verify physical rim material values on both source models and render from four angles in headless Chrome without shader errors.

Unsupported mobile terminal — October 7

  • [x] Phones and tablets show “MOBILE TERMINALS NOT SUPPORTED” in the existing terminal style. Detect mobile browser identities, including iPads using desktop identity, rather than small window width or touchscreen presence alone.
  • [x] Stop before loading/constructing the game or registering its offline cache on unsupported devices. Keep the message readable in portrait and landscape; desktop startup and menus remain available.
  • [x] Validation: node tests/mobile-terminal.mjs passed in headless Chrome with iPhone 13, iPad Pro 11 and Pixel 7 emulation; none loaded game code or GLBs. A 600px desktop viewport retained the normal menu. Production build passed.

Prepare Light Cycles before the menu — October 7

  • [x] Move arena download, GLB decoding, cycle surface repair and arena attachment into the initial loading terminal before enabling program selection. Previously this work began on Return, even when the asset bytes were cached. Reuse the existing arena promise across game starts.
  • [x] Preserve the mobile early exit and loading-error handling. This shifts preparation into initial loading rather than claiming to eliminate its CPU cost.

Preload all program resources — October 7

  • [x] Prepare and decode CLU/cycle sound samples before the menu; warm all selected soundtrack files and the Solar Sailer alongside arena preparation. Audio playback still resumes from the user's gesture.
  • [x] Fetch BIT's document, local scripts, four OBJ models, yes/no WAV samples, font and logo into the browser HTTP cache without running BIT, opening its microphone or sending a JEV request. BIT still initializes its own page and audio context when selected.
  • [x] Headless Chrome confirms arena, audio/BIT resources and Solar Sailer finish before the home menu, and cycle selection causes no GLB downloads. Desktop initial loading carries the preparation cost; mobile still exits before loading the game.

Smooth front cycle wheel shell — October 7

  • [x] Preserve the current surface/seam adapters in docs/models/archive/pre-front-wheel-refinement/ before changing the front wheel. Source GLBs remain untouched; the new front wheel adapter has an explicit enable switch.
  • [x] Replace the front wheel's faceted colored shell with a symmetric revolved surface derived from its measured axial/radial profile, using 128 radial segments and 64 profile segments. Retain the body attachment geometry, team paint and polished black inner surfaces; use the same adapter in game and credits.
  • [x] Headless Chrome checks both source-team models, original versus refined bounds (within 1 cm), preserved rear seam coverage and rim materials, and renders front/rear/side views plus test-results/cycle-wheel-wireframe.png. The new wheel has regular curved topology; window-border geometry remains a separate follow-up.

Home selection fade — October 7

  • [x] Fade unselected menu text and logo for 825 ms, then immediately fade the selected label over the opening scene together with the dark background for 1100 ms. Both phases are scheduled before synchronous game setup so setup cannot postpone the selected-label animation. BIT preserves the original fade deadline across navigation. Home selections replace the intermediate access typing screen; non-home restart paths remain intact. BIT carries its label across document navigation. Reduced-motion users skip the fades.
  • [x] Headless desktop Chrome: node tests/home-transition.mjs passed for CLU, Light Cycles, Credits and BIT; checks animation ordering/durations and destination. npm run build passed. No deployment performed.

Distance-sensitive arena turn tracking — October 7

  • [x] Ease cycle heading independently of camera translation, zoom and deliberate glances. Keep the existing quick tracking within 12 m; progressively ease distant turns toward a 1.2/second heading response at 140 m. Use actual camera distance so wall-shortened views respond quickly. Applies to player and spectator follow views; road cycling, openings and survivor-switch transitions retain their existing behavior.
  • [x] node --test tests/cycle-camera.test.js tests/camera-collision.test.js passed, including near/middle/far turn comparisons and eventual heading convergence for player and spectator views. Visual driving feel remains subject to user review.

CLU turret contact and wall ramming — October 7

  • [x] Add measured pivot-to-muzzle collision probes and bounded sweeps for hull movement, hull yaw and turret rotation. Stop the barrel at solid maze faces while retaining safe tangential sliding and withdrawal. Collision geometry remains separate from the model.
  • [x] Emit the existing chipped-wall/debris effect for hull or turret impacts above 30 m/s normal contact speed, with a 0.6 s per-tank damage cooldown. A muzzle impact above 40 m/s and sufficiently aligned into the face embeds the barrel 0.45 m and locks the tank/turret. Hold reverse for 8 s to extract gradually; show a HUD recovery hint. Restart, destruction and teleport clear the jam.
  • [x] Damage remains a shallow visual cavity; this does not create traversable maze breaches. Thresholds, probe spacing, embedding and recovery values live in TURRET_CONTACT.
  • [x] Headless desktop Chrome: node tests/turret-wall.mjs passed a real maze-wall ram, damage creation, stationary lodged state, HUD notice and reverse extraction. Captures: test-results/turret-lodged.png, test-results/turret-freed.png. Inspected the lodged render. Focused simulation checks cover slow contact, rotation sweeps, damage cooldown, hard lodging, extraction, reset and hull damage.

Stable carrier shadows and darker maze shading — October 7

  • [x] Supply explicit flat wall receiver normals, including rebuilt damage geometry, instead of screen derivatives. Treat near-parallel light angles consistently and keep the receiver varying distinct from the shader's local normal variable. This avoids alternating triangular moving-shadow patches on grazing maze faces.
  • [x] Suppress static shadow casting between coplanar neighboring wall faces with different slab IDs, accounting for float32 rounding; reject degenerate light-parallel caster triangles.
  • [x] Increase maze shadow attenuation from 40% to 60%, and carrier attenuation from 50% to 65%. Retain filtered carrier edges, static geometric shadow unions, and readable ground grid lines.
  • [x] Headless Chrome: carrier shadow edge/ray comparison, moving-shadow occlusion, grazing-angle receiver and maze grid tests passed. Grazing fixtures at 0 and 7000 m have zero spurious dark pixels; light-facing fixtures still receive the carrier shadow. Damage-geometry tests passed. Original screenshot location remains subject to user confirmation.

CLU hull corner collision — October 7

  • [x] Measure the imported non-turret mesh: 6.5 m width and 9.373 m length. Replace CLU's circular wall contact with an oriented rectangular footprint enclosing those bounds with a small clearance. Sweep translation and hull rotation, retain tangent sliding/reverse, and route hard hull contacts through the wall-damage mechanic. Enemy hull behavior remains unchanged.
  • [x] node tests/tank-hull.mjs confirms every measured hull vertex is enclosed. Unit checks cover previously missed corners, multiple headings, large turbo displacements, rotation contact and sliding. npm test: all 473 checks passed.

Combined carrier/maze shadows and menu cursor — October 7

  • [x] Compose carrier shadows with the exact static maze wall/floor polygons using minimum light visibility. Apply a compensating multiplier on the static overlays instead of multiplying two shadow attenuations or cutting the carrier coverage with the coarse maze depth atlas on wall faces. Preserve receiver-plane filtering and vehicle occlusion.
  • [x] Headless Chrome: tests/carrier-shadow-union.mjs covers 18,635 static-shadow pixels under a carrier shadow with zero incorrect overlap pixels. Carrier edge/ray comparisons, maze/grid rendering and all four menu transitions pass without shader errors. Original gameplay location remains subject to user confirmation.
  • [x] Fade the selection cursor in the first 825 ms stage with the other menu text. Retain its layout space but carry only the selected program name into the 1100 ms scene fade, including BIT navigation.

Immediate mobile unsupported terminal — October 8

  • [x] Detect mobile devices in the initial HTML and show a static, inline-styled unsupported-terminal message immediately. Desktop-only styles load through the desktop bootstrap; the confirmation script is deferred. The warning uses a fallback font immediately and does not wait for JavaScript modules, CSS downloads or the terminal font.
  • [x] Headless Chrome device profiles: iPhone, iPad and Android show the warning without loading game models; a narrow desktop still reaches the menu. The warning also remains visible with every external script, stylesheet and font request blocked. Production HTML retains the inline detector/styles and has no render-blocking game stylesheet.

CLU cannon sound — October 8

  • [x] Use the supplied docs/references/sounds/clue fire.mp3 for player cannon fire at its original pitch and existing shot volume. Decode it during the normal startup preload, reuse the buffer for subsequent shots, and include the hashed asset in the PWA cache. Enemy cannons retain their existing sample; the old sample remains a fallback if the new file cannot decode.
  • Validation: headless Chrome decoded the stereo clip (0.532 seconds after MP3 padding), and two player shots reused that buffer without audio-load errors. npm run build passed and emitted the hashed MP3 into the offline cache. Listening balance remains subject to play review.

Restore terminal/game crossfade — October 8

  • [x] Hold the shared selected-label/background fade until the first visible game frame has rendered. Simulation reset and shader preparation can no longer consume the fade while the canvas is hidden, which previously produced a black interval and sudden scene appearance. Preserve the 825 ms other-text fade and full 1.1-second scene dissolve. CLU and cycles use scene readiness; credits and BIT retain their document transitions.
  • Validation: node tests/home-transition.mjs passed for all four menu choices, including a partially faded curtain over a visible game canvas for CLU and cycles. Inspected test-results/clu-terminal-crossfade.png: CLU label remains visible over the emerging maze.
  • [x] Blink the selected home-menu label off/on twice for 77 ms per phase near the end of its 1.1-second dissolve. Background fading remains continuous; game blinks share the first-frame readiness gate. BIT carries the blink frames through its document transition, and reduced-motion mode skips them.
  • [x] Place each cycle rear and initial light-wall endpoint exactly two cycle lengths (7.2 m) inside its starting arena wall, for all team counts and directions. Remove start-position grid rounding and update the materialization camera to the same formation location.
  • Validation: all 474 simulation tests passed, including all nine team/roster arrangements and updated entrance-camera endpoint checks.
  • Browser validation: tests/home-transition.mjs passed all four programs and the exact on/off/on/off/on blink sequence; tests/cycle-opening.mjs passed the full entrance, materialization, fixed launch shot, pause/resume, and camera handoff. Inspected the updated formation capture. Production build passed.

Overlapping menu/game fade and visible confirmation — October 9

  • [x] Begin preparing CLU/cycles immediately after selection, preserve copies of the home text above the scene, and start the background dissolve alongside the unselected-text fade after the first rendered frame. Keep the selected label on an independent layer so its blinks are not dimmed by a parent opacity.
  • [x] Use three off/on blinks at a 30% faster rate (99/1.3 ms per phase), followed by a 140 ms final text fade. BIT carries the separate background and label timelines across document navigation; reduced-motion mode skips the animation.
  • Validation: node tests/home-transition.mjs passed for CLU, cycles, credits, and BIT, checking the three on/off sequences and simultaneous partial background/text opacity over the visible game canvas. Inspected test-results/clu-terminal-crossfade.png. npm run build and git diff --check passed.

Immediate menu feedback — October 9

  • [x] Start the unselected-text and cursor fades on selection, independently of scene readiness, with a linear onset. Allow the browser to submit these animations before synchronous game setup. When the game frame is ready, consume any elapsed first-phase time rather than replaying the text fade; preserve three bright final label blinks and the background dissolve.
  • Validation: the browser regression checks text opacity falls while scene readiness is deliberately withheld, then exercises CLU, cycles, credits, and BIT transitions.

Synchronized immediate menu reveal — October 9

  • [x] Reveal the existing rendered game canvas beneath the home screen and fade its black covering layer with the same 825 ms linear timing as the unselected text. These two animations start immediately; only the selected label waits for game readiness before its final three blinks. BIT navigation starts after the background fade completes.
  • [x] Record improving outside-arena cycle driving dynamics in TODO.md.

CLU opening camera during menu dissolve — October 9

  • [x] Start CLU's prepared opening before the first dissolve frame, reuse the fresh home-screen simulation instead of rebuilding it on Return, and warm the opening's rendering during loading. Generate fresh random patrol seeds during initial loading and return to the menu; explicit comparison seeds remain reproducible.
  • Validation: node tests/home-transition.mjs passed in headless desktop Chrome at 1280×800 for CLU, light cycles, credits, and BIT. The regression now records camera positions during partial background opacity and verifies that CLU's opening camera moves while the game fades in, in addition to checking the three selected-label blinks.

Light-cycle menu scene isolation — October 9

  • [x] Keep the background cover opaque when selecting light cycles until the first arena frame has rendered, then dissolve it and the unselected text together over 825 ms. Reuse the fresh home simulation and begin cycle setup without an extra frame delay. The selected label retains its three blinks. This prevents the home screen's CLU preview from appearing before the arena while keeping the scene reveal synchronized with the text.
  • Validation: headless Chrome regression covers delayed scene readiness, checks matching text/background opacity across multiple arena reveal frames, and checks that every revealed frame during light-cycle entry belongs to the cycle game; CLU's moving-camera fade and the credits/BIT transitions also pass.

MCP conversation terminal — October 9

  • [x] Add MCP to the home menu, with a separate conversation page showing the supplied film image. Animate mouth/jaw and attached wireframe during speech, respect reduced motion, and provide typed input alongside speech recognition and browser TTS.
  • [x] Add bounded conversational history and a server-only, OpenAI-compatible chat relay for Vite and the production Worker. Preserve origin checks and Worker budget checks. Leave provider configuration explicit; JEV cannot generate free-form dialogue.
  • [ ] Configure the user's chosen chat provider and verify a real microphone → model → spoken reply session. The current browser checks mock these external interfaces; voice character and animation fidelity remain subject to user review.
  • Validation: node --test tests/mcp.test.js tests/worker.test.js passed (10 tests). node tests/mcp.mjs passed the mocked speech/chat loop, history, stop, exit and unavailable-service recovery. Inspected the 1280×800 headless Chrome speaking capture against the supplied still and video frames. No deployment performed.

MCP voice cloning and deferred model cache — October 9

  • [x] Extract a reproducible MCP-only reference from the user's film clip and generate new dialogue using pinned Chatterbox weights. Add a saved audition and live voice test independent of chat-provider configuration.
  • [x] Begin the model download only when entering MCP. Run inference in a WebGPU worker and cache model files atomically in bounded records in IndexedDB, separate from game/PWA updates. Stop/exit cancels worker activity and playback. Drive jaw animation from synthesized audio amplitude.
  • IndexedDB validation: node tests/mcp-voice.mjs --local-models passed in headless Chrome on macOS with WebGPU. Stored 14 files (1,526,346,349 bytes), generated and played new speech, then reloaded successfully with no model-weight downloads (two optional missing-file probes remain). A local fixture supplied the pinned weights to isolate persistence from remote transfer failures. Relay unit tests passed 10 tests; production build passed.
  • Validation: native CPU inference generated a 5.68-second sample in 12.36 seconds; local Whisper transcription recovered the intended sentence. Initial headless Chrome WebGPU generation took 6.61 seconds to playback and completed successfully. Clone quality still needs the user's listening judgment; full dialogue still needs a configured chat provider.

MCP chat provider — October 10

  • [x] Select Gemini 3.8 Flash as the default MCP conversation provider, using Google's OpenAI-compatible endpoint in both local and Worker relays. Keep the API key server-only; local status stays unconfigured until a key is supplied. Explicit endpoint/model overrides remain supported.
  • [ ] Supply the Gemini API key and verify a live conversation.
  • Gemini credential storage: credentials/Gemini.txt uses the existing git-crypt filter and an explicit ignore exception. Local MCP reads the unlocked file; public checkouts with encrypted content remain unconfigured. Production uses the Cloudflare MCP_API_KEY secret, never the static bundle. The authorized local key is installed. A real Gemini reply through the local relay returned HTTP 200 in 2.73 seconds; production secret upload remains pending.

Light cycle match roster — October 10

  • [x] Show a top-center row of top-down renders of the repaired game cycle model, facing upward and grouped by team, using each team's color; retain eliminated cycles at 20% opacity.
  • [x] Rebuild the roster for each match and keep the controls/death prompt below it. Hide the roster outside cycle play and during the opening camera sequence.
  • [x] Chrome (headless, macOS ARM64): node tests/cycle-roster.mjs passed for a 12-cycle/four-team match, elimination dimming, six-cycle restart, and hiding. Inspected the captured icon layout.

MCP loading and voice comparison — October 10

  • [x] Display a combined download meter and ETA with the active component name. Distinguish transfer completion from GPU initialization and voice conditioning. Keep the saved audition and typed chat usable while loading.
  • [x] Preserve a static face and startup error message if the renderer/module fails. Restart the local Vite server with the MCP relay. Chrome UI tests passed; the user's original blank-screen report was not reproduced.
  • [x] Cache large voice files as separate, bounded IndexedDB records in an atomic transaction. Avoid unreadable large Blob entries and IndexedDB's record-size limit. Pin model architecture and quantization metadata to remove optional generic-model 404 probes. Host the inference runtime locally.
  • [x] node tests/mcp-voice.mjs --local-models: Chrome/WebGPU generated speech in 6.27 seconds after initialization and reloaded all 13 cached files (1,526,293,292 bytes) with no model downloads. node tests/mcp.mjs passed loading, interaction, cache and startup fallback checks. MCP download/relay/Worker unit tests passed 14 tests.
  • [x] Produce a same-dialogue audition at /mcp-voice-comparison.html: original film excerpt, dry clone, measured pitch/reverb match, and a deeper alternative. Measurements guide the candidates; final perceptual matching remains subject to listening review.

Cycle roster circles — October 10

  • Replace the rendered cycle thumbnails with filled team-colored circles. Eliminated cycles keep a full-color outline and have a transparent interior. Connect adjacent teammates with matching lines spanning only the gaps; no line crosses a hollow circle or joins different teams.
  • Move the controls/death prompt up beneath the shorter roster. Keep the existing model thumbnails available for future use.

Adaptive antialiasing and stable quality — October 10

  • [x] Query supported HDR/depth-stencil MSAA sample counts, retain SMAA, and adapt MSAA plus render pixel ratio toward a default 60 FPS target. Bound resolution to 2× and six million pixels. Development controls expose target FPS and adaptation enablement.
  • [x] Observe sustained frame pacing, exclude inactive/opening frames, and allow a settling period after changes. Increase only after 24 seconds of stable windows. A failed level lowers a session-long ceiling, preventing repeated up/down cycling; page reload starts a fresh evaluation.
  • [x] Five controller tests passed for capability limits, isolated stalls, inactive frames, upgrades, backoff, no retry of rejected levels, and the quality floor. Chrome renderer test switched from 4× MSAA at 1× resolution to SMAA at 0.85×, retained 27 textures, and reported no JS errors. Performance targets remain hardware/workload dependent; no claim of 60 FPS on every device.

MCP cache clarity and transient chat recovery — October 10

  • Distinguish downloading, saving each IndexedDB file, and GPU initialization. A cache-only launch explicitly reports no download. Hiding the page preserves pending voice loading; Stop/exit still cancels it. GPU initialization remains necessary after reopening.
  • Retry temporary provider errors/timeouts at most twice, with 0.5/1-second backoff and a 12-second per-attempt deadline inside the existing 45-second overall deadline. Authentication, model-access and quota errors do not retry. Explicit cancellation remains immediate.
  • MCP navigation keeps the home preview covered rather than flashing CLU before the separate page loads. Voice status now says “INITIALIZING VOICE FROM SAVED FILES” and distinguishes speech-engine startup from transfer. Chrome home-transition and MCP interface checks passed.
  • Gemini's compatible endpoint continued to time out from the deployed relay despite successful direct tests. Added native generateContent support while preserving custom compatible providers. Native request/response mapping, thought exclusion, bounded retries and cancellation are covered by tests.

MCP cloned voice only — October 11

  • [x] Remove browser/native text-to-speech entirely from MCP. If the clone is loading, unavailable, or fails generation, preserve the reply as text and show an explicit cloned-voice message. Keep the saved cloned audition.
  • [x] Chrome node tests/mcp.mjs verifies failed voice loading and generation never call browser speech synthesis; conversation history, Stop, exit, and cache/loading UI still pass.

MCP input waits for cloned voice — October 11

  • Disable the message field, Send and microphone until cloned voice initialization succeeds. Enforce the same readiness guard on submitted text and recognition callbacks. A failed/cancelled load leaves conversation input disabled and exposes the voice retry control.
  • Resume microphone listening only after voice readiness; unlock Web Audio during keyboard/pointer interaction before asynchronous chat and inference finish. No queued replies or alternate TTS voice.
  • Chrome node tests/mcp.mjs passed: input disabled during loading, enabled on ready, cloned-generation errors remain explicit, and browser speech synthesis is never called.

MCP connection refresh and simplified terminal — October 11

  • Reproduced an immediate local Gemini 503 while identical direct requests and a four-turn deployed conversation succeeded. Restarted the stale October 10 Vite process; four consecutive local and four deployed replies then succeeded (about 1–4 seconds each). The local relay now reads the credential file for each request, so key replacement takes effect without restarting. Gemini 3.8 Flash remains the model; no fallback model added.
  • Remove the top heading/home button and fill the top/width with the cropped MCP face. Put MIC, STOP, LLM and TTS indicators directly beneath it; keep progress/errors with those controls, outside the dialogue. Return submits the input without a Send button. Conversation contains only the latest user and MCP messages; Escape still opens home confirmation.
  • Verification: 11 MCP/cache unit tests, Chrome node tests/mcp.mjs (voice gating, Return submission, history, Stop/exit), inspected 1280×800 rendered capture, and production build passed. Live multi-turn probes verify chat only; cloned speech generation was covered by the earlier dedicated voice test, not repeated here.

MCP warm voice session, live effects and film terminal — October 11

  • [x] Instrument startup phases and cumulative IndexedDB read time/bytes. Real Chrome/WebGPU with local model fixtures measured cached manifest checks at 2 ms, runtime read 31 ms, tokenizer 2 ms, model loading/GPU sessions 53.20 s, reference conditioning 408 ms. A fresh fixture load measured model/GPU setup 50.27 s. Cache-read measurements overlap the model phase; they are not an additional phase. Cached reload used zero model downloads. Full reload still pays initialization cost.
  • [x] Keep MCP in a retained same-origin frame when opened from the home menu. Leaving stops audio/microphone/chat, pauses the face render, and hides the frame; returning reuses the initialized worker. Suspend the underlying game render while MCP is visible. Pending inference finishes silently before accepting another request, instead of destroying the model. Remove STOP; Escape confirmation returns home. Direct standalone MCP page navigation/full reload still tears down its worker.
  • [x] Check cache metadata without opening/prefetching large model streams during the manifest pass.
  • [x] Fix live speech bypassing the approved audition treatment: lower live playback pitch to 0.92× and apply a 0.9 s room tail/early reflections at 1.25 wet gain. This lightweight pitch shift also slows speech by 8%; it is not the audition's duration-preserving offline processor. The preprocessed sample bypasses effects, and the face follows adjusted playback timing. Listening comparison remains for the user.
  • [x] Create a local original MCP dot-matrix font from geometric glyphs, inspired by the supplied film terminal frame. Make MCP text uppercase with one font/size and only normal/dim blue text, including disabled controls, placeholders and the shared exit dialog. Other games keep their fonts.
  • Validation: real Chrome voice generation/playback and cached reload passed (node tests/mcp-voice.mjs --local-models, first speech ready in 4.48 s). Twelve MCP/cache unit checks passed. Browser lifecycle, typography, retained-worker, reverb-tail and Escape checks recorded in tests/mcp.mjs; inspected its 1280×800 font capture. Production build passed with existing asset/chunk advisories.

MCP short-sentence speech queue — October 11

  • Ask Gemini for one or two short, complete sentences (32 words total maximum; first sentence at most eight words). Keep the full reply visible while speaking it sentence by sentence.
  • Split speech at sentence boundaries, with a 120-character/16-word fallback for long sentences. Generate only one sentence ahead while playing the current sentence; preserve playback order, cloned-voice effects, and the existing reverb tail.
  • Escape discards buffered audio and lets in-flight generation settle silently before unlocking input. Handle speculative-generation errors immediately to avoid unhandled promise rejections, then report them after current audio finishes.
  • Validation: 16 MCP/chat/cache/speech unit checks passed, covering sentence boundaries, bounded prefetch, ordered playback, cancellation/draining, and prefetch failure. No measured real-model latency improvement claimed from these deterministic checks.

Analytic light-cycle rendering experiment — October 12

  • [x] Reduce the experiment's ambient intensity to 25% and fill to 40% of the original values, preserving the key light and highlights in both comparison views.
  • [x] Add isolated raycast-cycle.html, using Three.js/WebGL fragment shaders with closed-form ellipsoid intersections, half-space clipping and a convex chassis. This is direct ray casting, not distance-field marching. Keep all production game models/renderers unchanged.
  • [x] Match nominal length (3.6 m), width (1.014 m), height (1.52 m), camera and direct-light shader with a toggle to the existing repaired cycle mesh. The analytic model is an authored shape study, not a finished film-accurate replacement. Its panel contours and mechanical details still need work.
  • [x] Provide gold/blue, orbit/zoom, fixed 720p/1080p internal resolution, one/four primary rays per pixel and an optional hard shadow ray. Both views use the analytic vehicle as the shadow proxy; raster geometry receives hardware antialiasing while analytic edges use four ray samples by default. There are no reflected rays, ray-marching steps, texture maps, bloom, or full-game simulation in this benchmark.
  • [x] Browser test: node tests/raycast-cycle.mjs, headless Chrome on macOS, hardware reported ANGLE Metal Renderer: Apple M2 Max. After warmup, eight-second measurements at each setting sustained ~60 FPS (display-paced), p95 frame intervals 16.7–16.8 ms, with no page/shader errors. Inspected matched-camera analytic/current-model captures and a shadow capture. Production build passed with existing chunk/font/script advisories.
ViewInternal resolutionPrimary samplesShadowsMedian GPU ms
Analytic cycle1280×7204Off1.81
Analytic cycle1920×10804Off3.67
Current mesh + procedural grid1280×7204 grid samplesOff0.85
Current mesh + procedural grid1920×10804 grid samplesOff1.25
Analytic cycle1920×10804On6.31
  • Limits: one vehicle, static benchmark camera, simple lights and no arena. Results do not establish full-race performance or performance on weaker integrated GPUs. Camera movement is available for manual evaluation. The current mesh remains more detailed and closer to the film; the experiment establishes smooth analytic surfaces and a measured performance baseline, not replacement readiness.

POV-Ray cycle CSG port — October 12

  • [x] Replace the experiment's simplified shape with Carl N. Hoff's 54-primitive model from Jason Cox's MIT-licensed lightcycle-povray repository. Preserve the upstream source and license in docs/models/povray-lightcycle/; retain the existing production mesh comparison and leave the game unchanged.
  • [x] Transcribe CSG unions, intersections and differences over transformed spheres, cylinders/cones, boxes, planes, linear prisms and tori. Evaluate sorted ray-boundary events on the GPU; torus roots use quartic stationary-point brackets. Normalize source +X-forward coordinates to -Z and 3.6 m length without stretching proportions. This is a geometry port, not a browser port of POV-Ray itself.
  • [x] Separate the inexpensive floor pass from the CSG pass; scissor the latter to conservative projected model/shadow bounds. Compile shadow-free variants and prune candidates behind the nearest part. Shadows remain optional and off by default.
  • [x] Match the production arena's 4.32 m grid spacing, 0.08 m full line width, antialiasing, distance fade and navy background. Remove floor specular lighting entirely. Per subsequent user feedback, use brighter #cccccc grid lines in the experiment instead of production #888888.
  • [x] Correct initial bounds that clipped the bulging window sides. Give the glass priority within 0.03 source units (0.21 mm at runtime) of the gold roof to resolve the source's nearly coincident 389.721/389.722-radius surfaces in GPU float precision. Keep window gloss unchanged.
  • [x] Verification: node tests/raycast-cycle.mjs passed in headless Chrome / ANGLE Metal / Apple M2 Max with no page or shader errors. Inspected gold front, both sides, three-quarter, shadow and blue captures. Latest eight-second runs: 720p/four samples ~60 FPS; 1080p/four samples ~47 FPS; 1080p/shadows ~12 FPS. Earlier optimized runs reached ~60 FPS at 1080p without shadows, so sustained 1080p/60 is not established (other live browser workloads may contend for the GPU). Optional shadows remain too costly for gameplay. The earlier table above describes the simpler initial model, not this detailed port.
  • [x] Production build passed with existing script/font/chunk warnings. No deployment requested or performed.

Optional mixed cycle renderer — October 12

  • [x] Add an explicit runtime switch (bottom-left button or Shift-R during the cycle game) between normal meshes and POV-Ray CSG cycles. POV-Ray is now the default when entering the cycle game; the CSG module and shaders are dynamically imported at that point (not during normal CLU play or the home screen). ?cycleRenderer=normal explicitly opts out. Geometry and materials are disposed on return to normal; race/simulation state is untouched.
  • [x] Render each CSG bike through a conservative proxy box with true surface depth, linear lighting and game fog into the existing scene/composer. Arena, maze, trails, other vehicles, bloom and antialiasing retain their normal rendering. This is a mixed renderer, not full-scene ray casting. Gold/blue/red/green colors and interpolated position/rotation/lean follow the existing race view.
  • [x] Preserve wireframe materialization using the original model until solid. Preserve floor shadows using original cycle shadow casters (approximate silhouettes); expensive exact CSG shadows remain excluded from gameplay. Screenshot rendering also selects the correct bike representation.
  • [x] Isolate normal/CSG adaptive-AA controllers so CSG performance does not permanently lower normal-mode quality. Cancel stale asynchronous switches and clean up on application disposal.
  • [x] node tests/cycle-renderer.mjs: headless Chrome/Apple M2 Max, 1280×720; validated no CSG requests before selection, in-arena and outside-arena rendering, reversible switching, no race reset, asynchronous cancellation, keyboard/button controls, and unchanged normal geometry/draw-call counts after switching back. Inspected paired captures and live arena capture; no shader/page errors. Short mixed-mode sample p50 16.7 ms / p95 33.4 ms is a smoke check, not a sustained full-match performance guarantee.

Default POV-Ray cycles and slow-device fallback — October 12

  • [x] Automatically enable POV-Ray cycles on entry to the cycle game, retaining the button and Shift-R switch. Keep normal-only operation available through ?cycleRenderer=normal.
  • [x] After four seconds of active-play warmup, measure consecutive two-second frame-time windows. Three slow windows trigger a one-way fallback to normal (below 65% of target FPS, bounded to a 20–40 FPS threshold; 39 FPS for the usual 60 FPS target). Exclude pauses, hidden/unfocused windows, loading, opening camera work, and non-racing phases. Do not automatically retry after falling back; Shift-R allows an explicit manual retry.
  • [x] Show NORMAL (PERFORMANCE) on the existing switch after automatic fallback. Preserve normal mode's independent AA settings and release CSG geometry/materials.
  • [x] node --test tests/cycle-renderer-guard.test.js: four tests cover sustained slow play, short hitches, inactive periods/warmup, one-way fallback and manual retry. Browser coverage extends the renderer-switch test to default activation and injected sustained slow frames, verifying it stays on normal afterwards.

Closer turbo cycle camera — October 12

  • [x] Increase the speed-driven camera approach so full turbo settles at a 5.5 m horizontal follow distance (previously 7.8 m), approximately 30% closer. Preserve normal cruising, braking pullback and exponential easing.
  • [x] Only invoke the short-boom lateral wall escape when a wall actually clips the requested camera segment. This prevents the intentionally closer turbo framing from triggering a sideways jump.
  • [x] node --test tests/cycle-camera.test.js tests/arena-camera.test.js tests/cycle-renderer-guard.test.js: 35 checks passed, including smooth speed framing, wall clearance, horizon visibility and fallback behavior.

Cycle self-shadowing and status controls — October 12

  • [x] Cast a secondary ray toward the key light on lit CSG cycle surfaces. Transform the light into each bike's local coordinates so self-shadowing follows rotated bikes correctly; keep original-mesh floor shadow proxies and the existing performance fallback.
  • [x] Handle Shift-R before opening/arena-wait and inspection input gates. Hide the renderer control in ray-cast mode; show normal mode (including performance fallback) for four seconds after switching.
  • [x] Stop hiding system warnings during cycle play. Keep JEV failures visible as JEV UNAVAILABLE / LOCAL AI ACTIVE until recovery; retain the brief CLU notice.
  • Validation: Chrome headless on the local Mac, node tests/cycle-renderer.mjs passed shader compilation, renderer switching/disposal, visible simulated JEV failure, notice expiry and performance fallback. Inspected test-results/cycle-renderer-playing.png. Nine cycle-JEV/renderer-guard unit checks passed. A live local /api/jev/decision cycle request returned a valid choice with confidence 1; this verifies the local relay, not production availability. Self-shadowing increases GPU cost; broad client performance testing remains outstanding.

Cycle AI reaction profiles and collision lookahead — October 12

  • [x] Each rider owns a reactionTiming profile: mean, standard deviation, minimum and maximum seconds. Draw a seeded truncated Gaussian for each reaction (default deviation 40 ms, bounds 70–450 ms; gold/blue mean 200 ms, red 140 ms, green 300 ms). Human input is unchanged.
  • [x] Before scoring destinations, sweep the rider's next reaction travel against continuous trails, arena walls and projected moving bodies. Unsafe directions receive priority penalties over JEV goals and interception incentives. Reserve choices use the heading selected by the turn, instead of the old heading.
  • [x] Preserve reaction limits: safety checks occur on decision ticks and account for the sampled delay plus 100 ms margin; no instantaneous emergency turn bypass.
  • Validation: npm test passed all 486 checks, including fractional turbo obstacle avoidance, Gaussian distribution/bounds/reproducibility, team profile defaults and existing simulation invariants. This addresses immediate collision blunders; competitive tactics and future opponent turns remain imperfect and need play review.

Credit attribution, previews and launch framing — October 12

  • [x] Credit Carl N. Hoff's CSG cycle and Jason Cox's source repository in displayed and archival credits. Identify the custom project ray-casting kernel and Three.js integration accurately; ship the upstream MIT notice with the website.
  • [x] Render the Hoff credit with the same CSG mesh/shader factory as gameplay, including self-shadowing, preserving fade/disposal behavior. Keep Daniel Preti credited for the arena and original fallback meshes.
  • [x] Correct maze provenance per the user: traced from a TRON (1982) frame showing Flynn entering the electronic world, not an unidentified blueprint.
  • [x] Keep the home transition covered when selecting credits so the underlying CLU scene is never revealed.
  • [x] Credit blocks hold after typing for 240 words/minute plus 0.75 seconds, with a three-second minimum. Space still advances immediately.
  • [x] Lower the formation shot from 1.6 m to 0.55 m with a slightly raised gaze, preserving the right-side three-quarter view, smooth arrival and launch hold. Widen the vertical field of view on narrower windows to preserve horizontal framing.
  • Research: Carl Hoff discussed a POV-Ray tank model in his 2005 Tron-Sector thread. No verified downloadable tank source or reuse terms located; no tank asset imported.
  • Validation: nine credit previews rendered in headless Chrome with fade/framing/disposal checks, including the CSG shader preview; capture inspected. All 25 camera unit checks passed; tests/home-transition.mjs and tests/cycle-opening.mjs passed in headless Chrome. Inspected the lower formation capture. npm run build passed. Fixed the development tuning reset to exclude the new antialiasing checkbox from slider indexing.

Cycle wall elimination rewards — October 12

  • [x] An opposing cycle destroyed by a living cycle's trail fully restores the owner's turbo and brake reserves. An allied cycle crashing into the trail instead empties the owner's reserves, animating both meters downward; self collisions give no reward. Existing trail splitting remains unchanged.
  • [x] Watched-cycle meters fill brightly over 0.65 seconds, glowing for 1.1 seconds. Switching watched cycles clears the effect.
  • [x] W is the cycle turbo key and S is brake; remove T, Space and X aliases and update help. Outside the arena W accelerates/boosts; S brakes and selects reverse when pressed at a stop.
  • Validation: headless Chrome recharge presentation check and capture passed on macOS. Production build passed. Full simulation suite includes opponent/friendly awards, swept collisions and removed-key checks.

Arena artist credit preview — October 12

  • [x] Show Daniel Preti's arena architecture and game-style grid beside his extended credit, using an elevated view, proportional fitting and synchronized fades. No race simulation is created.
  • Validation: 15 focused collision/control tests passed. Headless Chrome verified reserve fill/drain and watched-cycle cleanup; all ten credit previews passed framing, fade and disposal checks. Arena render captured and inspected on macOS.

Credit floor and BIT transition — October 12

  • [x] Keep the CLU preview covered when departing the home screen for BIT; headless Chrome verified CLU, cycles, credits and BIT transitions.
  • [x] Use the usual procedural floor in the arena credit with the game's exact 4.32 m spacing and line width. Allow subpixel lines to disappear at credit-preview scale rather than widening or coarsening the grid. Gameplay floor defaults are unchanged.

MCP terminal introduction — October 12

  • [x] Hide the face, status, input and old controls. Show the MCP-font text at the opening terminal position and the supplied Neon ENCOM Retro Interface Badge at the lower-right logo position.
  • [x] Type the film's Dillinger access request with varied key timing and line pauses, request microphone access after typing finishes. Hidden face rendering is not initialized.
  • [x] Extract the opening beep from the user-supplied Dilinger.m4v, 0.295–0.620 seconds. Stereo 48 kHz WAV, 250–1800 Hz filtering, +12 dB gain and short edge fades. Film audio belongs to its original rights holders; no redistribution license asserted. Play one second before typing; browser autoplay rejection logs a warning and still permits the text sequence.
  • Validation: headless Chrome checked hidden elements, message placement, typed access text and Escape confirmation without loading the large TTS model.
  • MCP visual refinement: deeper blue text (#2864cf), matching dim blue, glyph outlines and advances narrowed to 90% with unchanged height, no typing cursor, and the ENCOM panel at 70% of its original size with 60% brightness, equal 4vw bottom/right margins and a four-second fade.
  • MCP background is near-black blue (#010207), including the iframe loading background and browser theme color.

MCP hosted voice and conversation entry — October 12

  • [x] Replace browser Chatterbox inference with server-proxied fal.ai Chatterbox using the existing MCP reference. Preserve pitch/reverb processing; no generic voice fallback. Local Vite reads credentials/Fal.txt; production requires the FAL_KEY Worker secret. Keys never enter browser bundles.
  • [x] Delete retired MCP IndexedDB model storage and cached ONNX/runtime requests on entry; preserve unrelated browser data.
  • [x] After access typing, request microphone access. Denial clears the terminal to MASTER CONTROL PROGRAM UNAVAILABLE. Approval plays WHAT CAN I DO FOR YOU, MR. DILINGER? through the cloned voice, then enables listening after playback finishes. Escape stops requests/audio.
  • Live fal.ai smoke test generated a short sample successfully in 13.1 seconds; this is not yet low-latency conversational speech.

Light cycle edge highlights — October 13

  • [x] Add thin, muted blue-gray highlights to the ray-cast cycle's surface creases and grazing rims, guided by the supplied 1982 film stills. Emphasize dark hubs, windows and underbody details; keep painted-body highlights subdued. Shared by game and credits, with named color/strength/width controls in cycle-ray-shader.js. Screen-space normal derivatives add no additional intersection rays; normal mesh rendering remains unchanged.
  • Validation: headless Chrome node tests/raycast-cycle.mjs and node tests/cycle-renderer.mjs passed without shader errors. Inspected study and game captures; switching, fallback and resource disposal checks passed. Hardware performance and motion shimmer still require human play review.

Outline filtering and MCP entry follow-up — October 13

  • [x] Replace discontinuous normal-derivative outlines in game/credits with an eight-tap filtered normal buffer. The cycle-only prepass adds one intersection pass; the rejected multiple-neighbor-ray approach was too expensive. Preserve normal-renderer isolation and dispose the buffer on renderer shutdown. The standalone study uses softened grazing highlights.
  • [x] Start the supplied Wendy Carlos “Break In (For Strings, Flutes And Celesta - Bonus)” recording with the first access character, at 30% volume. Pause it for exit confirmation/return home and release it on page exit. Original soundtrack rights remain with their rights holders.
  • [x] Request microphone permission before testing speech-recognition availability. Explain audio-input requirements and browser permission settings on failure; click or Return retries access. Unsupported speech-recognition browsers get a specific explanation.
  • [x] Add https://github.com/stevedekorte/TRON to Steve DeKorte's on-screen credit. credits_display.txt drives the terminal; credits_extended.txt remains linked/copied as the detailed archive.
  • Validation: headless Chrome MCP approval/denial/retry, first-character music timing, greeting-before-listening, game renderer switching/fallback and all ten model credits passed. Game and credit captures inspected. Local Vite needed a restart to install the new speech endpoints; voice-status now returns configured:true.

MCP response latency — October 13

  • [x] Use fal.ai Chatterbox Turbo with the same MCP audio reference and existing client pitch/reverb. Turbo uses temperature 0.7; standard-model exaggeration/cfg parameters are omitted according to its API schema. Short sentence generation and next-sentence prefetch remain enabled.
  • Measured one identical seven-word sentence: standard 2.995 seconds, Turbo 1.421 seconds. A separate local Gemini request took 2.068 seconds. These are individual service checks, not guaranteed end-to-end response times; recognition finalization, audio download, cold starts and network load add latency. Turbo voice delivery still needs user listening review.
  • Validation: all 12 focused MCP relay, validation and speech queue tests passed. Local server restarted to load the new endpoint.

Arena grid wall alignment — October 13

  • [x] Fit an even number of whole visual grid cells between the four inner arena walls. With the existing 409.06 m half-span, 190 cells span the floor at 4.3058947368 m each (previously 4.32 m). Center and boundary lines align without partial perimeter cells. Applies to gameplay and the shared arena credit floor; cycle movement remains continuous and unchanged.
  • Validation: direct dimension check confirmed 95 cells per half-span with zero wall remainder. Headless Chrome credit-model rendering checked the shared floor.

Ray-cast cycle materialization — October 13

  • [x] Keep the CSG cycle active through the opening/countdown wire sweep and solid fade, eliminating the mesh-to-ray shape change. Reuse the existing reveal timing and team colors.
  • [x] Draw antialiased construction curves directly on the analytic CSG surface at local section-plane intersections, with the filtered silhouette/crease pass. These are smooth surface cross-sections, not the old mesh's triangulation. Hidden rear surfaces stay suppressed. Named spacing, line width and intensity are in CYCLE_REZ.
  • [x] Preserve alpha/depth behavior through the fade; the normal prepass temporarily writes depth and restores the color-pass state. Raster fallback retains its existing materialization.
  • Validation: headless Chrome tests/cycle-ray-materialization.mjs captured sweep, wire, fade and solid stages; inspected wire/fade captures. Full cycle-opening and cycle-renderer checks passed (pause/resume, race handoff, switching, resource cleanup and fallback). Production build passed. Motion/fidelity remain subject to user review.
  • [x] Refine formation into defining silhouettes/creases first, cyan surface sections second, then a pale, glowing body that settles to its normal material. Timing is shared in cycle-materialization.js; yellow-green contours and cyan glow follow the supplied 42:54–42:56 film references. No riders are shown.
  • Release validation: 500 automated tests passed; production build and full opening browser check passed. Staged ray-cast captures passed without shader errors; user approved the appearance.

Cycle shadow contrast and MCP music — October 13

  • [x] Reduce ray-cast cycle ambient intensity from 0.25 to 0.03 and fill from 0.4 to 0.04. Fully occluded key light now contributes zero instead of 15%, producing near-black self shadows while retaining the key light and thin edge highlights. Shared by gameplay, credits and the analytic study.
  • [x] Double MCP opening music playback volume from 0.3 to 0.6.
  • Validation: headless Chrome materialization shader/lifecycle check passed; inspected shadow-side and lit-side captures. Production build passed for the shadow changes; music adjustment checked directly. These changes are local following the preceding deployment.

Cycle rear window panels — October 13

  • [x] Assign the rear prism-cut faces of both projecting CSG windows the same gray material as the underbody. Curved glazing remains dark and reflective; material selection follows the actual CSG boundary rather than camera direction or team color. Applies to the shared analytic model in gameplay, credits and the study.
  • Validation: Chrome materialization shader/lifecycle check and production build passed. Inspected rear-view and flat-material diagnostic captures to verify the gray panel independently of the new dark shadows. Local change, not part of the preceding shadow/music deployment (which completed successfully).

Moving wheel reflections and menu/audio timing — October 13

  • [x] Add antialiased white spoke glints only on both black inner CSG wheel discs during motion. Cadence is 12 flashes/second at normal speed, scales with speed up to 24 at turbo, and fades out below 2 m/s. Simulation time drives phase, so rendering frame rate does not set the animation speed; stopped/formation/result cycles and static credits have no glints. Named values live in cycle-wheel-reflections.js. Raster fallback remains unchanged.
  • [x] Cue MCP music before typing, with a one-second lead from playback starting. Retain cancellation, volume and exit handling.
  • [x] Place Light Cycles first and select it by default; keyboard order follows the displayed buttons.
  • Validation: all 502 automated tests passed. Headless Chrome checked wheel on/off/stopped captures, materialization shaders, menu order/default/wraparound/Return launch, and MCP music lead-in plus permission/greeting/reply lifecycle. Inspected wheel glint capture.
  • [x] Thin materialization surface-section lines from 0.006 m to 0.003 m half-width, reduce contour sampling radius from 1.2 px to 0.65 px, and narrow/soften the surrounding halo. Solid-cycle edge highlights are unchanged. Chrome staged shader/render checks passed and the thinner grid capture was inspected.

Live wheel animation and MCP response presentation — October 13

  • [x] Fix moving wheel glints being reset every frame by interpolated cycle object replacement. Reset the presentation clock only by stable seed/round/cycle ID. Live-match regression now waits for phase progression across actual game frames, in addition to the isolated shader checks.
  • [x] Shorten MCP typed access text to one line: REQUEST: ACCESS TO MASTER CONTROL PROGRAM. Hold it for 1.5 seconds before microphone permission/conversation startup. Reveal greeting and reply text at the beginning of cloned audio playback rather than while generation is pending.
  • [x] Add a separate Wendy Carlos credit for Break In (For Strings, Flutes And Celesta - Bonus), used for the MCP introduction, in displayed and extended credits.
  • Validation: all 502 automated tests passed; headless Chrome checked live wheel phase progression, the completed-intro pause, greeting/reply audio-start synchronization, and microphone allow/deny/retry paths.

Processed MCP speech cache — October 13

  • [x] First MCP spoken/displayed response is IDENTIFY USER AND ACCESS CODE.
  • [x] Cache fully processed mono PCM in IndexedDB (tron-mcp-rendered-speech), including pitch slowdown and the reverb tail. Playback recognizes processed audio and bypasses the live effect graph, avoiding double processing. Concurrent requests for normalized identical text share one generation. Cache failure falls back to generation/playback.
  • [x] Keys include normalized text plus MCP_VOICE_ID, processing revision and the complete effect settings. Opening with a changed version clears old audio. Bump MCP_VOICE_ID in speech-cache.js when changing the hosted model/reference voice; numeric effect settings invalidate automatically.
  • Validation: Chrome verified one TTS request for concurrent/repeated text, byte-identical PCM after a new page reload, nonzero baked reverb tail, and fresh generation after version invalidation. MCP permission and ENTER QUERY synchronization checks passed. Live-game wheel regression was expanded to require advancing phases on every living cycle; all six cycles, including five AI, passed.
  • [x] Initialize one live Web Audio output before the MCP introduction and route both background music and speech through it, eliminating late output-context creation/rerouting at first speech. Cached speech also avoids live effect-graph construction. Headless Chrome verified one live context, no music pause during greeting/reply, synchronized display and 1x playback for preprocessed audio. Device-specific audible continuity still needs user listening confirmation.

Multiplayer countdown audio — October 14

  • [x] Add a short 660 Hz beep for each received countdown second and a longer 990 Hz launch tone on the transition to racing. Follow the same rounded server timer as the HUD; repeated snapshots and backward timer corrections cannot repeat a beep, and missed seconds do not produce a catch-up burst. Joining an already-running match does not play a launch cue.
  • [x] Route the synthesized tones through the existing master volume/mute, consume muted ticks without replaying them on unmute, and dispose nodes on exit/reset. Single-player remains unchanged.
  • [x] Verification: all 10 multiplayer authority/audio unit checks pass, covering countdown synchronization, mute, late joins, envelope duration and node cleanup. Production build and Chrome multiplayer lifecycle checks pass; a Chrome audio probe observes eight 660 Hz ticks followed by exactly one 990 Hz launch tone. Subjective volume/timbre remains for user audition.

Solo multiplayer restart — October 14

  • [x] Return requests a fresh multiplayer round when exactly one human is connected, including after that player is eliminated. Show RETURN / NEW MATCH only in that case. Other connected humans, including spectators, prevent restart.
  • [x] The server checks the sender, connected-human count and current round before accepting the request. Duplicate/stale round requests are ignored, and the normal new-round path restores seats, AI, trails and countdown.
  • [x] Validation: multiplayer authority/audio unit tests cover sole-player restart, eliminated players, spectators blocking restart, unknown senders and duplicate/stale requests.

Multiplayer spectator reserve stability — October 14

  • [x] Preserve reserve-reward object identity across equivalent network snapshots. Previously, each decoded snapshot retriggered the HUD refill animation, making a followed AI cycle's turbo/brake meters repeatedly snap back. Number actual reward events so identical consecutive rewards still animate separately.
  • [x] Validation: 13 multiplayer authority/audio/HUD checks pass, including 40 repeated snapshots with no new reward, a genuinely new reward with the same values, and completion of the HUD animation. Chrome's isolated-arena multiplayer test passes solo Return restart and rejection with other humans connected, plus normal two-client rendering. Full suite: 517 tests pass; production build passes.

Multiplayer roster stripe refinement — October 14

  • [x] Match each black/white human-player stripe to the roster circle's 2 px border thickness. Extend the stripes over the border to the circle's outer edge, with rounded clipping that keeps them inside the circle. Preserve team connectors and hollow eliminated icons.
  • [x] Chrome roster check passes; inspected the rendered human stripes and eliminated circles.

Solo multiplayer Return follow-up — October 14

  • [x] Diagnose the unchanged localhost server: a sole-client WebSocket restart request was ignored by the old in-memory code. Restart the Vite server on port 5173 to load the new server-side handler.
  • [x] An accepted solo restart immediately initializes racing and trails with zero countdown when the new round has no waiting queue. Support main Return and keypad Enter; retain authoritative rejection when another human is connected.
  • [x] Multiplayer authority/audio unit checks pass, including immediate racing, trail initialization, stale/duplicate requests and queue protection. Chrome on the restarted port 5173 server verifies main Return and keypad Enter immediately restart a solo round while shared matches reject Return. Production build passes.

Eliminated human roster stripes — October 14

  • [x] Retain the black/white human stripes after elimination, over the transparent circle interior and team-color border. Chrome roster checks pass; visually inspected the hollow striped icon.

Compact multiplayer snapshots — October 14

  • [x] Introduce protocol 2 with whitelisted presentation fields, submillimeter coordinate quantization, field-level cycle/trail changes, roster updates only when changed, and crash updates only when changed. Keep collision and AI simulation at full precision on the server. Initial/new-round snapshots are complete; deltas identify their baseline and clients request a full resync on a mismatch.
  • [x] Keep protocol 1 supported for cached clients during deployment. Share encoded messages among clients with the same baseline and preserve separate late-join baselines. Applied human turns and reserve-control changes trigger a snapshot immediately instead of waiting for the next 20 Hz update. Prediction clones only moving trail tips rather than every trail object each frame.
  • [x] Reproducible five-second measurements (node scripts/measure-multiplayer-bandwidth.mjs, same snapshots, uncompressed JSON): six cycles/one human falls from 111,015 to 12,779 bytes/sec (88.5%); twelve cycles/twelve humans falls from 197,499 to 13,360 bytes/sec (93.2%). These measure bandwidth, not real-network latency or perceived smoothness.
  • [x] Validation: full suite passes 520 tests; 17 focused multiplayer checks include a subsequently added mixed-version/late-join/resync regression. Chrome renders two compact clients alongside twelve legacy wire clients without errors; inspected normal-renderer capture. Production build and Worker dry run pass.
  • [ ] UDP-style transport: WebTransport datagrams or unreliable WebRTC data channels need a compatible server/gateway. Cloudflare Workers' documented protocol interfaces do not provide a direct WebTransport/WebRTC server endpoint. Retain WebSockets for this optimization; no hosting migration or deployment is included. See the multiplayer document for sources and tradeoffs.

Multiplayer arena breaches — October 14

  • [x] Enable impact-created arena breaches in multiplayer, synchronize openings in full and compact snapshots, and restore intact walls each match. No opening is pre-created.
  • [x] Cycles crossing the outer edge silently derez, stop counting as survivors, and enter the normal next-match queue. No explosion effect or explosion sound; trail cleanup remains active. Keep bounded AI enabled after breaches appear.
  • [x] Validation: 27 focused multiplayer/breach/AI unit tests pass; Chrome arena breach geometry checks verify an opening and restored walls; production build passes. Local implementation only, not deployed.

Cycle AI evaluation rewards — October 14

  • [x] Add persistent, bounded confinement attribution, hollow roster assist dots, and offline rewards for direct kills, trap assists and creating confinement. Runtime remains the first gate; aggression and wins jointly determine fitness. 561 unit tests, Chrome roster checks, dense attribution benchmark, evolution smoke and production build pass. No live weights changed; implementation local only. See cycle AI for measured costs and conservative attribution limitations.

First evolved cycle AI playtest — October 14

  • [x] Run 128 training and 64 paired held-out matches with aggression rewards; preserve weights/results and check serial/browser performance. Candidate gets 5 versus 3 direct kills, 10 versus 9 trap assists and 5 versus 4 wins in the 32-match held-out comparison. Evidence remains weak across eight independent seeds.
  • [x] Add a development-only ?cycleAITrial=1 route for playing the candidate in LIGHT CYCLES. Exact weights and rendering verified in Chrome; baseline and production unchanged. See cycle AI for the reproducible artifact, timing and limitations.
  • [ ] Human play review and broader evaluation before promoting the candidate, including multiplayer wall-breach matches.

MCP closing-sentence fade — October 14

  • [x] Fade the MCP face during the END OF LINE sentence, completing before speech finishes rather than leaving it visible through the post-speech hold. Use the actual audio duration/pitch and exclude the rendered reverb tail. Keep complete playback, the one-second hold and the normal game transition. Clear the fade state on another announcement or panel resume.
  • [x] Four speech queue unit checks and the Chrome game-launch test pass, including progressive fade, disappearance before the closing audio ends, no early launch, complete speech, post-speech hold and direct cycle entry. Local only.

Evolved AI default for solo and MP — October 14

  • [x] Following the user's playtest, select frozen aggression-1-0 weights as the common solo/MP default. Keep the original baseline for offline comparisons and keep ongoing experiments from replacing gameplay weights automatically. Solo arena AI remains bounded after breaches.
  • [x] Focused AI/authority policy-selection tests, two-client Chrome MP lifecycle coverage and Worker dry run pass. Production deployment remains outstanding.

Cycle AI research and evolution plateau — October 14

  • [x] Complete the extended evolution run: stop after three consecutive generations without a qualifying validation gain. Fresh evaluation does not improve on the playtested policy; retain aggression-1-0. Preserve the experiment and limitations on the cycle AI page.
  • [x] Review original Tron AI research and Armagetron source for territory evaluation, neural inputs, passive self-play failure modes and close-combat interception. Record findings and proposed experiments on the cycle AI page. No new neural controller or overtaking behavior is implemented by this research.

Faster-win AI evaluation — October 14

  • [x] Add a tunable maximum 0.5-point bonus to confirmed wins, declining linearly with elapsed time relative to the evaluation match limit. Losses and timeouts earn no speed bonus; existing kill/trap/confinement rewards remain. Record match limits and worker bonus contributions for reproducibility. Runtime remains the first gate; gameplay weights are unchanged.
  • [x] Four fitness tests pass, covering fast/late wins, loss/timeout exclusion, bounded scoring, tuning and missing/invalid timing. Offline evolution smoke passes. New scoring needs a fresh training/evaluation comparison before any policy promotion; historical scores use the previous objective.
  • [x] Run node tools/ai/evolve-until-plateau.mjs --fast-wins: 352 simulated matches; stop after three consecutive failed validation generations. Retain aggression-1-0, with no trial/default change. Fresh results: 5/32 wins for both retained policy and original baseline, fitness 0.5266 versus 0.5500, mean winning duration 147.5 versus 151.2 seconds. No demonstrated improvement; see full results and limitations. Runtime p99 gate passes; no deployment.