# Afterlight — design decisions

## Initial design / 1.0.0

Recorded while choosing and implementing the first release; release time is recorded separately in RELEASES.md.

| Opportunity / problem | Chosen approach | Expected benefit | Tradeoff |
| --- | --- | --- | --- |
| A canvas game needs an immediate identity and a complete solo arc. | An orbital salvage ritual: collect embers, deposit them at the central star, survive three tides, restore the sun. | A clear objective and a satisfying finite ending. | Less replay variety than a large procedural campaign. |
| Abstract neon arenas can feel visually generic. | Ink-blue space, fine orbital engravings, a warm luminous sun, handmade vector ships, radiant particles and generous editorial typography. All art is drawn in canvas. | A cohesive, striking world without downloads or external assets. | Procedural visuals take rendering time; cap pixel density and particle counts. |
| Movement and combat should be approachable without becoming passive. | Keyboard movement or pointer steering; a timed radial flare; at most three carried embers. Threats announce their arrival. | Movement, route choice and flare timing create small meaningful decisions. | No aiming or weapon upgrades; the focus stays on salvage. |
| A hit can create an unfair chain of failures. | Knockback, a temporary shield, cargo drops, and one hull repair between tides. | Mistakes remain recoverable; cargo can be reclaimed. | The forgiving shield lowers peak difficulty. |
| Browser interruptions and mobile controls can interrupt a run. | Pause on blur/hidden page, modal-aware pausing, touch steering, a dedicated flare button and responsive layout. | A run survives interruptions and works without a physical keyboard. | Small phone screens provide less visual space. |
| Publication should require minimal infrastructure. | Plain HTML/CSS/classic JavaScript with no fetch, dependencies, server logic or external fonts. | Open locally or publish the exact files to a static host. | Saves are device-local and may be unavailable under restricted browser storage. |
| Design claims should not be mistaken for evidence. | Keep expected benefits here and record actual automated / visual checks in TESTING.md after implementation. | Reviewable decisions and bounded, honest validation. | Automated checks cannot establish long-term enjoyment. |

Verified results for 1.0.0: 15 simulation checks and 19 browser checks passed. Desktop and portrait screenshots reviewed. Offline launch, scoring, pause behavior, touch input and both endings worked in tested Chrome flows. Enjoyment and real-device cross-browser performance remain expectations, not verified results.

## Refinement / 1.0.1 — decisions before implementation

| Observed problem / opportunity | Chosen approach | Expected benefit | Tradeoff |
| --- | --- | --- | --- |
| Screenshot review shows two star captions occupying the same place. | Draw one caption and its coordinate directly in canvas. | The caption stays anchored to the sun at any aspect ratio. | Decorative text stays outside the accessibility tree. |
| The initial phone layout hides How to play. | Keep a compact, named help button in the mobile header. | Touch users can open the complete rules during a run. | A question mark is less explicit than a full text label. |
| Holding P can repeatedly toggle pause because browsers repeat keydown. | Ignore repeated pause key events. | One physical key press causes one pause transition. | Holding P intentionally cannot alternate states. |
| A completed flight still shows an inactive Pause control and an instruction to gather embers. | Hide Pause at the end and give the objective an ending-specific status. | End-state controls and copy clearly match the result. | End-state HUD has slightly different controls. |
| Pointer input and storage fallback warrant broader evidence; effects should remain aligned after rotation. | Add pointer / repeat-key / blocked-storage checks, a full simulated flight, performance sampling, and resize effect translation. | Stronger evidence for behavior and a cleaner orientation change. | Automated flight and emulation cannot substitute for a human on real devices. |
| Follow-up flight simulations of the 1.0.0 mechanics completed 100/100 routes in 15.2–19.4 seconds with full hull and no shades cleared: tides ended before far-edge threats arrived. | Spawn threats on a reachable outer orbit, shorten arrival intervals, and announce two fresh threats at each tide change. Increase threat speeds moderately; retain the 1.1-second warning and recovery shield. | Flare timing and navigation should matter even on efficient routes; landscape and portrait should offer comparable pressure. | Less quiet time between tides; this is a balance inference from bots, not a claim about human difficulty. |

Verified results for 1.0.1: 16 simulation checks and 26 real browser checks passed. Mobile help is accessible at 390 and 320 pixels; held pause keys, pointer input, blocked storage, both endings and offline play passed. One caption remains attached to the sun in reviewed screenshots. All 100 route simulations won in 14.8–21.7 seconds, clearing 472 shades and sustaining 54 hits in total. Landscape and portrait produced the same seeded outcomes. This supports reachable victory and actual threat encounters; human difficulty and enjoyment remain unverified. On this Windows host, a 120-frame headless Chrome sample with GPU disabled averaged 23.055 ms per frame (about 43.4 fps), with a 33.4 ms 95th percentile. That is a measurement of this test setup, not a device performance guarantee.

## Expansion / 1.1.0 — Slipstream & Resonance

