{ "_comment": "Planet visuals + home-planet rules + the invisible star's flavor (class colors — non-home systems have no central body) + the solar system's layout. texture is a spritesheet of frameWidth×frameHeight frames (frame 0 = top-left); frames maps a planet kind to the sheet frames it may be drawn as — the generator picks one per planet (seed-deterministic). homePlanet is the player's world — present ONLY at the origin of the system they start in (the starting system's central body); every OTHER system's center is empty — the star is invisible flavor (`star` below: name/class feed the dossier and gate names, never rendered). scale = world pixels per sheet pixel (1.0 = 1:1, so a Terran world is 1024 px across on screen). A planet is a solid disc: the ship may approach to shipClearance px (edge-to-edge) from its rim but can never cross it. spawnDistanceFromEdge = how far (edge-to-edge) the ship starts from the home world's rim. classScale = size multiplier per planet class (1.0 = 1024 px across); classTint = optional canvas tint per class (multiplicative — the terran art stands in for every kind until real art lands). compassColor = the compass-arrow accent for planets (the home world + the system's worlds — data/stations.json's stations and data/asteroids.json's clusters carry their own; the scan signal compass reads it too). solarSystem = the top-down LAYOUT RULES (js/galaxy/SystemGenerator.js → layoutSystem), built around TETHER DISCOVERY (data/tether.json): the objects of a system (planets + free-space stations + the home world in the starting system) sit on a compact arc at one orbital radius — the star (or home world) at the origin — with CONSECUTIVE objects a level-1 tether apart (clearly inside level 1: ≤ 5120 − edgeMargin) so a chain of level-1 tethers always discovers the whole system, and level-2 DEFINITELY discovers while undiscovered objects remain (its adjacency graph is connected) — level-3 never needs to be required. NO object pair (among anchorable objects — planets, stations, the home world) may sit in the no-man's-land band around a tether rim: (L1 − edgeMargin, L1 + edgeMargin) or (L2 − edgeMargin, L2 + edgeMargin) — objects are clearly inside or clearly outside each tether region, never at the edge (the scan edge case). The invisible star (non-home systems) is not a tether anchor, so its distances only need minSpacing..maxSpacing; the home world IS an anchor, so its distances also respect the bands (homeMaxSpacing is additionally capped at L2 − edgeMargin). minSpacing = star/home-world-to-object floor; maxSpacing = star-to-object ceiling (6400..15360 px); homeMaxSpacing = home-world-to-object ceiling; neighborMin = the planet/station-to-planet/station floor (disc clearance + the chain-gap lower bound). The rotation biases toward the jump-gate directions (data/gates.json). All values are center-to-center px (the same unit as the 1024 px world disc).", "texture": "assets/images/planets.png", "frameWidth": 1024, "frameHeight": 1024, "scale": 1.0, "frames": { "terran": [0, 1, 2], "rocky": [6, 7, 8], "gas": [3, 4, 5], "ice": [9, 10, 11], "lava": [12, 13, 14], "arid": [15, 16, 17], "capitalNeutral": [18], "capitalApex": [19], "capitalMindweave": [20], "capitalZenith": [21] }, "capitals": { "_comment": "CAPITAL WORLDS (data/factions.json, the faction pass in js/galaxy/Galaxy.js): the four designated capitals are NOT composition planets — the roster picks the SYSTEM (neutral: a seeded pick of home's gate neighbors; apex/mindweave/zenith: one per branch, middle band, seeded) and SystemGenerator converts the system's OUTERMOST world into the capital world (replacing it — the object budget + arc layout + settlement count stay exactly as rolled). frames = the planets.png frame per capital id (18 neutral, 19 Apex, 20 MindWeave, 21 Zenith — fixed per faction, never a random pool); the art carries each faction's color, so classTint is white (no tint) for the capital classes and the renderer's classScale sizes them (planets.classScale.capital*). All four are habitable cities (a capital has population by definition) and host the 'capital' settlement (data/settlements.json → kinds.capital); the neutral capital's settlement is owner-less, the faction ones are owner: (the reputation faction seam).", "frames": { "neutral": 18, "apex": 19, "mindweave": 20, "zenith": 21 } }, "classScale": { "rocky": 1.0, "gas": 1.45, "ice": 0.85, "lava": 0.95, "arid": 0.9, "capitalNeutral": 1.2, "capitalApex": 1.2, "capitalMindweave": 1.2, "capitalZenith": 1.2 }, "classTint": { "rocky": "#e8d9b8", "gas": "#ffb066", "ice": "#cfeaff", "lava": "#ff8a5c", "arid": "#e2a25f", "capitalNeutral": "#ffffff", "capitalApex": "#ffffff", "capitalMindweave": "#ffffff", "capitalZenith": "#ffffff" }, "compassColor": "#3dff88", "typeLabels": { "terran": "Home World", "rocky": "Rocky World", "gas": "Gas Giant", "ice": "Ice World", "lava": "Lava World", "arid": "Arid World", "capitalNeutral": "Neutral Capital", "capitalApex": "Apex Capital", "capitalMindweave": "MindWeave Capital", "capitalZenith": "Zenith Capital" }, "homePlanet": "terran", "homeName": "Terra", "homeTypeLabel": "Home World", "star": { "_comment": "The system's INVISIBLE star — flavor, not a body. Every non-home system's center is empty (the star is never rendered; js/entities/Star.js is gone); this section feeds the dossier's identity (content.star) and the class colors used by the diagnostics and the map plate tag. classColor = the class's hue (G/K/M/… → hex).", "classColor": { "O": "#9db4ff", "B": "#9db4ff", "A": "#cfd8ff", "F": "#fff4e0", "G": "#ffe9b0", "K": "#ffc07a", "M": "#ff8a64" } }, "starTypeLabels": { "O": "O-type Star", "B": "B-type Star", "A": "A-type Star", "F": "F-type Star", "G": "G-type Star", "K": "K-type Star", "M": "M-type Star" }, "shipClearance": 50, "spawnDistanceFromEdge": 150, "solarSystem": { "enabled": true, "minSpacing": 6400, "maxSpacing": 15360, "homeMaxSpacing": 10240, "neighborMin": 2048 } }