- Waypoints were comms-only beacons with no landing or trade; a second
deep-space station is a more useful destination in their place
- The old waypoint chance in systems.json becomes
deepSpaceStation.second, so a system can roll 0–2 stations
- StationFrames now assigns a distinct sprite variant per station
(Galaxy.stationFrames is id → [frame, …]) and a two-station system
always wears two different variants
- Rename the route-gate pulse from "destination's waypoint" to
"route's next stop" so the term no longer refers to a removed kind
- New ShimmerCue module: pure shimmerPhase/drawShimmer cycle (yellow band sweeps face, comet runs cut-corner edge), shared by both surfaces
- ActionBar gains setShimmer + a dedicated additive layer; the RESEARCH slot wears the full face+edge recipe while a tech can start and the console is closed
- ResearchWindow._paintCues paints the edge-only shimmer on every category tab whose tree still holds an available tech, plus the ACK pulse on the "Unlock Jumpgates" plate (or SYSTEM tab when off-screen)
- GameScene._applyResearchCue switches one cue at a time: deck slot when console closed, console cues when open; rests while a project runs (maxConcurrent 1), under standby, or under the tutorial finger
- ResearchModel.hasAvailable and SystemCategory.gatesReady/gatesNodeId encode the ready rules
- data: actionbar.json animation.shimmer, research.json fx.tabShimmer (#ffd84d, comm-pulse yellow family)
- dev: Node test (research-cue.test.mjs) pinning the pure cycle model + slot/tab behavior; browser verify page (research-cue-shot.html/.mjs) with CDP capture poses
- assets: arid-surface-03 / arid-takeoff-03 videos
- New TutorialGuide.js beat table picks which control to pulse based on live comms/research records, so a loaded run resumes the same beat
- ActionBar and ResearchWindow gain setHighlight() with pulsing rims (ACKNOWLEDGE-style sonar rings in the console) that hide under deck standby/locked slots/closed window
- GameScene applies the highlight per frame before surfaces draw, tracks scanPressed one-shot, and reads targets from data/quests.json → tutorial
- Add tutorial section to quests.json plus tests for beat table, ActionBar rim gating, and data consistency (slot ids, console node matches starter research check)
The Shop button on the deck is now always live — the shop sub-bar opens on every world. The "Special Delivery" capital-landing witness now gates only the shop's Buy/Sell tab (ShopView reads GameScene.isTradeUnlocked, which replaces isShopUnlocked), so trading stays dark until the player lands on the neutral capital while the rest of the shop UI is reachable everywhere.
- Rename GameScene.isShopUnlocked → isTradeUnlocked and update all references (SaveData, SurfaceScene, quests.json comments)
- Remove the deck-slot enable guard in SurfaceScene.toggleShop / setBarLocked; the slot now re-arms with the rest of the deck
- Add ShopView.isTradeUnlocked + gate checks in setTab / _onTabTap; gray the Buy/Sell tab via _refreshTabs until the gate lifts
- Update dev probes (scout-*, shop-*) to lift gs.story.capitalLanded so the trade panel is reachable
- Extend shop-ui.test.mjs with a TRADE GATE case covering closed/lifted states
- Introduce VignetteHub/VignetteWindow/VignetteModel to play quest-gated
dialogue scenes over location clips on the surface (bar/shop)
- Ship first scene: Special Delivery step 1 (Trestle + Carol at the bar),
replacing the old capitalLanded check with a vignettePlayed witness
- Add q3 speech clips for Carol and Trestle; remove retired q2 Carol clips
- Wire save/restore of the played ledger, deck lock while a scene holds,
per-sound music ducking under voices, and window sizing to each line
- Add dev flow test (dev/vignette-flow.html/mjs) and model unit tests
- Point landing.json ice-land-01 entry at the new arid-* video assets
- Replace the surface deck's SHIP slot with an EXPLORE drawer that folds up a full-width secondary bar (MenuSubBar span mode) carrying per-world service items resolved by a `where` clause matcher (world / planetClass / faction, case-insensitive, list any-match)
- Add the neutral capital's BAR clip toggle: swaps the surface loop for the world's bar video, relabels the slot to LEAVE BAR, and locks every other deck + drawer button until pressed back
- Record quest checklist steps as DONE on the ledger (QuestState.completed set) so a step that stands on the home world keeps standing after the ship leaves; save/load round-trips the witness and old saves degrade cleanly
- QuestWindow fresh open now lands on the run's priority quest (tracker HUD seam) with its tab activated, falling back to the active tab's first quest when no priority is set
- MenuButton.setLabel re-fits the panel and hit rect in place for the LEAVE BAR relabel; ExploreBar.js provides the pure worldContext / matchesWhere / resolveItems item logic
- Add dev tests: explore.test.mjs (deck, items, where-clause, span, relabel) and quest-window.test.mjs (open landing + priority), plus updates to quests/research-builds tests for the new surface deck layout
- New main quest granted after claiming "Leaving the Nest": land at the neutral capital (the bar), upgrade cargo bays, then deliver the sealed package to the home world.
- Introduce a non-tradeable `special-package` good (sheet frame 114) that no shop stocks or buys back; `Economy.isTradeable` filters it out of every floor and the sell grid refuses to queue it.
- Record story witnesses (`capitalLanded`, `launchedFromCapital`, `lastLandedWorld`, `delivered`) in a registry-backed ledger, persisted via SaveData so progress survives load and reset clears it.
- Gate the surface shop behind the capital landing: deck slot disabled and `toggleShop` refuses until `isShopUnlocked`.
- On capital departure, set the destination back to the home world so the compass marks the delivery leg; delivery proof is monotonic once recorded.
- Surface console note announces the package handoff when it first lands in the hold.
- Extend economy and quest test suites to cover the new check types, non-tradeable exclusion, unlock chain, and save/load of the story ledger.
- TradeScout now resolves each exit's specific object (planet of that class, deep-space station, or home world) and exposes objectId/objectName so the destination points at the route's final stop rather than a bare system.
- SurfaceScene dialog and toast show "WORLD · SYSTEM" and pass the object id to GameScene.setDestination; null falls back to system level.
- ScoutPanel exit rows display the world name + hops instead of the class label, drop the per-section tap hint and footer (they collided with the last row in a short panel), and rename "SIGHT ON" to "SOUGHT ON".
- Save/restore now carries ship.credits and ship.cargo across jumps; GameScene restores both and refreshes the credits HUD. Saves tests cover capture, prepare, and legacy records without these fields.
- trade-scout tests assert every exit has objectId/objectName and that resolved ids are real objects of the exit class; scout-dest test verifies the confirmed destination names a real world.
- Add dev/scout-overlap probe (html + mjs) to screenshot the scout panel and numerically report any overlapping text boxes.
- Ship lava-planet-03 art and lava-land-03 video assets.
- Trade scout best-exit rows now open a "SET DESTINATION" confirm dialog
(SurfaceScene.askSetDestination + ConfirmOverlay), confirming sets the
GameScene destination; local-system exits are rejected with a note.
- Surface scene builds a corner credits/minerals readout over the shop clip,
refreshed after trades and torn down on leave.
- Sell-bay selection restyled: green stroke + tinted fill + upper-left
checkmark badge (data/shopui.json slot config), replacing the cyan ring.
- Add lava/capital-neutral music, videos, and landing data entries; remove
tresle.png in favor of capital-neutral-surface.png.
- New dev probes: scout-dest, shop-hud, shop-select-shot, map-dest-shot,
cdp-cast; extend shop-ui.test.mjs for selection visuals and exit taps.
- New js/ui/PerimeterShimmer.js: constant amber base rim + glow, and two comets in counter-streams (amber CW, neon cyan CCW) tracing the cut-corner plate perimeter; pure arc math (perimeterPath / arcPoint / arcPolyline) exported for bare-Node tests
- QuestTrackerHud promotes READY rows to the console's cut-corner plate (CyberShape.rectPoints), drives PerimeterShimmer per-frame on the absolute clock so repaints never reset comet phase, and fires a one-shot rim flash when a row is claimed; shimmers are torn down with each paint
- data/quests.json gains tracker.shimmer config (enabled, notch, periodMs, dashFrac, phaseOffsetPerRow, claimFlashMs, base, comets)
- CyberShape.rectPoints added for absolute-coord cut-corner polygons
- New dev/perimeter-shimmer.test.mjs covering arc math, counter-streams, absolute-phase invariance, degenerate configs; quest-tracker tests extended for shimmer lifecycle and claim flash
- Pressing the open tab now closes the panel (back to entry state) instead of
rebuilding it; pressing again re-opens with the selection restored, so hiding
the panel no longer loses the player's pending trade.
- Save the SELL/BUY maps onto ShopView (_pendingSell/_pendingBuy) on toggle-close
and tab switch; _restorePendingSelection() re-applies them when the panel is
rebuilt. The sub-bar stays live while closed: NET shows the delta, Clear
cancels the saved trade, Confirm executes it.
- preview()/clear()/_afterTrade()/_hasAnySelection() now treat a null tab with a
pending selection as an active trade, so the buyback path is no longer shadowed.
- Rename ScoutPanel.data to report: Phaser's GameObject reserves .data (its Data
manager), and a plain object there crashed GameObject.destroy(). Update all
callers in ShopView, tests, and dev/shop-shot.mjs.
- Simplify the scout price line to credits only ("9 CR") and drop the now-unused
priceSell style from shopui.json; update goods.png/psd.
- Add setSellMap()/setBuyMap() to TradeGrid/BuyList to restore a saved selection
onto freshly rebuilt panels, and cover the toggle flow in shop-ui.test.mjs plus
a toggle probe in dev/shop-shot.mjs.
- Tap a BUY-list row's box (outside the stepper) to swap the cargo grid for a strategy report showing the good's identity, producer/demand classes, and top-N charted exits ranked by sell price with per-unit profit.
- New pure TradeScout module computes the report from galaxy data and visited systems; new ScoutPanel renders it over the SELL grid area.
- BuyList gains tap detection (distinguishing taps from drags), a focus glow on the scouted row, and an onRowTap hook.
- ShopView wires open/close/swap semantics: same box toggles off, different box swaps report, dead-space or panel tap closes and restores cargo grid; sell-grid input is disabled while scout is shown.
- Add Trestle character art, Carol Q2 speech lines, shopui.json scout config section, and tests for both the pure logic and UI integration.
- Widen the tab sub-bar from a button-width pill to the full deck span (left/right edges of the main action bar), centering it on that span.
- Pack tabs at the left edge and Clear/Confirm + NET readout at the right edge, compressing gaps rather than button widths when the deck is narrow.
- Right-anchor the NET value (origin 1,0.5) and reserve its widest slot so growing totals never shift the label or overflow the bar.
- Extend SurfaceScene.shopAnchor to expose left/right edges for the sub-bar layout.
- Add sub-bar probe assertions in dev/shop-shot.mjs and unit tests in dev/shop-ui.test.mjs covering span, alignment, non-overlap, and NET math.
- Add carol character image and lava-land video assets.
- Rows that spill past the viewport edge used to render whole, ghosting over
the BUY title or onto the Confirm bar; now only elements fully inside the
window render (this Phaser build can't crop glyphs), and row plates draw
just their in-window slice for a clean cut.
- Clipped-out steppers are no longer tappable: hit-testing gates on element
containment, not just row visibility.
- Add a right-edge scrollbar (track + drag/jump thumb) that tracks scroll
position and hides when content fits the viewport.
- Extend shop-shot/dev tests to verify the clip invariant, dead-click
behavior, and scrollbar geometry; add a geckodriver screenshot helper.
- Center the row background plate on its own local origin so it no longer double-offsets with the object's world position, eliminating the right/down drift and stretched spacing.
- Switch stepper glyphs to a centered (0.5, 0.5) origin and recompute the tap area live inside hitAreaCallback against the current glyph size, so the box stays centered on the visible button even as qty text re-measures.
- Add dev/shop-shot probes that assert bar fillRect coords and verify plus/minus clicks register on the glyph while a point in the old mis-anchored gap does not.
- Extend landing.json with additional land/surface/takeoff/shop video entries.
The panel was centered as a group; now the SELL grid's left edge sits at
the surface HUD's planet-text left edge (landing.hud.marginX, 24px —
same key the HUD name/line use) so the cargo grid lines up vertically
with the planet name above it, and the BUY list stretches from just
past the grid all the way to the right edge minus that same padding
(1280px window: BUY list 560 -> 770px wide; the 440px floor stays as
the narrow-window fallback). The 16px gap between the panels is
unchanged, and the sub-bar still anchors to the deck's Shop button.
shopui.json's buyList.w is now only the headless fallback width.
The center column is gone: Confirm + Clear move onto the tab sub-bar
([tabs] | [Clear][Confirm] | NET value), serving both the trade and
buyback tabs, so the two panels sit side by side with just a bit of
padding between (grid.centerW 208 -> 16). The row description keeps the
smaller font, word-wraps inside the text column (wrap width stops
before the price), and the char-count budget now spans two lines so the
headless path stays bounded; rowH grows 64 -> 72 to fit both lines.
The buttons persist across tab switches (they were content before and
died with it), Confirm stays grayed while the trade is invalid, and the
stub gains setX/setY so the bar layout is testable.
While the shop clip is on screen (the SHOP slot reads LEAVE SHOP), the
command deck's other slots — Build, Ship, Quests, Take Off, Menu — go
standby: dim, no hover, no press, clicks swallowed — the same inert
language as the 'ack' comm's deck hold. The press that opened the shop
is the only way out; the slots re-arm on LEAVE SHOP (and if the shop
clip fails to load).
js/ui/ActionBar.js setSlotEnabled(id, on) — per-slot lock: arms/
disarms one slot (input off, standby paint);
setEnabled (deck-wide standby) keeps each slot's
flag in sync and still owns input over a
per-slot unlock; setHover/press guard on it;
setLabel no longer repaints a locked slot live
js/scenes/SurfaceScene setDeckLocked(locked) — lock everything but
SHOP on enter (toggleShop), release on leave
(leaveShop) + the broken-clip fallback
dev/actionbar.test.mjs new — slot lock / deck lock / standby-priority /
label-kept-locked, headless
docs/ECONOMY.md §12 the deck-lock bullet
All headless suites that passed before still pass (the five pre-existing
failures — music/quest-tracker/system-hud/galaxy-labels/jumpgate —
import SurfaceScene, which extends Phaser.Scene that the headless stub
doesn't provide; they fail identically without this change).
description + price + stepper) instead of the 4×4 icon grid
Each stock good is now ONE WIDE ROW — the good's icon, its name + a
one-line description (the good's flavor), and the price + a −/qty/+
stepper on the right — the way the user wanted the shop list to read.
The stock (12–16 goods) outgrows the panel, so the list SCROLLS:
drag on the row area or the mouse wheel; rows outside the window are
clipped (row-based alpha clipping — this Phaser build has no
ScrollContainer/camera clip), and hidden rows' steppers are
non-interactive. The selection is data (goodId→qty), so stepping a
good works whether its row is on screen or not.
js/ui/shop/BuyList.js new — the scrollable BUY list (rows, drag +
wheel scroll, per-row steppers, flavor text)
js/ui/shop/TradeGrid.js SELL-only now — the BUY mode (steppers, stock
rendering, buy-selection data) is stripped;
one grid, one purpose
js/ui/shop/ShopView.js composes TradeGrid (SELL) + BuyList (BUY);
the BUY panel sizes itself to the SELL grid's
height (top- AND bottom-aligned)
data/shopui.json buyList row/typography knobs (name, desc,
price, row bg/border, selection accent)
dev/shop-ui.test.mjs BUY assertions rewritten for the list + a new
SCROLL section (scroll clamps, row clipping,
stepping off-screen rows)
dev/shop-shot.mjs BUY probe → the row's inline text (no tooltip)
docs/ECONOMY.md §12 the BUY bullet + mockup now describe the list
The BUY side's name + price used to live in a hover tooltip because a
grid cell is too small for text; a wide row carries them inline, so the
tooltip stays on the SELL side only. All headless suites green
(shop-ui, economy, cargo, builds, ship-behavior).
The pending trade's credit delta now sits at the right end of the
Buy/Sell + Buyback sub-bar, past a hairline divider — tabs AND the
credit math on one console, one glance apart (entry state dims it to
0 cr). The center column keeps Confirm/Clear (re-centered); the
buyback panel's Confirm moves up to sit just below its rows.
Knobs: data/shopui.json → preview (bar sizing, zeroColor, divider).
Docs: docs/ECONOMY.md §12 mockups + bullets follow the new layout.
Tests: dev/shop-ui.test.mjs asserts the bar's NET readout mirrors the
pending trade (+N cr while picking, 0 cr after Confirm).
- TradeGrid cells now render only the good's icon; hovering a usable cell reveals a shared per-grid tooltip with the name and "sell/buy for N cr" price line, anchored above (or below on the top row) and clamped to the panel.
- Per-cell name/price text objects are removed; a single `label` remains only for locked/empty state ("locked", "—").
- data/shopui.json: add `tooltip` section (bg, border, pad, gap, font sizes) and bump `iconScale` to 0.62 so icons fill the now-cleaner cell.
- Apply theme fonts throughout the shop UI — Ethnocentric for section titles, Centauri for body text, tooltip, stepper, and buttons via `fontStack()`.
- dev/shop-shot.mjs: replace old layout probe with a hover-tooltip probe (structure check, programmatic + real mousemove hovers on sell/buy cells, pointerout hide) and await web fonts before boot so screenshots use the real typefaces.
- dev/shop-ui.test.mjs: new HOVER TOOLTIP suite asserting tooltip visibility, text content, locked/empty suppression, unhover, buy-side pricing, and theme font application.
- Shop now opens on the tab sub-bar only (shop video plays); clicking Buy/Sell reveals the trade panel — showcases the clip before the UI takes over.
- Tab bar and Confirm/Clear are now MenuButtons in a console-blue sub-bar that rests above the command deck, anchored to the deck's Shop button (MenuSubBar recipe), replacing the old top-of-screen custom buttons.
- Fix trade panel vertical placement: a Container's (x,y) is a pure translation of local space (verified via dev/cbox-test.html), so the grid position IS the panel top-left; setting it to topY + h/2 treated it as a centered origin and clipped bottom rows. Panel now anchors just under the HUD planet text via SurfaceScene.shopTopY().
- Parent TradeGrid plate/title to the grid container so they render above the shop video (scene-level depth-0 objects drew behind it in this build).
- Add dev probes (dev/cbox-test.html, dev/shop-shot.{html,mjs}) and update phaser-stub/test stubs for setSize/setBlendMode/rectangle; document entry state + sub-bar in docs/ECONOMY.md.
- Introduce CargoHold (pure class) as the ship's trade-goods carrier: fixed bays, one good each, capacity = unlocked bays, save/restore round-trip. Ship.cargo + setCargoHold/cargoRoom wired into stats.
- Add three credit-costed cargo builds (cargo-bay-8/12/16) that expand the hold 4→8→12→16 (MAX wins). BuildWindow affordability now covers both minerals and credits; GameScene.beginBuild debits credit lines and _applyCargoUpgrade expands the hold on completion.
- Add tradePreview/resultingCargo to Economy.js as the shop's pure calculator: sell/buy pricing, net credits, the two caps (can't go negative, end hold fits capacity), and atomic sell-to-free-room-for-buy.
- New ShopView + TradeGrid compose the buy/sell screen over the shop clip: SELL grid of cargo bays (tap to check), BUY grid with quantity steppers, live NET preview, Confirm/Clear, and a session-local Buyback tab (neutral undo at the sale price, locked until a sale). Wired into SurfaceScene's SHOP button.
- data/shopui.json drives the shop layout/animation knobs; economy.json gains cargo.maxSlots (16-slot grid); ship.json base cargoHold drops to 4 unlocked bays.
- Headless tests: dev/cargo.test.mjs (hold rules + trade preview caps), dev/shop-ui.test.mjs (construct, sell, buy, caps, buyback, clear), plus updated builds/ship-behavior suites; phaser-stub gains Geom.Rectangle for the hitArea path.
- New Economy.js price/stock engine: deterministic buy/sell prices based on
producer/demand classes and hop distance (regional availability model)
- Goods catalog (114 goods, 9 categories) with spritesheet mapping and
per-class producer/demand roles
- Credits state on Ship (add/spend/set/canAfford), save/restore support,
and upper-right HUD stacked above the minerals readout
- Quest reward payout now supports credits alongside minerals
- cargoHold reduced to 4 units for initial play balance
- Economy generation pass in Galaxy.js computes classBySystem and
producerHops via multi-source BFS over the jump network
- dev/economy.test.mjs validates determinism, fixed prices, trade loop
profitability, distance scaling, shop floor composition, and icon mapping
- docs/ECONOMY.md: full design doc covering pricing model, gemstone system,
and locked decisions
- BUILT rows are now lit — accent fill, glow ring, icon halo, and a
stamped seal — so installed upgrades read as done at a glance.
- The readout now names the world a build was actually installed on
(new BuildState.builtOn): ship upgrades show "SHIP-WIDE · INSTALLED
FROM KEPLER-186F" instead of the planet the console sits on.
- BUILT outranks BUSY, so an installed upgrade no longer reads as
waiting while another build is in flight; its cost line reads PAID.
- Category tabs gain progress pips: filled = built, pulsing = in
progress, hollow = not yet.
- Dev-only headless harness (dev/build-shot.html/.mjs) boots the game
and stages the full row-state matrix for one-frame screenshots.
- Refresh the planet sheet artwork (planets.png/.psd).
Branch sizes are inherently skewed; previously only the cap (median quota)
applied, so a small faction could start with a one-system sliver.
- FLOOR (balance.minTerritory, data/factions.json): a faction below the
floor absorbs the nearest unowned eligible overflow first, then the
richest faction's least-core systems — territory stays contiguous; a
tiny galaxy with too few eligible systems is best-effort.
- Territory is now tracked per faction: g.factions.factionTerritories is
the truth, the branch view is derived; capitals are placed inside the
faction's post-floor territory, so a faction built entirely from
borrowed space still gets its seat in its own territory.
- The galaxy plate rings EVERY star: faction color for territory, neutral
silver for wild space (home included) — the ring color is the
ownership read at a glance.
- dev/factions.test.mjs now checks the floor, cap, disjointness, and
branch-view invariants; new throwaway diagnostics
dev/faction-balance.diag.mjs / dev/faction-sweep.diag.mjs sweep seeds
for the invariants + determinism.
- Key the lane/region colors and draw the faction rings/capital
seat in the GALAXY legend, live from factions.json
- Name a hovered star's standing in the tooltip: territory,
capital, or wild space
- Add a dev screenshot harness to smoke-test the legend and
tooltip
- Assign each jump-tree branch a faction (apex/mindweave/zenith) with seeded
shuffle; territory = depth 2..maxDepth-1 per branch, ring + tips stay neutral
- Designate four capital worlds (neutral + one per faction) as the outermost
planet of their system, with fixed frames 18-21 and faction-owned settlements
- Add cross-branch bridge gates in the middle belt so factions can reach each
other without routing through the trunk; Dijkstra picks the shorter route
- Introduce arid planet class (always habitable, settles as colony) across all
system types with rebalanced class weights
- Wire Trestle's last brief to auto-set destination to the neutral capital on
acknowledgment (CommsHub onEnd → GameScene._commEnded)
- Render faction ring layer + capital seat marks on the galaxy plate; style
bridge lanes distinctly from trunk edges
- Populate settlement owner from system faction (reputation seam now live);
SystemReport reads faction label/color
- Add dev/factions.test.mjs covering config, branches, capitals, territory,
arid, bridges, determinism; update existing tests for new invariants
- New second main quest "Leaving the Nest" (data/quests.json) that unlocks when the starter quest's reward is claimed, with four checks: system charted, gates activated, Trestle talked, Trestle met
- Quest unlock chain in QuestState (isUnlockMet / grantUnlocked) and GameScene._grantUnlockedQuests — grants on claim + scene create for loaded saves, announces via SFX, OAC quest-grant voice (new oac-quest-new comm), and NEW QUEST toast
- Trestle story beats: three-brief ACK sequence (trestle-brief-1/2/3, trigger trestleBrief) armed when home jumpgates go online, and arrival beat (trestle-arrive, trigger trestleArrival) on landing in a neighbor system; CommsHub gains onStart hook so the played-ledger marks feed quest checks live
- Quest check types: systemCharted, gatesActivated, trestleTalked, trestleMet — evaluated in GameScene._questCheckEval / _trestleCheck against the comms played-ledger (survives reloads; mid-sequence quit re-arms only unplayed beats)
- System-complete milestone moved from research completion to the chart-completing discovery (celebrateDiscovery), one fire per system via _systemCompleteSeen set
- QuestTrackerHud READY state: completed-unclaimed rows turn amber with breathing tint, percent reads "READY" (bold), one-shot flash + diamond burst on flip, CLAIM REWARD button in row popup claims in place; silent when tracker is slid off (toast + chime carry it)
- New speech clips (trestle q2-01/02/03), lava-takeoff video, updated lava-land video, renamed lava-planet image, new laval-surface image
- Dev: quest-ready.html/mjs capture harness for the READY state shot; tests updated across comms, quests, quest-tracker, and system-hud suites
- Slot cards: fit content lines to card width (wrap, shrink, ellipsize)
and stack them by measured height so long names no longer spill into
neighbouring slots; bump fill opacity to reduce bleed-through.
- SavePanel open choreography now lands only after every card stagger
and footer rise complete — the old state-gated loop dropped row 2.
- Move feedback toast inside the panel on the subtitle line, hiding the
header while it shows (old spot collided with the O.A.C. comms box).
- ConfirmOverlay: reset to base size each show, fit title/body text into
the plate before laying out, and make the body fully opaque so card
text no longer bleeds through.
- Add dev screenshot harness (save-shot.html/mjs) and extend the saves
UI test with overflow, stagger-completion, and toast-position checks.
- Update planet sprites and add/refresh SFX + music assets.
- ensureLandingTether runs before SurfaceScene launch so the surface HUD
already reads Tether Level 1; free + instant, no console step
- Extend tether lookups (_applyBuildEffects, tetherLevelFor,
_rematerializeBuiltTethers, applyRestore) to include systemStations so
station tethers anchor, level up, and re-anchor like planets'
- Idempotent: home seed, existing build record, or an already-hosted
tether all short-circuit; adopt rather than double-anchor
- tether-l1 targets now ["planet", "station"]; update descriptions in
builds.json, README, PROJECT_NOTES
- Reorder MapWindow tabs to CURRENT SYSTEM / GALAXY / SYSTEM (galaxy is
the live middle tab) and keep SYSTEM as the armed standby target
- Introduce the `firstForeignPlanet` trigger: when the player discovers a planet in a non-home system, Trestle (new out-of-system mentor character) delivers a two-part ack comm pair (meetup + quest claim), with dedicated video and speech assets.
- Make audio cache keys folder-scoped so characters with identically-named clips (e.g. both having `intro-01.mp3`) don't collide in the loader.
- Add an amber pulsing attention cue (halo + staggered sonar rings) on the ACKNOWLEDGE button for ack comms, driven per-frame from CommsBox.update().
- Put the ActionBar deck into a standby state while an ack comm holds: slots go inert (no hover/press), dimmed visually; re-arms when the comm ends. GameScene wires this via `actionBar.setEnabled()` each frame based on `comms.paused`.
- Extend MenuButton to accept a custom border color so the ACK button can wear the box's amber against the cyan UI.
- Add dev self-check harnesses (`comms-trestle.mjs`, `comms-trestle-hold.mjs`) and update existing tests to cover the new pair, folder-scoped keys, deck standby behavior, and pulse animation.
- Disable browser module caching in CDP probe/shot scripts to avoid stale ES modules shadowing on-disk changes during dev testing.
- Use fixed short button copy for the gates tech ("Unlock Jumpgates") and mining nodes (drop "Mining" prefix) since the tree node has no room for system names or category words
- Raise detail panel height and widen node/button plates so long descriptions and status labels stop bleeding past plate edges
- Add word-wrap to the unlocks line and trim redundant status prefixes ("RESEARCH CONSOLE STANDBY", "PROJECT COMPLETE")
- Fix ice-surface-01 video reference in landing.json (was pointing at rocky-surface)
- Add OAC speech clips and ice surface video asset; update planets.psd
- Tighten tether research descriptions to match the new short-copy style
- Fire a one-shot ignition (expanding rings, edge pulse, child flares) when a project completes; queue it if the console is closed or on another tab, dropping stale events after 15s
- Add per-tech progress pips on each category tab showing done/in-progress/not-yet states, with a pulse on the active one
- Light up unlocked nodes with an accent glow ring, icon halo, and a stamped seal glyph replacing the plain checkmark
- Add dev harnesses for screenshotting the live completion treatment and verifying the queued-celebration path
- Replace the square star field with a wide (width × height) field whose
aspect matches the map plate, so the fully-zoomed-out galaxy fills the
plate instead of letterboxing; recompute zone edges for equal-area thirds
under the new diagonal CDF.
- Add fitPadded() in SystemChart.js and use it in GalaxyView.js to frame
the galaxy as a true rectangle fit with a plate-pixel margin, replacing
the old world-unit padding that left stars on the plate edge.
- Rework the JumpNetwork spanning-tree heuristic to "save the stranded
first" (attach the candidate with the fewest unvisited non-barren
neighbors) and strengthen the repair pass: never attach to barren nodes,
guard swaps against cycles via inSubtree(), and add a last-resort
fallback that preserves strong connectivity.
- Update tests (galaxy.test.mjs, system-chart.test.mjs) for the field
bounds and the new fitPadded behavior; refresh README, PROJECT_NOTES,
and data comments to document the 2:1 field and platePadding knob.
- Mining now fires `onDepleted` when a cluster's last rock is consumed; GameScene splices the depleted cluster out of world entities, solids, content record, and map chart, then records its id for persistence
- SaveData captures/restores `depletedClusters` so mined-out fields stay gone across save/load (legacy saves default to empty set)
- Change station compass color from red (#ff4d5e) to bright purple (#c84dff) in data and all UI references
- ResearchWindow: thicken tech-tree edges to 3px core + wide glow, add crawling dash animation on unpowered links, endpoint socket dots, and a comet-trail pulse on powered edges
- New QuestTrackerHud component slides in below the system dossier once it folds, showing active quests (main story first) with a live progress checklist under the priority quest
- Priority quest: player can set/clear via row popup or console; auto-assigns to first active story quest; cleared state sticks until a grant or claim re-arms it
- QuestWindow gains SET PRIORITY / CLEAR PRIORITY controls and openAt() to land on a specific quest (used by SHOW MORE / VIEW QUEST)
- GameScene wires the tracker into the dossier lifecycle: hidden while expanded, slides out before expand, slides in on collapse; pointerdown contract prevents world clicks from leaking through rows and popups
- SurfaceScene delegates priority changes to the sleeping GameScene's ledger
- QuestState serializes/deserializes priority + cleared flag for save round-trips
- quests.json gains a tracker section (title, maxVisible, slideMs, toast configs)
- New dev/quest-tracker.test.mjs pins the full contract; dev/quests.test.mjs extended with priority and tracker-knob checks; system-hud test updated for the extra tracker elements
- Use `video.resume()` instead of `video.play()` in Build, Map, Quest,
and Research windows: Phaser v4's `play()` is a no-op after `pause()`
because the `_playCalled` flag stays true, leaving the feed frozen
after close → reopen. `resume()` handles both first open and re-open.
- Play the 'construct' SFX when the planet HUD lines start their
scramble-decode animation in SurfaceScene.
- Introduce QuestState ledger (granted/claimed ids) persisted via SaveData, with safe fromJSON validation that drops unknown ids and enforces claimed ⊆ granted
- Define the starter quest "Start Your Journey" in data/quests.json with four live checks: research node, lifetime asteroid mining, home tether level, and discovered world count
- Add totalMined counter tracked on each ore event to support the mining requirement independently of cargo hold
- Build QuestWindow (full-screen console at depth 80) with video feed, category tabs (Main Story live, Side Quests standby), quest list, detail plate with checklist and CLAIM REWARD action
- Wire QUESTS slot into both flight and surface command decks right of SHIP; SurfaceScene delegates snapshot/claim to the sleeping GameScene while rendering its own console notes
- Grant starter quest on first boot with delayed toast; announce "QUEST READY" once per quest when all checks complete
- Update research-builds tests for seven-slot deck layout; add dev/quests.test.mjs covering data contract, ledger behavior, save round-trip, and deck slot placement
- Draw the active SET DESTINATION path in orange on galaxy lanes and circle the destination star with a breathing ring
- On the current-system chart, circle the destination object when it is in this system, or show the route exit gate plus a dashed ship-to-gate line when the destination is elsewhere
- Carry `route` edge keys and `destinationId` through `buildGalaxySnapshot`, `mapChartSnapshot`, and `systemChartSnapshotFor` so views can render the course
- Add dev screenshot harnesses (route-shot, exit-gate-shot) and extend galaxy-map tests to cover route/destination flags
- Document the new visualization in PROJECT_NOTES.md and add a takeoff video asset
- In the destination system, the orange compass arrow now points at the
destination OBJECT (not just the next gate), so the "where to fly next"
marker persists across the last hop into the system.
- Add `_checkDestinationReached` per-frame check: clears the destination and
fires REACHED only when the ship is within the object's keep-out rim,
replacing the old jump-time clear for destinations with a specific object.
- Route compass entries (`route:`/`dest:` ids) are now resolvable by
`autopilotTo`, fixing the ship aiming at the star instead of the gate.
- New `alwaysFull` flag on compass targets keeps route waypoints at full
readout (arrow + type + name) regardless of distance; add tests.
- Add `route.destTypeLabel` config key and update docs/PROJECT_NOTES.md.
- New `js/galaxy/Route.js` derives the unique path between systems over the spanning-tree jump network (Dijkstra), exposing `planRoute` / `nextSystem`; pure and Node-tested in `dev/route.test.mjs`.
- Persist only the destination (`systemId`, `objectId`) in save data; the route itself is recomputed from the current system, so following it shortens automatically and a detour re-plots.
- Compass marks the route's next gate in orange (shown even while undiscovered) and suppresses that gate's ordinary cyan entry.
- On jump, resolve arrival / on-course / detour before `captureState` and queue REACHED / RE-PLOTTED notices to surface after the destination scene spawns.
- Map console SYSTEM tab now charts a charted star's system; confirming an object sets the destination and closes the map.
- Fix galaxy stars bleeding through the system chart: plate culling respects overall visibility, fog skips when no tethers anchor it, and the boot reveal finalizes to full alpha on tab switch.
- Add `assets/videos/ss-land-03.mp4` and document the route feature in PROJECT_NOTES.
- Add per-show width/height overrides so the SYSTEM tab's longer
"SET DESTINATION" label gets a wider dialog than AUTOPILOT's ENGAGE
- Grow each button panel to fit its label (_fitBtn) and re-flow title,
body and buttons into the bottom band (_layout) instead of using fixed
positions that let long text run past the panel edge
- Record baseWidth so a grown button never stays wide for the next dialog
- Wire map.json systemConfirm/confirm size config through MapWindow
- Add ss-takeoff-02.mp4 asset
- New "System" socket in MapWindow: a charted star's chart drawn by the
same painter as Current System (no ship/tethers), armed until the player
picks that star on the Galaxy tab, then wakes with its map.
- Galaxy tab click flow changes: a visited star opens its chart in the
System tab (onStarOpen) instead of confirming a jump; uncharted stars
are readouts only and a lit lane to an uncharted star pops nothing.
- Zoom-bloom star art (GalaxyChart.starArtSpec + GalaxyView blit):
diffraction spikes, per-type crowns (granulation, prominences, binary
companion, habitable rings, nebula disc, void horizon) and a surface
wobble fade in as you zoom; all angles/phases seeded per system.
- Star hit-testing now scales with the dot size and includes a crowded
cluster dead band so lanes/empty space between stars no longer trigger
hover.
- New systemChartSnapshot() in SystemChart.js plus tests covering shape,
coverage, discovery flags, stats and determinism.
- Set Destination dialog (System tab) acknowledges the pick via
onSetDestination; destination model is still being defined.
- Added spacestation image/video assets for future use.
- New `GalaxyView` renders glowing stars per archetype (pulsing heartbeat),
the jump-lane web (traveled/frontier/unexplored), the charted region's
convex hull, HOME/SHIP markers, hover readouts, and CONFIRM JUMP on a
live lane (reuses the existing gate transport).
- `GalaxyChart.js` provides the pure model + geometry: edgeKey, snapshot
builder, convex hull / padded polygon, star pulse/color, and plate
clipping (Liang-Barsky + Sutherland-Hodgman) — all Node-testable.
- Run's footprint (`visitedSystems`, `usedGates`) is captured/restored/
reset in SaveData; legacy saves default to "current system charted,
nothing traveled".
- MapWindow gains tab switching between the system chart and the galaxy
view, with shared stats/legend/status chrome per mode.
- Two dev tests cover the galaxy model, save round-trip, hull geometry,
plate clipping, and a regression for the star-label blink bug.
- The sub-bar was anchored to the MENU button's center + half-height, which
made it spill over the command deck's top rail (buttons are inset below
the bar's top edge). Anchor y is now the deck's top edge so the bar's
bottom edge sits on the deck.
- Update landing.json rocky land-02/03 entries to reference their own
rocky surface/takeoff/shop videos instead of reusing gasgiant/terran
assets, and add the new rocky-shop-03.mp4 video.
- Temporarily disable per-class planet tints in GameScene (option still
accepted by Planet for when we re-enable it).
- New `data/research/mining.json` tree (Improved/Advanced Mining Arm, Improved Storage) as blueprints that unlock matching builds
- Three new ship-scoped builds in the console's Mining tab: mining arm rate 1.5/2.0 minerals/s and hold cap 350; MAX-guarded effects applied to `ship.stats`
- Tether Level 3 promoted from research-direct effect to a build (tether-l3) gated on L2 tether, consistent with L2 blueprint pattern
- `BuildState.isBuiltAnywhere` + `isShipScoped` so ship upgrades count as built wherever the ship lands (no re-buy), records still key the planet
- `GameScene._restoreMiningUpgrades` re-derives ship mining stats from build records on load; `_applyMiningUpgrade` handles rate/capacity with toasts and HUD refresh
- New procedural icons: tether3, mining, mining2, storage
- Updated tests (builds, research-builds), diagnostics (BuildDiag v4), docs, README, manifest
- Targets beyond `farDistance` from the ship fold to a small text-less chip with a shrunken arrow, reducing visual clutter for distant objects
- Hovering a far chip expands it to the full readout after an intent delay; hovering off folds it back only after a grace period, so quick flicks don't pop or yank it
- Assign per-type compass accent colors: green for planets (data/planets.json), red for stations (data/stations.json), gray for asteroid clusters (already present)
- Export `isFarTarget` and `syncEntryMode` as pure helpers for Node testing; add far-display coverage to dev/discovery.test.mjs
- Add a headless integration driver (dev/compass-far.html + .mjs) that boots GameScene, parks the ship between near and far targets, and exercises the hover-intent lifecycle end-to-end
- Pass the ship position into `compass.refresh()` from GameScene so the compass can compute per-target far/near state each frame