Decisions recorded before implementing the revision.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| The flare is the only active maneuver. | Add a directional Slipstream dash on Shift or a touch button: a short burst, brief protection, and a separate 4.2-second recharge. | A second escape decision and a more expressive skiff. | An additional control to learn; an overly frequent dash could trivialize threats. |
| Victory has little reason to optimize return routes. | Reward uninterrupted full three-ember returns with a resonance streak: +75, +150, then +225; hits reset the streak. Keep the fifteen-ember objective unchanged. | Full holds become a deliberate risk / reward choice and scores offer replay goals. | More scoring rules; interrupted or partial deposits earn normal points without the full-return bonus. |
| Extra points would make old personal bests incomparable. | Use a separate browser record for the new scoring rules, leaving the previous record stored. | Fair comparisons within the current rules. | The new scoreboard starts fresh. |
| Small actions need clearer feedback; the ending panel masks the restored star. | Add delivery ribbons and point labels, stronger tide-specific nebula colors, an exposed sunrise beside / above the results, and end-of-flight maneuver statistics. | Players can read their actions and see the payoff of restoration. | Additional effects cost rendering time and must respect reduced motion. |
| Prior software-rendered Chrome averaged 23.055 ms per frame; broad background gradients are redrawn every frame. | Cache the static starfield, grid and nebula backdrop; animate only selected stars and the active scene. | Less repeated painting without losing the atmosphere. | A cached canvas uses extra memory and must invalidate on resize and tide changes. |
| Resize currently grants a shield even for minor size changes. | Remove free shield refreshes and apply the dash shield only on a successful maneuver. | The new invulnerability mechanic has predictable rules. | Orientation changes no longer award extra protection. |
| First visual checks of the new ending found the result card clipped at 320 pixels, while rapid delivery labels overlapped. | Anchor phone results above the stage bottom with a scrollable height bound, hide the flight HUD after victory, and combine nearby point labels. Activate touch abilities on pointer-down so a second finger can act while steering. | A complete phone ending and readable feedback with practical two-finger controls. | Constrained result panels may scroll on short screens; touch actions occur on press rather than release. |

Verified results for 1.1.0: 27 simulation checks and 33 browser checks passed. Dash direction, duration, charge, shielding and paused timers were checked; full / partial / interrupted deposits, capped streaks, final-haul bonuses and hit resets were checked. Native keyboard dash, touch activation, simultaneous two-finger steering / dash, phone result bounds, cached-atmosphere invalidation and old-record preservation passed. All 200 bot routes won: 100 without dash averaged 17.81 seconds and sustained 54 hits; 100 with dash averaged 16.11 seconds and sustained 42 hits. That supports a functional, useful maneuver, not a claim about human mastery or enjoyment. Reviewed desktop sunrise, violet flight, 390-pixel dock and 320-pixel result screenshots. The 120-frame GPU-disabled Chrome sample averaged 16.666 ms / about 60 fps (95th percentile 16.8 ms), compared with the previously recorded 23.055 ms sample. Measurements are specific to this test setup, and the revision changes both rendering and gameplay.

## Expansion / 1.2.0 — Eclipse Fronts

Decisions recorded before implementing the revision.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| All prior bot routes won, and both abilities primarily address individual shades. | Add warned, expanding coral storm fronts with mint-colored safe gaps; a flare cuts additional openings and a protected dash can cross a band. | Route planning and ability timing should interact with the arena itself. | Another hazard to learn; visual gaps and collision rules must agree. |
| One difficulty cannot serve both first flights and repeat mastery. | Keep a forgiving Dawn profile and add an optional Eclipse profile with faster / more frequent shades and recurring fronts. Explain the difference before launch. | Players can choose an appropriate challenge. | More UI and separate best-score records; bot outcomes cannot establish human difficulty. |
| Fly again currently generates a different layout, limiting route comparison. | Assign each voyage a visible seed, reset the generator on retry, and provide separate Retry voyage and New voyage controls. | The same inputs reproduce the same voyage; practice becomes reviewable. | Different routes still consume randomness differently, so later arrivals can differ with player choices. |
| Scores earned under different hazard profiles should be distinguishable. | Store independent Dawn and Eclipse personal bests for the new rules and retain all prior keys. | Fair mode comparisons and no erased history. | Each new mode record starts fresh. |
| Stage repair feedback claims a repair even at full hull, and end statistics have awkward singular labels. | Make repair messages conditional and format flight counts grammatically. Add front-cut statistics and mode / seed labels. | Feedback describes what actually happened. | Slightly more result copy. |
| Visual review found overlapping FRONT OPEN labels after quick successive cuts. | Reuse a nearby identical status label while keeping separate score labels. Verify both mode retries and sample the renderer with three active fronts and thirteen shades. | Cleaner feedback and stronger evidence for replay and rendering behavior. | Closely spaced identical cues merge into one; the heavy-scene sample is a scripted rendering scenario. |

Verified results for 1.2.0: 39 simulation checks and 46 browser checks passed, including geometric gap safety, front collision / warning / expiry / pause, flare openings, shielded crossings, repeatable simulation in both profiles, native retry fields, mode records, blocked-storage session records, and 320-pixel mode / result layouts. All 200 Dawn routes won; Eclipse had 198 wins and two losses. Across the routes, Dawn sustained 168 hits including ten front hits and cut 352 fronts; Eclipse sustained 249 hits including sixty front hits and cut 684 fronts. This supports mechanically distinct pressure, not a human difficulty judgment. Both normal and three-front / thirteen-shade rendering samples averaged about 16.666 ms per frame, with 16.7 ms 95th percentiles on the tested GPU-disabled Chrome host. The heavy scene uses controlled state. Reviewed desktop / phone selectors, warnings, open fronts, results and the heavy-scene screenshot. Cosmetic particles remain unseeded; retry determinism refers to the simulation.

## Expansion / 1.3.0 — Constellation Run

