- Ship gains a `thrust` state and `thrustToward()` that commits to the heading toward the click point and holds full throttle past it, until a plain click or stop steers out.
- GameScene pointer handler branches on `pointer.event.shiftKey`: Shift+click locks the heading (raw aim), plain click still flies to the clamped stop point.
- Mining teardown no longer stomps the ship state when the player has already moved it into `thrust`/`normal`.
- Update hint text and add unit tests (tests 7–10) plus a live-scene smoke harness (`?thrusttest=1`) verifying past-click flight, steer-back arrival, stop braking, and mining-exit signaling.
- Extract minerals from the latched asteroid at ratePerSec × miningSpeed; each mineral shrinks the rock by 1 px so the beam stays latched to its rim.
- Break rocks that lose ~1/3 of their original size: large ones halve in place (beam keeps mining one half), small ones shatter into pieces that fly home and load the hold.
- Add ship.minerals hold with addMinerals/setMinerals capped at stats.mineralStorage; a full hold ends the run instead of grinding the rock away.
- Persist the hold in save/restore (captureState writes ship.minerals, applyRestore restores it) and keep legacy saves working when the field is absent.
- Play new mining_split sfx on each break and surface split/absorbed/storageFull events as console toasts.
- Expose AsteroidCluster rock surgery (setSize/addRock/removeMember) for runtime splits, and add headless Phaser stub + loader plus a mining test suite covering extraction, halving, shattering, full-hold stop, and the hold API.
- 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.
- 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.
- 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
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