{ "_comment": "MAP — the deck's MAP button (to the right of SHIP): the full-screen cartography console, js/ui/MapWindow.js (depth 80, the ResearchWindow idiom). LEFT = the cartography feed (assets/videos/map.mp4, a muted 2:3 loop, the same recipe as the research archive feed). RIGHT = tabs on top (CURRENT SYSTEM — the live system chart, SYSTEM — a CHARTED star's chart, picked from the GALAXY tab; armed until then, and GALAXY — the whole-galaxy chart: glowing, pulsing stars per archetype, the jump-lane web with traveled lanes bright + flow packets, the charted region's outline — js/ui/GalaxyView.js), and the readout on the bottom (per tab: the system's discovery/resources, or the galaxy's charted stats). THE CHART (the magic, drawn to a canvas texture): the whole solar system — every object's extent (planets, stations, gates AND asteroid clusters, discovered or not) + `bounds.padding` px of padding on each edge — fitted to the plate. Only DISCOVERED objects are drawn (planets / stations / gates / rock fields, small representations). The TETHER RANGE is drawn as the union boundary (Tether.visibleArcs) with a soft zone glow inside, and everything OUTSIDE the tether union is grayed out (a fog-of-war dim pass with feathered rim) — so the chart reads as 'here is what you have charted, and here is the room to expand'. A live SHIP marker + hover tooltips + click-to-autopilot (GameScene.autopilotTo) sit on top. All colors/motion are steered here.", "enabled": true, "title": "STELLAR CARTOGRAPHY", "meta": "NAV DATA // LIVE FEED", "video": { "_comment": "The cartography feed (like research.video): `file` is the clip under assets/videos/ (or a full relative path / URL). Muted, looping, 2:3 portrait (map.mp4 is 544×800). A missing file leaves the NO SIGNAL plate up — the console still works.", "file": "map.mp4", "aspect": [ 2, 3 ] }, "tabs": { "_comment": "The sockets above the chart (top right), equal widths. `currentSystem` is the live system chart (default). `system` is a CHARTED star's chart (the same painter, no ship/tether) — it wakes from standby the first time the player picks that star on the GALAXY tab; until then it's the armed killswitch. `galaxy` is the whole-galaxy chart (js/ui/GalaxyView.js). `standby: true` on ANY socket is the killswitch — the tab renders dimmed with its standbyTag and a press fires the scene's onLocked (a console toast) instead of switching.", "currentSystem": { "id": "currentSystem", "label": "Current System", "accent": "#00e5ff" }, "system": { "id": "system", "label": "System", "accent": "#a8ffc4", "standby": true, "standbyTag": "NO TARGET" }, "galaxy": { "id": "galaxy", "label": "Galaxy", "accent": "#ffc94d", "standby": false, "standbyTag": "OFFLINE" } }, "galaxyLockedToast": "GALAXY MAP OFFLINE — SECTOR DATA NOT ACQUIRED", "systemLockedToast": "NO SYSTEM TARGET — PICK A CHARTED STAR ON THE GALAXY MAP", "bounds": { "_comment": "The chart's frame: the furthest X/Y extents of EVERY object in the system (planets, stations, gates, asteroid clusters — discovered or not) plus this much padding, px, on each edge (the design rule: ~1024).", "padding": 1024 }, "chart": { "_comment": "The plate's rendering (the canvas texture is redrawn on open / on discovery / on tether changes). colors follow theme.json (neon cyan range, amber alerts). grid.spacing = the world-px step of the adaptive grid (snapped to 1/2/5×10^k). glow = the soft light pooled inside each tether zone (fraction of the zone radius the gradient spans, and its strength). labels = the small name tags under NAV objects.", "colors": { "bg": "#040914", "bgGlow": "#0a2238", "star": "#9fd8ff", "grid": "#1b3a5a", "gridAlpha": 0.28, "ink": "#eaf6ff", "dim": "#7d92c4", "faint": "#3d4c74", "tether": "#00e5ff", "tetherGlow": "#00e5ff", "neon2": "#ff2d6f", "amber": "#ffc94d", "fog": "#111c33", "fogAlpha": 0.55 }, "grid": { "spacing": 512, "alpha": 0.28 }, "glow": { "span": 0.92, "alpha": 0.22 }, "tetherLine": { "dash": 7, "gap": 5, "width": 2, "coreWidth": 1, "ghost": 2.5 }, "labels": { "enabled": true, "size": 10, "letterSpacing": 1.2 }, "planetMin": 4, "planetMax": 16, "starMin": 7, "starMax": 30, "vignette": 0.34 }, "stats": { "_comment": "The bottom-right SYSTEM readout. discovery = the share of the system's NAV objects (planets + space stations + jump gates — the central body is the chart's anchor, not a count) the player has found; resources = the share of asteroid fields found (the only resource kind for now). Both render as segmented bars (one segment per object) + a percent.", "discoveryLabel": "SYSTEM DISCOVERY", "discoveryMeta": "PLANETS · STATIONS · JUMP GATES", "resourcesLabel": "SYSTEM RESOURCES", "resourcesMeta": "ASTEROID FIELDS", "noResources": "NO RESOURCE FIELDS CHARTED" }, "legend": { "_comment": "The glyph key under the stats (the chart's visual language).", "items": [ { "glyph": "planet", "label": "WORLD" }, { "glyph": "station", "label": "STATION" }, { "glyph": "gate", "label": "JUMP GATE" }, { "glyph": "rock", "label": "ROCKS" }, { "glyph": "tether", "label": "TETHER RANGE" }, { "glyph": "ship", "label": "SHIP" } ] }, "galaxy": { "_comment": "THE GALAXY TAB (js/ui/GalaxyView.js) — the whole-galaxy chart on the plate: one GLOWING STAR per system (colored by its archetype, data/systems.json → types, pulsing on that archetype's heartbeat in `pulse`), THIN LANES where the jump gates connect (the JumpNetwork spanning tree — a maze), the CHARTED REGION (the convex hull of the visited systems, inflated — the discovered-area shading), HOME + SHIP markers, ambient dust + the core glow. TRAVELED lanes (the run jumped them — saved with the run) glow brighter + carry a flow packet; FRONTIER lanes (one end visited) are the 'next step'; unexplored lanes are faint threads. Hover = the star's readout + its link state to the current system — STARS ONLY, and the zone hugs each star's drawn dot (glow radius + a few px of mouse pad), so the lanes between the stars never trigger it; click a CHARTED star = its chart in the SYSTEM tab; uncharted stars are readouts only. FACTIONS (planned, not yet implemented): the snapshot carries per-system `faction: null` — the reserved seams are a faction color layer over the stars + a per-faction territory region (the same hull/fill recipe as `hull`, per faction color + relation alpha).", "name": "GALAXY", "padding": 90, "stars": { "_comment": "Per-system star rendering. minPx = the core dot at 1× zoom (a tad bigger than a pixel — the fully-zoomed-out dot); zoomGrow = px gained per zoom step (the star grows as you approach). glow/core = legacy world-unit bases (kept for the glow texture's swing). visitedBoost = how much brighter a charted star's glow reads; unknownMul/unknownAlpha = the dimmer read on uncharted stars (the galaxy is bigger than the run). art = the ZOOM-BLOOM design: the star is a plain dot until flareAt, then diffraction spikes fade in; at crownAt its type's signature appears (main = granulation rim + corona ticks, redDwarf = breathing corona + prominence arcs, binary = an orbiting companion on a faint ellipse, habitable = the life-zone rings + orbiting world(s), nebula = a tilted accretion disc + drifting speckles, void = a dark horizon + shimmering photon ring + lensing ticks); at surfaceAt the core gains a surface wobble + a glint. All sizes are × the dot; all angles/phases are seeded per system (deterministic); everything animates on scene time. spikes = 0 for the void (no sparkle around a horizon).", "glow": 30, "core": 6, "glowAlpha": 0.6, "visitedBoost": 1.3, "unknownMul": 0.78, "unknownAlpha": 0.55, "minPx": 3.2, "zoomGrow": 1.25, "art": { "_comment": "Zoom-bloom layers (thresholds are zoom levels, map.galaxy.zoom.zMin..zMax). fade = the zoom span each layer takes to fade in. Per-type: spikes (diffraction rays), crown (the signature — see the parent comment), sizeMul (dot scale vs the base dot), plus crown parameters: companion.* = the binary's second star (orbit radius × dot, its core size × dot, ellipse tilt, orbit period), rings/tilt = the nebula disc (ring radii × dot, ellipse squash), ring/planet*/planet*PeriodMs = the habitable zone (outer orbit × dot, world sizes × dot, orbit periods), voidColor = the dark disc the void's horizon sits over.", "flareAt": 1.6, "crownAt": 2.8, "surfaceAt": 4.5, "fade": 0.45, "main": { "spikes": 4, "crown": "granulation", "sizeMul": 1 }, "redDwarf": { "spikes": 4, "crown": "prominences", "sizeMul": 0.92, "spikeAlpha": 0.8 }, "binary": { "spikes": 4, "crown": "companion", "sizeMul": 1.05, "companion": { "dist": 2.7, "size": 0.5, "tilt": 0.55, "periodMs": 14000 } }, "habitable": { "spikes": 4, "crown": "lifeRing", "sizeMul": 1.05, "ring": 2.2, "planetSize": 0.16, "planetPeriodMs": 21000, "planet2Size": 0.11, "planet2PeriodMs": 33000 }, "nebula": { "spikes": 6, "crown": "disk", "sizeMul": 1.12, "tilt": 0.4, "rings": [2.1, 2.9, 3.7] }, "void": { "spikes": 0, "crown": "horizon", "sizeMul": 0.95, "voidColor": "#040810" } } }, "pulse": { "_comment": "The per-archetype heartbeat (the 'per-star-type animation' — the plate's aliveness): `speed` in Hz (cycles/s of the sin), `amp` = the swing depth 0..1 (1 = full 0..1 swing, 0 = steady 0.5). Deterministic for (type, time, phase) — js/galaxy/GalaxyChart.js starPulse; each star's `phase` is seeded so they don't beat in unison. binary = fast double-beat; nebula = a wide shimmer; void = a slow dim breath.", "main": { "speed": 0.5, "amp": 0.5 }, "redDwarf": { "speed": 0.3, "amp": 0.45 }, "binary": { "speed": 1.1, "amp": 0.6 }, "habitable": { "speed": 0.4, "amp": 0.55 }, "nebula": { "speed": 0.8, "amp": 0.8 }, "void": { "speed": 0.2, "amp": 0.3 } }, "edges": { "_comment": "The jump-lane web — three reads of the same thin line. used = a lane the run TRAVELED (bright glow pass + the flow packet); frontier = exactly one end charted (the next step); unexplored = the faint maze. width = plate-px at 1× (0.75–1.25× with zoom).", "used": { "color": "#8df3ff", "width": 1.8, "alpha": 0.95 }, "frontier": { "color": "#3fb9d8", "width": 1.1, "alpha": 0.62 }, "unexplored": { "color": "#2a4f70", "width": 0.8, "alpha": 0.3 } }, "hull": { "_comment": "The CHARTED REGION — the convex hull of the visited systems, inflated by `padding` (a fraction of the plate width at 1× zoom — stable under zoom). A soft fill + a subtle double outline (the discovered-area shading). FACTIONS (planned): per-faction territories reuse this exact pass, colored per faction.", "enabled": true, "color": "#00e5ff", "padding": 0.055, "fillAlpha": 0.05, "outlineAlpha": 0.26 }, "flow": { "_comment": "Flow packets drifting along the TRAVELED lanes — the routes the player flew (the lane's history). size = plate-px; cycleMs = one traversal (a per-lane seeded stagger desyncs them).", "enabled": true, "color": "#d8f7ff", "size": 2.6, "cycleMs": 2600 }, "dust": { "_comment": "Ambient structure under the stars — a few soft nebulous blobs + the galaxy's core glow (the disc's heart). alphaMin/alphaMax = the seeded per-blob alpha band.", "enabled": true, "blobs": 5, "alphaMin": 0.03, "alphaMax": 0.08, "centerAlpha": 0.13 }, "labels": { "_comment": "Star name labels (under the star). The HOME/SHIP stars always label; the rest earn their label with zoom: visited at `visitedZoom`×, uncharted at `anyZoom`× (the uncharted galaxy stays quiet until you look in — labels appear only at a fairly close zoom, so the plate stays uncluttered).", "enabled": true, "visitedZoom": 2.5, "anyZoom": 5 }, "zoom": { "_comment": "Wheel zoom about the cursor + drag pan (the map.zoom idiom, galaxy scope) + double-tap 1× reset.", "enabled": true, "zMin": 1, "zMax": 10, "sensitivity": 0.0022 }, "reveal": { "_comment": "Tab switch / window open: a ripple OUT OF THE HOME system — stars bloom by distance (speedPerWorld = ms of delay per world-px, clamped to maxDelayMs), lanes trace in, the region fades in last.", "enabled": true, "speedPerWorld": 0.7, "maxDelayMs": 850 }, "dialog": { "_comment": "The clicked star's readouts (the window's shared ConfirmOverlay — the MapWindow autopilot idiom). {name} = the star, {current} = the current system, {gates} = its gate count. A CHARTED (visited) star wakes the SYSTEM tab with its chart (onStarOpen — the old JUMP confirm is gone; the star's chart IS the next step). Uncharted stars are readouts only (both buttons dismiss): GATE DORMANT; or NO DIRECT LINK. A lit lane to an uncharted star pops nothing — the jump stays a decision made at the gate (the LANE READY readout is gone).", "hereTitle": "YOU ARE HERE", "hereBody": ["{name} — the system your ship is in."], "dormantTitle": "GATE DORMANT", "dormantBody": ["The lane to {name} exists, but the gate out of {current} is dark."], "dormantHint": "Chart {name} and research its jump gates to wake the lane.", "noLinkTitle": "NO DIRECT LINK", "noLinkBody": ["No jump gate connects {current} and {name}."], "noLinkHint": "The network is a maze — follow the lanes one jump at a time.", "closeLabel": "CLOSE", "homeTag": "HOME", "homeTagBoth": "HOME · SHIP", "shipTag": "SHIP" } }, "sweep": { "_comment": "The scan band crawling across the chart (the CRT pass of light).", "enabled": true, "everyMs": [ 5200, 9800 ], "durationMs": 1500 }, "glitch": { "_comment": "Ambient glitch bursts over the window (slice bars + title RGB split, the ResearchWindow model).", "enabled": true, "intervalMs": [ 5000, 11000 ], "durationMs": [ 200, 420 ] }, "hover": { "_comment": "Plate hover: the object under the cursor gets a highlight ring + tooltip. radiusSlop = extra screen-px hit slop (tiny map objects need room).", "enabled": true, "radiusSlop": 9 }, "zoom": { "_comment": "Wheel zoom + drag pan over the chart plate (Phaser 4's input plugin delivers `wheel` and pointer events to the plate's image, whose hit area IS the plate — so they only fire over the plate; Phaser also stops the page scroll on the canvas by default). Zooming re-renders the chart at the new scale about the cursor (the painter's grid/labels adapt, so it stays crisp) — the visible box is the full frame ÷ z, clamped inside it. A press that moves past 5px pans the zoomed view (drag); release on a still press is the click (select / double-tap reset). Each system remembers its last view; double-tap on empty plate resets to 1×. sensitivity = exponential zoom per px of wheel delta (0.0022 ≈ 2.2× per 500 px of scroll).", "enabled": true, "zMin": 1, "zMax": 8, "sensitivity": 0.0022 }, "clickToast": { "_comment": "Plate interaction copy.", "coursePlotted": "COURSE PLOTTED — {name}", "noCourse": "NO NAV LOCK — OBJECT NOT CHARTED" }, "confirm": { "_comment": "The ENGAGE AUTOPILOT dialog (js/ui/ConfirmOverlay.js, the save pop-up's confirm) shown over the plate before a click engages autopilot — autopilot is a commitment, so it's confirmed. CONFIRM (ENGAGE) plots the course AND closes the console; CANCEL, a scrim click, or ESC leaves the map exactly as it was (the plate + chrome are inert while it's up). width/height/labels are the console language; the destination + distance body is computed live from the pick.", "width": 440, "height": 168, "title": "ENGAGE AUTOPILOT", "label": "ENGAGE" }, "systemConfirm": { "_comment": "The SYSTEM tab's SET DESTINATION dialog (same shared ConfirmOverlay — the clicked object on a CHARTED star's chart; the ship isn't in that system, so no distance row / autopilot). The destination model is still being defined — CONFIRM acknowledges the pick through onSetDestination (systemId + objectId), CANCEL / scrim / ESC leave the map as it was.", "title": "SET DESTINATION", "label": "SET DESTINATION" } }