Decisions recorded before implementing the revision.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| Repeatable voyages still primarily reward the shortest salvage-return route. | Add one optional three-beacon constellation on the outer orbit. Link nodes in order while carrying all three embers; cargo is retained. Each node awards +50, with an extra +250 on completion. | A longer, riskier route provides another scoring goal without blocking the fifteen-ember ending. | Extra distance exposes cargo to threats; another visual feature must remain readable. |
| Completing a risky detour should help a skiff get home. | Linking the third node instantly recharges flare and Slipstream and grants a 1.2-second shield. Keep hull and cargo unchanged. | A clear payoff and a brief opportunity to escape. | Skilled routes can time the reward to gain extra ability uses. |
| New map content could inadvertently change existing seeded routes. | Generate beacon positions with a separate generator derived from the voyage seed; keep ordinary salvage and arrival randomness unchanged. Translate beacons with the sun on resize. | Existing routes retain their seeded mechanics, and retries reproduce the constellation. | One constellation per voyage provides less variety than a dynamic quest system. |
| Safe front gaps and a new objective could look alike. | Use blue numbered hexagonal beacons and constellation threads, a compact optional-objective HUD, contextual full-hold guidance, and end-of-voyage link counts. | Players can distinguish beacons from mint gaps and understand the cargo condition. | Labels and lines consume screen space; visual review on phones is required. |
| Bonus points change best-score comparisons. | Introduce independent v1.3 Dawn / Eclipse records, preserving every previous key. | Scores compare within the same rules. | The current best starts fresh. |
| Phone screenshot review shows the toast overlapping the expanded objective, with small beacon numbers. | Place phone toasts above the ability dock, trim the phone resonance explanation, and keep beacon glyphs at least nine CSS pixels. Full-hold guidance offers banking or linking. | Readable cues with fewer competing text regions. | Phone guidance is more compact; complete explanations stay in How to play. |

Verified results for 1.3.0: 50 simulation tests and 55 Chrome checks passed. Full-hold gating, link order / range / one-time scoring, +400 total, cargo retention, final recharge / shield without healing, progress persistence, reset, pause, resize and normal-input route completion were checked. Browser checks verified visible guidance / rewards / ability states / result counts, help copy, native retry, preserved previous record keys and real touch steering through a beacon. Phone screenshot review confirmed readable numbers and separate toast / HUD / dock regions.

All 400 direct routes retained every preceding-release gameplay result field except score: incidental beacon links raised sixteen runs' scores. All 400 deliberate constellation routes linked every beacon; Dawn won all 200 and Eclipse won 189, with eleven defeats. Average route times rose from 17.66 to 23.76 seconds in Dawn and from 18.27 to 25.11 in Eclipse. Eclipse hits rose from 249 to 487 across its two 200-route groups; Dawn hits were 168 in both. This supports a mechanically reachable detour with greater Eclipse exposure, not human difficulty or enjoyment. One Eclipse constellation seed / strategy had different win / loss outcomes between orientations; viewport hazard expiry and numerical differences can affect later interactions. Same-viewport retry remains reproducible.

Both 120-frame render samples averaged 16.6658 ms on the tested headless Chrome host with GPU disabled; p95 was 16.8 ms for the ordinary scene and 16.7 ms for the scripted heavy scene. These samples do not establish performance on physical phones or other browsers.

## Expansion / 1.4.0 — Echo Voyages

Decisions recorded before implementation.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| Same-seed retries offer practice but no visual comparison with the previous attempt. | Record a skiff sample every 0.1 simulated seconds; show an optional, non-interactive ghost of the immediately preceding matching seed / mode on retry. Use positions relative to the sun and interpolate position / facing. | A player can compare routes and timing while retaining full control. | An extra moving marker can distract; offer a toggle and keep the ghost subdued. |
| A visible voyage code cannot currently be entered to replay a field later. | Add an optional eight-digit hexadecimal seed field next to Launch, with inline validation and normal form submission. Blank launches randomly; New voyage clears the field. | A recorded code becomes useful for deliberate practice, offline as well as online. | A seed reproduces a field within the current rules; viewport bounds and player choices still affect later hazards. |
| A player could remain in a voyage indefinitely. | Keep one previous attempt in page memory, recording at most the first five simulated minutes and fading the echo after the recorded end. Pause time is excluded. | Bounded memory and predictable playback; no extra storage permissions or uploads. | Reloading clears the echo; long flights have a partial replay. |
| The new aids should preserve existing mechanics and records. | Leave the simulation and scoring unchanged; retain the v1.3 best-score keys. Use a hollow lavender skiff and short dashed tail distinct from the player, embers, beacons and gaps. | A practice aid without changing challenge or score comparisons. | Cosmetic playback is an approximation between ten-Hz samples, especially during a dash. |
| More launch controls may overwhelm narrow title screens, and keyboard shortcuts could interfere with typing. | Put seed and Launch in one compact row, keep a visible field label, and exempt text entry from game shortcuts. Validate phone bounds and native typing / Enter behavior. | A legible title screen and predictable keyboard entry. | Compact phone controls have shorter labels and reduced spacing. |
| Motion preferences should apply to the new visual aid. | Default the echo off when reduced motion is requested, with an explicit toggle to enable it. Return focus to the playfield after toggling. | Less unrequested motion and uninterrupted keyboard play. | The practice aid requires one additional action for those users. |

Verified results for 1.4.0: 61 simulation / recorder tests and 73 Chrome checks passed. Recording cadence / exact final point / bounds / pause / seal / relative coordinates, shortest-angle interpolation / fading, valid zero / blank / maximum seeds and invalid entry were checked. Browser flows verified real Enter submission, inline errors and focus, shortcut isolation, matching retry echoes without current-skiff movement or scoring, live toggles, paused playback, faded ending, seed clearing, reload behavior, phone form / touch bounds and reduced-motion opt-in.

All 800 seeded simulation results are exactly equal to the saved v1.3.0 report, and engine.js is byte-for-byte unchanged. That supports the intended mechanical neutrality. The record stays in page memory; existing v1.3 bests remain in use. Desktop / 320-pixel screenshots show a distinct hollow echo and a bounded launch form.

Three 120-frame samples averaged about 16.666 ms / 60 fps, each with a 16.7 ms p95, on the tested headless GPU-disabled Chrome host. The echo stress fixture uses a scripted maximum-length 3001-sample path with three fronts and thirteen shades. This supports functional playback and bounded rendering responsiveness in that setup. Whether players learn faster, and performance on real phones or other browsers, remain expectations rather than verified results.

