- New shared audio voices: js/utils/Sfx.js (playSfxOn/stopSfxOn/sfxPlayingOn)
and js/utils/Music.js (loop voice + shuffle playlist), both with v4 guard
rails (cache.audio.has, stopByKey, isPlaying) so missing assets never throw.
- data/music.json: menu loop, shuffled deep-space soundtrack for GameScene,
and per-world surface loops keyed by planets.png frame; new mp3 assets in
assets/music/.
- data/sfx.json: add ui_hover/ui_click/ui_window/ui_close/mining_loop and a
dedicated scan track; wire UI components (buttons, panels, popups, save
vault) to the shared voice via scene.playSfx seam.
- GameScene: start/stop the shuffle on create/shutdown, stop both soundtrack
and mining hum on 'sleep' (landing launch+sleep) and resume on 'wake';
mining hum loops while beam is live and stops quietly on 'stopped'.
- SurfaceScene: preload and loop the world's track from landing through
takeoff; fix landing frame hand-off to pass sheetFrame instead of the
texture Frame object.
- MenuScene: preload SFX + menu music, start the menu hum in create, stop it
on the 'shutdown' event (v4 never calls shutdown() on transition).
- data/ship.json → stats: hullIntegrity/shields/cargoHold/mineralStorage,
exposed as ship.stats for future combat/trading/mining systems.
- Tests: dev/sfx.test.mjs and dev/music.test.mjs cover the shared voices,
guards, and data contracts; ship-behavior and system-hud tests extended
for base stats and the mining hum lifecycle.
- New SurfaceScene overlays GameScene when the player requests landing:
plays a one-shot landing clip, then a looping surface clip behind a
dedicated command deck (Shop/Build/Ship + Take Off + Menu).
- Wire comms panel "Request Landing" / "Land" buttons to launch the
surface; TAKE OFF stops SurfaceScene and wakes GameScene so the run
resumes exactly where it left off.
- ActionBar accepts an optional `buttons` override so scenes can supply a
different slot list while sharing layout/colors/animation.
- SavePanel gains a `stateScene` option so saves from the surface read
state from the paused GameScene underneath.
- Add data/landing.json (per-frame video map) and four placeholder
surface clips; CommsPanel now passes its full target payload through to
onAction so landing metadata survives the round-trip.
- Add dev harnesses: headless-Firefox screenshot helper, click-path test
for the real user flow, and a surface-flow assertion suite with parked
screenshot pages.
- New CommsPanel UI: world-anchored rusty-metal/green-phosphor console that opens on planet or station click, showing name decode, reputation bar (41 marks, -20 to +20), and REQUEST LANDING / LAND / CANCEL buttons
- New Station entity with procedural rendering (deep-space station ring + solar wings, or waypoint beacon), solid collision, and comms-target support
- data/stations.json configures station kinds, sizes, ship clearance; added to manifest
- GameScene wires click-to-fly + panel open together, handles button/outside/ESC close race, ESC priority, and commsAction seam for future landing logic
- Reputation.marksFor() computes lit-mark count for the gauge; covered by new unit tests in dev/reputation.test.mjs
- Dev tooling: comms-click (real-input interaction test), comms-shot (screenshot states), wdshot setup-step logging
- Introduce `Ship.state` ('normal' | 'mining') with `setState()` and an
`onStateChange` callback so the scene can react to state exits.
- Any player-initiated movement (world click or compass autopilot) now
drops the ship back to 'normal', which ends the mining sequence via the
scene's handler; Mining.update() enforces the gate as a belt-and-braces.
- Rename `Mining.isLocked` to `isActive` and update GameScene click logic:
clicks no longer hold during extension — they move the ship and abort the
arm's reach.
- Tighten the popup-button swallow window from 300 ms to 20 ms and add a
`containsScreen()` hit-test so only the exact button press is consumed,
not subsequent deliberate clicks on the panel area.
- Expand the headless mining test to cover the new movement-abort contract:
world click mid-extension breaks the arm, autopilot retracts the beam,
and ship state transitions are asserted at every stage.
- Generate 4–8 rock groups per system with seeded placement, spacing, and slow tumble/drift motion driven by data/asteroids.json
- Add AsteroidCluster entity (Phaser container) with halo, dust motes, per-rock spins, and ship keep-out collision reusing Planet.resolve
- Integrate clusters into GameScene: load spritesheet, constrain ship post-physics, include in click-to-fly/autopilot/discovery/compass
- Synthesise unique cluster names via NameGenerator.asteroid (syllables + field suffix)
- Add dev test suite and ?seed= param for deterministic galaxy generation
- Load `assets/images/ships-player.png` as a Phaser spritesheet via
`data/ship.json` (`texture`, `frameWidth`, `frameHeight`, `frame`)
- Add `artFacing` config; Ship applies a constant `artOffset` so heading
math is unchanged while the frame art (facing north) renders correctly
- Scale sprite as `(size * scale) / frameWidth` to preserve the 46 px world
hull size and collision radius regardless of frame dimensions
- Fall back to the built-in procedural dart when the sheet is missing or
fails to load, with a console warning in GameScene.create()
- Update ship-behavior tests to account for `artOffset` in heading checks
- Add source art (`ships-player.psd`, landed-ship reference) and a demo
video; document the new pattern in README and PROJECT_NOTES
- Discovery rule: ship within `discovery.distance` (540 px) of a world's edge discovers it once per system; state is pure, save-ready (`Discovery.toJSON/fromJSON`)
- Off-screen compass (`DiscoveryCompass`): themed screen-edge arrows with type/name chips point back at discovered worlds; geometry helpers (`edgeAnchor`, `circleInView`, `lerpAngle`) exported for Node tests
- Solar-system layout: `layoutSystemPlanets` places generated worlds in a deterministic annular band around the home world, enforcing edge-to-edge separation and per-class scale/tint from `data/planets.json`
- All system planets are solid to the ship (collision + click-clamp), not just home
- Rim ping + HUD toast on discovery (`celebrateDiscovery`)
- New planet class pools (rocky/gas/ice/lava) with frames, `classScale`, `classTint`, and `typeLabels`
- Smoke-game dev hooks: `?ship=x,y` and `?near=px` for screenshotting discovery/compass states
- Node test suite (`dev/discovery.test.mjs`) covering rule boundaries, per-system state, JSON round-trip, layout bounds/determinism, compass geometry, and class pools
- Allow planet kinds to specify multiple sheet frames and pick one with a seed-derived Rng so the same galaxy always gets the same home world.
- Add Ethnocentric and Centauri font assets.
Adds the player's home planet to the starting system, rendered from the new
planets.png spritesheet. The planet is a solid disc: the ship may come within
shipClearance of its rim but can never cross it, and clicks on the planet
clamp to the keep-out rim so the ship always has a reachable destination.
- js/entities/Planet.js: solid-disc entity with a circle keep-out constraint
(constrainShip/resolve, pure and scene-free) plus edgePoint/aimPoint helpers
- data/planets.json (+ manifest entry): texture, frame size, scale, homePlanet,
shipClearance, spawnDistanceFromEdge
- Ship.js: exposes a radius (half the hull width) for the keep-out math
- GameScene.js: loads the spritesheet, spawns the home world at the origin,
starts the ship ~150 px off its rim in a seed-derived direction, and applies
the constraint each frame after the ship moves
- dev/planet.test.mjs: Node tests of the constraint against real config;
dev/test-game.html gains a <base href> so asset paths resolve from /dev
- 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