- New `js/visuals/EngineFlare.js` drives nozzle glow, ignition burst, and a short fading exhaust plume from the two side-pod engines, driven by the ship's live throttle so braking dims it and Shift+click lights it up full
- Configurable via new `thrustFx` block in `data/ship.json` (enabled flag, core/plume colors)
- Hooked into GameScene lifecycle: created per scene restart, updated from the scene clock, cleaned up on landing sleep and scene destroy so nothing survives frozen mid-glow
- Add dev harnesses for visual verification: `dev/engine-flare-test.mjs` (headless Chromium CDP walk through idle → ignite → burn → coast → settled with screenshots) and `dev/particle-probe.{html,mjs}` to confirm particle velocity follows the emitter's heading
- Add new arid planet art asset
- Play a soft thunder SFX (sfx_thunder_01..04 at volume 0.35) on the
strobe's 0→>0 edge, once per strike; mid-strobe frames stay silent.
- Move `wasOn` latch after the thunder check so it reflects the previous
frame's state (fixes arm-frame and edge detection).
- Add `thunder: false` config to silence the voice while keeping the bolt.
- Cover with tests: arm frame silent, one clap per strike, mute path.
- New NebulaLightning visual: jagged edge-to-edge bolt with branches,
strobed in the gas base/accent colors, plus a soft distant thunder clap
- Pure seeded math (boltStrobe, strikeCycle, boltShape) in SystemEffectsMath,
Node-tested for determinism and shape correctness
- Wired into GameScene create/update/destroy lifecycle
- Config block in data/systems.json types.nebula.effect.lightning; docs
updated with tuning notes and smoke-game probe (?lightning=1&forceStrike=1)
- Add `front` block to game.json: depth-11 clouds above the ship (parallax > 1) that drift past the player, creating a "flying through" feel vs. the back layer at depth 3
- Implement `shiftHue` in Color.js to derive the front accent from the system's base atmosphere color (hue rotation + lightness lift), making every nebula a stable two-tone gas
- Refactor NebulaAtmosphere into a data-driven layer array with per-layer depth/tint/parallax/drift; extract `spawnCloud` helper; scale swirl speed by configurable drift
- Add 21 new test checks covering accent math (hue delta, identity, white/black preservation, all 8 palette shades) and two-layer structure (depths, tints, parallax ranges, wrapping, destroy, revert path)
- Stub `Phaser.Math.Between`/`FloatBetween` in phaser-stub for Node tests
- Update PROJECT_NOTES.md to document the two-layer model, accent derivation, and new tuning knobs
- Play thunder claps on habitable storm strikes, solar-flare SFX on red
dwarf flare onset, and solar-buzz on binary light-trade midpoint
crossings, all via the shared Sfx voice (new playSfxOneOfOn helper)
- Add per-context music volume overrides (music.volumes) so each context
can deviate from the global mix; menu ships at full volume
- Expand surface music frames to cover rocky and ice worlds (frames 6-11)
- Teardown per-system effect layers on scene restart (jump) so a previous
system's storm doesn't keep striking and playing thunder in the new one
- Update planets.png sheet, add gasgiant-03/rocky-01/rocky-02 tracks, and
register the new SFX assets in GameScene preload
- New StormLayer renders purple cloud clusters with a seeded charge → strike → afterglow envelope in the upper sky, using sprite compositing (back/flash/front trios) rather than shaders
- Add `stormEnvelope` + `sstep01` to SystemEffectsMath.js; refactor NebulaAtmosphere's cloud shape into a shared `cloudAlpha` used by both `drawCloud` and the storm's flash texture
- Extend EmberField with optional per-spark twinkle (rate/depth) so habitable fireflies pulse while redDwarf embers stay steady
- Wire StormLayer create/update/destroy into GameScene alongside the other content effects
- Populate `types.habitable.effect` in systems.json with grade, void, particles, and storm blocks; update landing.json to use ice land/takeoff videos for slots 02 and 03
- Add 7 new test checks covering the storm envelope math, habitable data contract, bundle sanity, and facade apply(); bump live types from three to four
- Add VoidBase content layer (neutral dark+grit surface at depth -1) so the
grade shader's two-light shadow lift can paint amber/azure onto the void
(the clear color bypasses filters)
- Extend grade shader with uLift2* and uBreath uniforms: side A glows color 1,
side B glows color 2 across the seeded axis, with a slow sinusoidal trade
- Wire breath period/depth from config into per-frame update()
- Rework WandererStar to anchor to the camera view each frame (wrap-in +
parallax trail) so it stays visible in the sky regardless of ship travel;
increase default core/halo sizes for a more present companion star
- Update systems.json binary effect with lift, breath, void config and larger
wanderer sizes
- Add test coverage for the new two-light lift, breath animation, and shader
uniform declarations (59 checks total)
- Replace the single `kind: ripple|none` effect with optional per-type blocks (ripple, grade, flare, haze, particles, wanderer) so each archetype wears exactly what it lists
- Add redDwarf visual identity: super-subtle star-anchored ripple that surges on a seeded flare, warm color grade with shadow lift + grain, a gritty red haze behind the stars, and drifting ember dust
- Add binary visual identity: two-color directional split grade plus a wandering companion star (no ripple)
- Generalize the ripple shader/filter to up to two orbiting centers and drive both the ripple amplitude and the grade flash from one shared flare signal
- Stamp per-system fx variation (phase/angle/drift) in SystemGenerator so each system's flare rhythm, split axis, and wanderer path are stable but distinct
- Add EmberField, RedHaze, WandererStar content layers wired into GameScene create/update/shutdown
- Update the data contract, 57-check test suite, project notes, and landing/systems JSON; add ice landing/takeoff video assets
- Nebula gas layer: soft coloured cloud sprites at depth 3, tinted with a
per-system palette color assigned deterministically at galaxy generation
(SystemGenerator stamps content.atmosphere.color). Only nebula-type
systems render it; all other types are untouched.
- Ripple effect: a full-screen WebGL composite on the world camera that
displaces the starfield and world objects while the HUD stays crisp via
a new UI/world camera split (UiCameras.js). Data-driven per archetype in
data/systems.json (nebula = ripple, all others = none). Canvas fallback
degrades to no effect.
- Demo mode: ?fx=<type> URL param retargets the run to the richest system
of that archetype, fully charted with all gates active, for judging the
effect in isolation.
- New ice and lava planet art (slots 9–14 in planets.png) replacing the
placeholder terran/rocky/gas reuse.
- Node test suites for the nebula palette/determinism/cloud texture and
the ripple math/data contract/shader/facade (50+ checks, bare Node).
The overlay was drawing the sweep image and glitch burst bars at negative-x offsets (e.g. `-w/2`) as if in a centered coordinate system, but Phaser graphics/images live in scene space starting at 0. This shifted the sweep left by half the viewport and clipped the glitch bars off-screen. Anchor them to `0` / `w/2` so they align with the visible area.
- Boot the game from a static server with no build step (Phaser 4 vendored in lib/)
- Main menu (New Game button) and GameScene where clicking makes the ship fly there
- All tunables live in data/*.json (game/menu/ship), loaded via manifest + Config singleton
- Ship behavior driven by arcade physics (thrust, drag, maxSpeed, arrival) with a Node test harness (dev/ship-behavior.test.mjs) and a dev smoke page that boots straight into GameScene
- Project conventions documented in docs/PROJECT_NOTES.md; README rewritten to describe layout, run instructions, and dev tools