## Expansion / 1.5.0 — Flight Atlas

Decisions recorded before implementation.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| A live retry echo does not support close inspection of a completed route. | Add Review flight to both endings: a native dialog with a canvas route atlas, a scrubbable timeline and optional double-speed playback. Open at the recorded ending and keep playback stopped until requested. | Players can inspect a route and compare its decisions without launching another attempt. | More result UI; a narrow-screen dialog must remain usable and scrollable. |
| The current recorder stores position but gives no context for a detour or interruption. | Extend samples with cargo / hull / returned embers / score / tide; retain timed delivery, hit, beacon and flare markers relative to the sun. Include a final result separate from the clip. | A map can explain what happened along the route and show state at the selected time. | Ten-Hz samples approximate motion; threats are not reconstructed. |
| Recording indefinitely or densely could accumulate memory or rendering cost. | Preserve the five-minute / one-prior-flight limits, cap action markers at 240, and draw route paths in batches. Fit the map to the entire recorded route and handle modal resize. | Bounded storage and a readable route across aspect ratios. | Long flights show only the first five minutes, with the complete final result stated separately. |
| Review should be a practice aid rather than a change in challenge. | Keep the engine and best-score keys unchanged. Reuse the native modal's pause, focus and keyboard behavior; keep review controls keyboard / touch accessible. | Existing records remain comparable and opening review cannot change the outcome. | Review is available only after an ending and disappears on reload with the page-local record. |
| The first maximum-length atlas sample averaged 19.5825 ms / roughly 51 fps, with a 33.4 ms p95. | Cache the static map / entire faint route per size and pixel ratio, and update state text only when its displayed values change. | Reduce repeated painting and DOM work during replay. | A cached canvas uses memory and must invalidate on resize; measurements remain host-specific. |
| Static atlas caching alone did not improve the measured rate: the next sample averaged 19.86 ms with the same 33.4 ms p95. The frozen scene behind the blurred dialog was still painted every frame. | Keep the main canvas image while a modal is open, repaint on resize / modal opening, and resume ordinary drawing on close. Continue the independent atlas animation. | Avoid identical background painting and repeated blur work during review. | The frozen scene needs explicit invalidation when its canvas size changes; modal and resume checks must cover this. |

Verified results for 1.5.0: 68 simulation / recorder tests and 86 Chrome checks passed. Timed relative markers, whitelist / cap / five-minute / sealed limits, observed state selection, same-time final-state updates, complete results beyond the clip limit, cloned geometry and a complete normal-input recording were checked. Browser checks covered both endings, stopped initial review, keyboard Home, optional playback, pointer / touch seeking, observer cleanup / returned focus, phone controls, modal resize, explicit clip limits and maximum-length playback.

All 800 route result fields exactly match v1.4.0, and engine.js is byte-for-byte unchanged. A normal-input Eclipse seed 17 record restored the star in 20.1833 seconds with 3450 points, all beacons, 203 samples and 24 markers. Desktop and phone review screenshots use that record, injected into a controlled browser ending fixture. This establishes functional route / state review, not a human learning benefit.

The final 3001-sample / 240-marker playback sample averaged 19.0275 ms / about 52.6 fps, p95 33.3 ms and maximum 33.4 ms. The initial sample was 19.5825 ms; static caching alone measured 19.86 ms. The final sample shows a small measured improvement with frozen main painting, not a proven causal speedup across devices. The main paint counter stayed unchanged during review and increased on modal resize. Ordinary, heavy and echo samples averaged about 16.666 ms / 60 fps on the tested GPU-disabled Chrome host. Physical phones, other browsers, human learning and enjoyment remain unverified.

## Expansion / 1.6.0 — Orbital Score

Decisions recorded before implementation.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| The voyage has only short action sounds despite its changing atmosphere. | Compose an original procedural score with three tide harmonies, a slower Dawn / quicker Eclipse pulse, full-cargo bell accents and a low-hull bass layer. Start only when sound is explicitly enabled and a flight is playing. | Music should give each tide a distinct mood and reinforce flight state. | Additional sound may distract; enjoyment and clarity need human listening rather than graph assertions. |
| Players may want cues without music or a quieter mix. | Keep the existing Sound button / M toggle and add a music checkbox and master-volume slider to How to play. Apply master volume to both music and cues; retain preferences in page memory. | A controllable mix without crowding the phone header or changing gameplay. | Settings require opening help and reset on reload. |
| Scheduled sound can linger after muting or continue during pauses. | Use bounded separate cue / music voices, short scheduling lookahead, gain envelopes and immediate lifecycle synchronization on pause, dialogs, blur and visibility. Fade and stop music on interruption, restart its phrase on resume; fade all voices when sound is disabled. | Quiet pauses and predictable resource use, including rapid toggle / resume races. | Resuming restarts the musical phrase; this is a soundtrack rather than an exact historical audio replay. |
| A soundtrack should preserve reproducibility and existing scores. | Read simulation state without changing it, use no simulation randomness, and leave engine / record keys untouched. Test an injected audio graph separately and native browser controls / lifecycle. | Existing voyages and score comparisons remain valid. | Automated tests establish scheduling and control behavior, not speaker output quality or human benefit. |
Verified results for 1.6.0: 83 simulation / recorder / audio tests and 105 Chrome checks passed. Audio graph checks cover opt-in construction, common master mix, tide / mode / cargo / hull layers, state immutability, independent voice budgets, cleanup / disconnect, music-only controls, volume clamping / silence, bounded lookahead / stall recovery, suspended contexts, unavailable audio and a pending-resume / later-mute race. Native flows cover a silent title, playing-only music, current-tide resume, quiet help / notes / atlas / endings / blur, keyboard volume and music toggles, cue voices with music disabled, master mute, retained page settings, reset on reload and real phone touch. The cue check activates the Flare button after closing help: focus correctly returns to Help, where Space retains normal button behavior.

All 800 voyage result fields exactly match v1.5.0; engine.js, voyage.js and atlas.js remain byte-for-byte unchanged. Existing best-score keys remain in use. Reviewed desktop and 320-pixel sound settings, with labels / slider / checkbox fitting inside the native dialog.

A real OfflineAudioContext rendered twelve seconds at 24 kHz across the three tide harmonies, full-hold and low-hull layers. Every sample was finite; absolute peak was 0.04949, overall RMS 0.00717, with nonzero RMS in all four three-second segments. This establishes produced audio without sample clipping in the controlled render; it does not establish listening quality, perceived loudness, musical preference or real speaker output. The preview uses scripted state, not a historical flight reconstruction.

Ordinary, heavy and echo renderer samples remained around 16.666 ms / 60 fps; the maximum atlas sample averaged 19.0275 ms, p95 33.3 ms, on the same GPU-disabled headless Chrome host. These samples do not establish performance on physical phones or other browsers. Audio startup and native node lifecycle were checked, but human immersion remains an expectation.


## Expansion / 1.7.0 — Nightglass Prisms

Decisions recorded before implementation.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| Shades chase and needles fly straight; surviving mostly rewards moving away from bodies. | Add stationary Nightglass prisms with a visible aiming corridor, an initial tracking interval, a locked warning and a short damaging beam followed by cooldown. Introduce a guaranteed prism in Dawn's final tide and Eclipse's second / third tides; limit simultaneous prisms to three. | Dodging a committed line should create another timing / positioning decision and a distinct visual enemy. | Extra rules and long-range pressure; warnings must agree with collision geometry and allow time to move aside. |
| An added threat should connect with familiar abilities. | Flare destroys a prism in its existing 175-unit radius for the usual 25 points; protected Slipstream can cross its beam. Preserve hull, cargo drop and shield rules. | Players can choose evasion, an offensive approach or an ability crossing. | Prisms at range cannot be cleared by a distant flare; dash invulnerability remains brief. |
| Dawn should remain a forgiving introduction. | Keep the first Dawn tides and Eclipse's first tide free of prisms. Replace some later enemy arrivals rather than increasing the thirteen-enemy cap; keep existing tide shields and repair. | New pressure appears gradually while preserving a reachable basic voyage. | Normal seeded routes may change later; automated routes cannot establish human difficulty. |
| A beam body could resemble a blue constellation beacon or an unmarked safe line. | Draw a coral triangular device, a dashed corridor while charging, a solid luminous firing band, a warning countdown, tide guidance and concise help. Count prism hits / clears in the result. | Shape, color and phase should distinguish the threat from friendly content. | Another annotation can compete with the existing front / objective HUD, especially on phones. |
| Changed hazards invalidate direct comparison with earlier bests. | Start v1.7 Dawn / Eclipse personal-best keys while preserving all older keys and release records. Consume the same number of spawn RNG calls; retry the new rules deterministically. | Fair records for the new challenge and reproducible practice. | Current mode bests begin empty; matching an older seed no longer reproduces the older hazard rules. |
| Collision and rendering should share one definition of the ray. | Export bounded beam geometry, use it for collision and rendering, and test endpoints, lock timing, protection, phase transitions, pause, resize, flare and same-seed replay. Run both unchanged legacy bots and a beam-aware steering bot. | Evidence can distinguish a real hazard from a cosmetic line and establish reachable ordinary-input counterplay. | Bots and controlled browser fixtures do not establish enjoyment or real-device readability. |
| Phone review shows readable prism warnings at the tested position, but the existing HUD still says ORBIT CLEAR during a beam. Devices can also spawn close enough to an arena edge to clip their label. | Add prism / combined-threat HUD text and clamp measured warning labels inside the canvas, using a short leader when a label shifts. Verify edge labels on a 320-pixel screen. | The HUD should reflect live beam danger, and warnings should remain readable near arena edges. | Edge labels can move away from their device; leaders add a small amount of visual ink. |

| Final source review found that the new enemy classification used a data field named type, which could overwrite the warning event’s identifier. | Keep the warning event name and emit the classification as enemyType; assert both in the spawn / retry check. | Arrival events should retain their established contract for every consumer. | One explicit metadata field; no new gameplay behavior. |

Verified results for 1.7.0: 100 pure tests and 123 Chrome checks passed. Seventeen added simulation checks cover finite / round-ended beam geometry, arrival safety, tracked then locked direction, charge / fire / rest transitions, stationary position, one hit with shield recovery, cargo / resonance loss, safe range / footprint, protected dash crossing, reachable / distant flare behavior, ordinary kill points and counters, staged introduction / cap, pause / ending, translated locked rays and retry / spawn-RNG determinism and retained warning-event identity. The reset-stat assertion now includes the two new counters. A skiff just behind the beam can still touch the device’s larger body; endpoint tests distinguish beam range from that contact hazard.

Native browser checks establish keyboard evasion, protected crossing, touch escape, reachable flare kills, updated HUD / cargo / hull / result counts, recorded hit markers, help, quiet review, current records / preserved old keys, phone geometry, measured labels at all four edges and reduced-motion threat information. Desktop locked / firing / hit scenes, phone warning / edge warning and heavy / reduced-motion scenes were visually reviewed. The edge label remains inside the canvas with a leader back to its device.

The unchanged steering strategy won 794 of 800 routes: Dawn direct 200/200, Dawn constellation 200/200, Eclipse direct 200/200 and Eclipse constellation 194/200. It sustained 32 prism hits and cleared 120 prisms. Beam-aware steering won 790 of 800: the same first three groups all won, and Eclipse constellation won 190/200. It sustained two prism hits and cleared 110 prisms. Both strategies linked all beacons in all 400 deliberate constellation routes and had no timeouts. The beam-aware strategy steers perpendicular to an impending corridor through ordinary input; it does not override simulation state. Fewer beam hits came with more overall losses in these routes, so this supports counterplay rather than a universally superior strategy. The preceding release’s unchanged bot won 787/800: replacing some moving threats with stationary devices can ease some routes; the verified change is varied hazard behavior, not uniformly higher difficulty. 544 of 800 legacy result records changed in at least one pre-existing field.

The normal-input recorded Eclipse seed 17 still finished after 20.1833 seconds with three hull and all beacons, now with 3425 points, 203 samples and 24 markers. The recorder, atlas and soundtrack source are byte-for-byte unchanged. Their existing hit / score recording handles the new device; the atlas still does not reconstruct threats. New v1.7 best keys preserve earlier records and establish fresh comparisons under the new hazards.

The 120-frame prism stress fixture uses three held-open beams, ten additional enemies, three fixed fronts, a long shield and enabled music. Its mean was 16.6658 ms, p95 16.7 ms and maximum 16.8 ms. This deliberately holds firing longer than gameplay to stress painting, not to represent a natural flight. Ordinary / heavy / echo samples remained around 60 fps; maximum atlas playback averaged 19.8608 ms, p95 33.4 ms. Measurements are from GPU-disabled headless Chrome on Windows. Human enjoyment / difficulty, physical phones and other browsers remain unverified.

The final repeat retained all 123 Chrome passes after the warning-event identity fix; all 1600 route fields exactly matched the initial new-rules reports. The final documentation records that repeat’s rendering measurements.


## Expansion / 1.8.0 — Flight Guide

Decisions recorded before implementation.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| The game has many readable rules but no immediate visual indication of a useful next destination. | Add an optional gold / blue flight guide: select a nearby available ember while gathering, then the sun with a full hold. Draw a subdued dashed course and destination reticle, with a concise HUD label. | New flights should be easier to navigate and gathering / banking intent should be clearer. | Additional marks can compete with danger lines; keep them faint, distinct in color and freely toggleable. |
| Full holds can bank or take the optional constellation detour. | Offer a Bank route / Beacon route button when the hold is full and beacons remain. The guide marks the next blue node in order; after completion it points home. | Players can make the risk / reward route choice explicitly. | A goal marker does not find a safe path around threats; the player still chooses movement and ability timing. |
| Repeated nearest-target selection can flicker when two embers are similarly close. | Keep the current ember until another is over thirty world units closer; skip locked scattered cargo and select a fresh target after pickup. Keep all target data independent of simulation objects. | A steadier visual destination without changing collection rules. | The displayed ember may be slightly farther than the absolute nearest. |
| More HUD controls can burden phone layouts and keyboard focus. | Use compact controls under the existing objective, restore canvas focus after button use, and provide G / R shortcuts with text-entry / modal guards. Verify real touch and objective / toast / dock bounds. | Navigation remains usable on desktop and phones without interrupting steering. | Extra HUD height; labels and controls need explicit narrow-screen review. |
| A guide should not alter the challenge or records. | Read simulation state only, retain the engine and v1.7 best keys, preserve guide on / off within the page, reset route intent to banking for each launch, and use static guide marks under reduced motion. | Existing voyages remain comparable while guidance remains optional. | Navigation benefit and enjoyment require human playtesting; automated equality only establishes mechanical neutrality. |
| Final HUD review found that an ended flight would otherwise show Awaiting an ember, despite having no destination. | Suppress route choice after endings and show Voyage ended / Voyage complete. Add an ending-status browser assertion. | Guidance should describe the current flight state accurately. | Guide on / off remains available as a preference for the next attempt. |


Verified results for 1.8.0: 113 pure checks and 140 Chrome checks passed. Thirteen guidance checks cover unlocked selection / copied target data, exact hysteresis threshold / near ties, post-pickup selection, lock expiry, partial / full holds, numbered beacon progression / final banking, toggle / reset, seed / translated coordinates, inactive / paused states, invalid intent / positions, frozen simulation input and identical entire simulation snapshots through a same-input ending. This last fixed-input fixture ends in defeat in both copies; its purpose is state neutrality, not a winning-strategy claim.

Native browser flows verify a live ember target, G toggles / repeat isolation with unchanged paused movement and score, real cargo pickup / bank targeting, R and button intent, sequential beacon updates / final home target, cargo gating, help / modal isolation, ending status, retry preference / banking reset, seed typing isolation, 320-pixel control / toast / dock clearance, real touch and static reduced-motion presentation. Reviewed gold gathering / bank marks, blue beacon routes and phone / reduced-motion guidance.

All 1600 route result fields exactly match v1.7.0, and engine.js, voyage.js, atlas.js and sound.js remain byte-for-byte unchanged. Legacy steering retained 794/800 wins; beam-aware steering retained 790/800. Both had no timeouts and linked all beacons in every deliberate constellation route. Existing v1.7 bests remain in use.

Five 120-frame samples measured ordinary / heavy means 16.6667 ms, echo / prism means 16.6658 ms, with 16.7 ms p95 and 16.8 ms maxima. Maximum-length atlas playback averaged 19.9992 ms, p95 / maximum 33.4 ms. The guide remains enabled in the gameplay samples; stress states are scripted fixtures. These measurements establish the checked behavior on GPU-disabled headless Chrome on Windows. Faster human navigation, enjoyment, physical phone performance and other browsers remain expectations rather than verified results.


## Expansion / 1.9.0 — Flight Signals

Decisions recorded before implementation.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| Finding a specific action on the atlas requires repeated timeline scrubbing. | Add a timestamped signal list, type filter and previous / next controls using the existing bounded action record. Preserve simultaneous signals as distinct entries. | Players should reach a useful review moment more quickly. | Extra dialog controls and vertical space; use a short scrolling list with native buttons and a narrow-screen layout. |
| Route lines alone do not identify the selected action clearly. | Draw a static colored selection halo at the stored marker position and show its kind, time and distance from the sun. | The selected signal should be easier to locate and compare with the ship's route. | The marker is the action location; delivery markers belong at the sun, and ten-Hz ship poses are approximate. Do not infer unrecorded causes or threat positions. |
| A single still frame gives little sense of an approach. | Offer an explicit Replay approach action from two seconds before the signal through one second after it, clamped to the recorded interval, then stop. | Players should be able to examine their steering around an action with little setup. | Playback remains at the existing ×2 speed; it shows recorded motion and actions, not reconstructed hazards. Motion only begins after an explicit action. |
| Review controls must not affect rewards, retry seeds or the ended flight. | Keep event selection in a separate read-only model; clear it on manual scrubbing, preserve stable ordering, and retain engine / recorder / soundtrack and score keys. | Existing voyages and records remain comparable. | Automated checks establish mechanical isolation, not human learning or enjoyment. |
| A bounded record can omit late actions or overflow its signal cap. | Explain the first-five-minute / 240-signal recording limits in the atlas and keep final results separate. Show an explicit empty-filter state and disable unavailable navigation. | The review should describe the available evidence accurately. | Late-flight details cannot be recovered; avoid presenting the list as a complete history when limits apply. |

Implementation layout decision: the longer review dialog can scroll its original close control out of view. A sticky atlas header keeps Close reachable while inspecting lower signals. Expected benefit: reliable exit and focus restoration on narrow screens. Tradeoff: the header occupies a small persistent strip and needs an opaque background so scrolled content stays readable.


Verified results for 1.9.0: all 123 pure tests passed, retaining 113 earlier checks and adding ten signal tests for stable simultaneous ordering, validation / identity, time / marker bounds, filtering / selection, navigation boundaries, approach clipping, empty / zero-duration records, frozen input isolation and tenth-second clock rollover.

All 157 Chrome checks passed, retaining the preceding 140 flows and adding seventeen signal checks. Native select keyboard filtering, exact event jumps, same-time hit / flare distinction, explicit approach playback / automatic stop, keyboard row activation, manual seek clearing, real phone touch, 320-pixel bounds / sticky Close, static reduced-motion selection, unchanged desktop simulation / recorded evidence, resize-neutral rewards / time, close / focus restoration, zero-length clips and empty filters were verified. Reviewed desktop selected-hit, phone selected-beacon, reduced-motion and empty-filter captures. An initial timing assertion needed a floating-point tolerance; another compared absolute world coordinates across a normal viewport translation. The final assertions verify exact stored marker times and unchanged rewards / time while recognizing existing resize behavior.

Engine.js, voyage.js, sound.js and guidance.js match the v1.8.0 ZIP byte for byte. The existing normal-input Eclipse seed 17 review route was generated again by the browser test and retains its completed score / record assertions. The prior 1600 route reports were not rerun because simulation code is unchanged; this release makes no new route-completion claim.

Five 120-frame rendering samples measured ordinary / heavy / echo / prism means of 16.6658 ms, p95 16.7 ms except echo 16.8 ms, maximum 16.8 ms. The maximum atlas with 3001 poses and 240 signals averaged 19.5825 ms, p95 / maximum 33.4 ms. The bounded list builds once per filter; playback updates selected row styling only when selection changes. These are controlled rendering fixtures on GPU-disabled headless Chrome on Windows, not physical-phone measurements. Faster review, learning, musical preference and enjoyment remain expectations requiring human playtesting.


## Expansion / 1.10.0 — Flight Distinctions

Decisions recorded before implementation.

| Problem / opportunity | Chosen approach | Expected benefit | Relevant tradeoff |
| --- | --- | --- | --- |
| After restoring the sun, the next voyage offers mainly a score target. | Add three optional distinctions: Sunwarden (win without hull hits), Starweaver (win with all three beacons), and Resonant (win after reaching resonance ×3). Read existing simulation facts; add no score bonuses or rule changes. | Replays should offer clear routes toward mastery beyond raw score. | These are demanding optional goals, not requirements for victory; reaching a condition before defeat earns no distinction. |
| Players need to understand progress without another live HUD block. | Show a compact distinction strip on the pause and ending panels; explain exact rules and current progress in How to play. Keep the flight HUD unchanged. | Goals should be reviewable without obscuring threats during steering. | Detailed progress requires opening help or pausing; the game already pauses for those interactions. |
| An earned distinction should survive reload and distinguish mode difficulty. | Maintain separate Dawn / Eclipse collections with a small validated local record, preserving every existing score key. Merge repeat awards idempotently and fall back to a page-session collection when storage fails. | A completed goal should become a durable personal milestone. | Collections stay on this browser, can disappear if browser data is cleared and are not transferable achievements. |
| A collected medal is different from an award on this attempt. | Give each result card explicit Earned this flight, Collected earlier or Not yet collected wording, plus a completed-flight summary. Use names / symbols as well as color. | Players should understand this run's outcome and their retained collection. | Compact result cards add height; review 320-pixel endings and keep all actions reachable. |
| New persistence must not affect flight evidence or corrupt older records. | Use an independent read-only evaluator / collection model, validate known identifiers, and test frozen simulation inputs, malformed / blocked storage, mode isolation, reload and both endings. | Existing gameplay, seeded retry, atlas and best records should remain comparable. | Automated checks cannot establish motivation, learning or enjoyment; those expected benefits need human playtesting. |

Implementation review found that phone victory panels became tall enough for automatic Retry focus to scroll the title out of view. Chosen approach: compact the narrow-screen result spacing and put the verbose maneuver statistics in a native Flight details disclosure, expanded by default on desktop and collapsed on phones. Expected benefit: keep the title, medals and retry visible together while preserving every statistic. Tradeoff: phone players need one tap to inspect the longer statistics; changing between narrow / wide layouts resets the disclosure's default state.

The final 320-pixel browser check verified that the compact spacing and collapsed Flight details already keep the title, medals and Retry visible without panel scrolling. An additional proposed reduction of victory prose was therefore not retained; the full victory sentence remains on phones.


Verified results for 1.10.0: 137 pure checks passed, retaining 123 earlier checks and adding fourteen distinction checks. These cover independent victory-only conditions, repaired-hull hit retention, peak resonance, invalid progress, bounded / malformed storage validation, mode isolation / reload, score-key preservation, repeated awards, malformed-record recovery, blocked / quota-failing storage and later recovery, merging another saved milestone, frozen simulation isolation and invalid-mode / defeat rejection.

All 175 Chrome checks passed, retaining the preceding 157 flows and adding eighteen distinction / layout checks. Help and pause progress, three-award victory with unchanged score, atlas final score, retry qualification reset, collected-earlier wording, reload / mode isolation, defeat rejection, repaired-hull conditions, phone defeat / victory bounds, initially visible title / medals / Retry, native touch / keyboard Flight details and blocked-storage session retry were verified. Reviewed desktop pause / earned seals and phone defeat / earned layout. A discarded test setup tried to serialize window after installing a storage block; the final fixture installs the block before initialization and tests actual fallback behavior.

Engine.js, voyage.js, sound.js, guidance.js, atlas.js and signals.js remain byte-for-byte equal to v1.9.0. The browser suite regenerates its normal-input Eclipse seed 17 atlas route and verifies the retained final outcome. The prior 1600 route reports were not rerun because simulation code is unchanged; no new route completion or human difficulty claim is made.

Five 120-frame samples measured ordinary / heavy / echo / prism means of 16.6658 ms; p95 16.7 ms for ordinary and 16.8 ms for the other three; maxima 16.8 ms. Maximum atlas replay averaged 20.9708 ms with p95 / maximum 33.4 ms. These existing controlled stress fixtures use GPU-disabled headless Chrome on Windows. Faster learning, sustained replay motivation, enjoyment and performance on physical phones remain expectations requiring human testing.


## 1.10.1 / separate start measurement

Recorded 2026-10-05 12:07:49 CEST (UTC+02:00, Europe/Zagreb) before implementation. Problem: the user wants collection arrivals and game-specific launches, while the original Lumenwake reports many actions. Approach: share an isolated analytics helper across /ai-games/, send only afterlight_game_start or lumenwake_game_start from a successful new run, and use a canonical landing page_view. Expected benefit: useful separate counts without detailed play telemetry. Tradeoffs: retries count as starts; blocked analytics can reduce recorded counts; GA maintains its own client / session metadata. Local checks establish behavior, not reporting in the GA account. Gameplay and records are preserved.


# Collection 1.0.1 / analytics decision record

Recorded 2026-10-05 12:07:49 CEST (UTC+02:00, Europe/Zagreb), before implementation.

Problem: the collection landing has no tracking; the copied Lumenwake tag automatically measures page views and its older game hooks report numerous actions. The user wants collection arrivals and a separately named start event for each game.

Approach: retain measurement ID G-F8SHB9S9BF. Measure one canonical /ai-games/ page_view per landing-page load. Invoke afterlight_game_start and lumenwake_game_start from their successful run-start functions. Every new run, including a retry, is a start; title visits, invalid seed submissions, pause/resume, notes, and in-game actions are not. Do not emit a shared game_start event or gameplay parameters.

Delivery: isolate the Google tag inside a short-lived, noninteractive same-origin measurement frame. Disable automatic page_view in config, send only the allowlisted event, and disable further collection when its callback finishes. Parent documents have no Google tag; story pages have no tracking. Use fixed canonical page URLs to exclude seeds, query strings and fragments. Keep tracking restricted to HTTPS on evilappliances.net and www.evilappliances.net; local/offline previews remain unmeasured.

Expected benefit: count real arrivals and launches by game with minimal application telemetry and avoid counting title visits as play. Tradeoffs: retries count as additional starts rather than unique players; a disabled tag, network failure or blocker can reduce recorded counts. The shared GA property can still present totals in its standard reports; the game event names remain separate and no cumulative game event is emitted. Google Analytics also manages its own session/client metadata. A browser event check is not proof of processing in the user's GA account.

Verification planned: check event queues / transport using intercepted Google requests, actual game launch controls, invalid seeds, retries, resume and touch. Compare original release entries and gameplay modules against the preceding ZIP. Rebuild and extract a new versioned archive, preserving the preceding release.

## Transport restriction / recorded 2026-10-05 12:19:36 CEST (UTC+02:00, Europe/Zagreb)

Verified problem: the actual Google tag sent an automatic scroll event during the first landing test despite disabled automatic page views and a noninteractive frame. Frame layout changes did not eliminate it. Chosen approach: restrict collection transport inside the measurement frame to its one expected event, suppress duplicates, and filter batched payloads. Cover fetch, sendBeacon, image and XMLHttpRequest transports; parent/game documents remain untouched. Expected benefit: preserve the requested event boundary even when the property's enhanced measurement is enabled. Tradeoff: this small compatibility layer depends on GA's collection format; blocked or unsupported requests are omitted. Real-tag browser checks and transport unit scenarios are required before publication.

Verified: 13 transport unit scenarios and 23 real-tag browser analytics checks passed; these establish checked event generation, not GA account ingestion. All preceding game modules except the tracking hook are preserved.
