116 lines
6.0 KiB
JSON
116 lines
6.0 KiB
JSON
{
|
||
"_comment": "ASTEROID CLUSTERS — loose groups of slowly tumbling rocks drifting in the system's void. texture = spritesheet of frameWidth×frameHeight asteroid frames (frameCount frames). cluster = how a group looks & moves: groupSize = rocks per cluster (minFullSize guarantees at least one full-size rock), sizes = per-rock diameter px, spread = how far a rock may sit from the cluster center, gapFactor = the small edge-gap between ANY two rocks, as a multiple of their combined radii (1.0 = touching, 1.12 = a subtle gap — the generator pushes apart just the overlapping pairs, each by half, so groups stay compact), spin = each rock's OWN very slow tumble (deg/s, direction per-rock random), groupSpin = the whole loose group drifts around its center (deg/s), tint = subtle warm/cool starlight per cluster (anchors blended toward white by strength), halo = soft glow behind the group, debris = a halo of fine dust motes orbiting just outside the rocks. distribution = how many clusters a system gets: targetObjects − planetCount, ±jitter, clamped to [minClusters, maxClusters] (more planets ⇒ fewer clusters); the starting system always gets at least startingSystemMinClusters, and those first ones are placed INSIDE the player's initial tether so they're reachable from the spawn. placement = where clusters may sit: minObjectSpacing = no cluster may be closer (center-to-center) than this to ANY other object (home world, planets, free-space stations, other clusters); minRadius/maxRadius = the annulus around the origin random clusters live in; tetherMargin = how far inside the tether rim a starting-system cluster must sit (whole group stays reachable). shipClearance = how close (edge-to-edge) the ship may get to a rock — clusters are solid, like worlds.",
|
||
"enabled": true,
|
||
"texture": "assets/images/asteroids.png",
|
||
"frameWidth": 128,
|
||
"frameHeight": 128,
|
||
"frameCount": 10,
|
||
"typeLabel": "Asteroid Cluster",
|
||
"compassColor": "#c8d2e0",
|
||
"shipClearance": 50,
|
||
"mining": {
|
||
"_comment": "MINING (v0.4) — the ship's energy arm. armExtendMs = the 'Extending Mining Arm...' reach before the beam fires (the ship is locked while it extends). beam = the arm's line: inMs/outMs = the beam extends (ship→rock) / retracts (rock→ship); glowWidth/midWidth/mainWidth/coreWidth = the white core in its blue glow (px, additive under the core); ghostOffset = the console RGB fringe split off the beam sides. ore = the mineral stream: motes ride the beam rock→ship (speedPxPerSec along the beam), each with a travelling wobble + a tail, absorbed at the hull. impact = the molten bite point: glowScale × rock radius (glowMinPx floor), the hot core, shock rings, and chipping sparks. surge = the big ore packets riding the beam home (the arm brightens while one is in flight). popup = the context menu a rock click opens (world-anchored at the click). economy = the rock IS its minerals: its size (width = height, px) at the start of mining is the minerals it holds; ratePerSec = minerals extracted per second (× the ship's stats.miningSpeed multiplier) — each mineral shrinks the rock by 1 px (width AND height; the beam tracks the live rock, so the impact point stays latched as it shrinks) and loads the ship's hold (capped at stats.mineralStorage — a full hold ends the run). splitLostFraction = once the rock has lost this fraction of its ORIGINAL size it breaks: ≤ smallSizeMaxPx it shatters into smallPieces of floor(size × pieceFraction) px each and ALL pieces are sucked into the ship (their minerals land on impact, capped); > smallSizeMaxPx it splits in HALF (floor(size/2) each, both starting fresh with their own original size) and the beam re-latches onto one half to keep mining. suckSpeedPxPerSec / suckStaggerMs = the shattered pieces' ride home. Every break plays sfx mining_split.",
|
||
"armExtendMs": 1500,
|
||
"beam": {
|
||
"inMs": 420,
|
||
"outMs": 380,
|
||
"glowWidth": 30,
|
||
"glowColor": "#2f7bff",
|
||
"glowAlpha": 0.1,
|
||
"midWidth": 15,
|
||
"midColor": "#00b3ff",
|
||
"midAlpha": 0.22,
|
||
"mainWidth": 7,
|
||
"mainColor": "#00e5ff",
|
||
"mainAlpha": 0.5,
|
||
"coreWidth": 2.6,
|
||
"coreColor": "#ffffff",
|
||
"coreAlpha": 0.95,
|
||
"ghostOffset": 2.6,
|
||
"ghostCyan": "#00e5ff",
|
||
"ghostMag": "#ff2d6f",
|
||
"ghostAlpha": 0.2
|
||
},
|
||
"ore": {
|
||
"maxParticles": 28,
|
||
"spawnEveryMs": [55, 110],
|
||
"speedPxPerSec": [140, 280],
|
||
"wobblePx": [1.5, 4],
|
||
"sizePx": [5, 12],
|
||
"tailPx": [8, 16]
|
||
},
|
||
"impact": {
|
||
"glowScale": 0.6,
|
||
"glowMinPx": 30,
|
||
"coreSizePx": 12,
|
||
"ringEveryMs": [550, 1100],
|
||
"sparkEveryMs": [90, 240]
|
||
},
|
||
"surge": {
|
||
"enabled": true,
|
||
"everyMs": [1800, 4200],
|
||
"durationMs": 320,
|
||
"bandLen": 46
|
||
},
|
||
"popup": {
|
||
"width": 248,
|
||
"padTop": 10,
|
||
"padBottom": 12,
|
||
"gap": 8,
|
||
"headerHeight": 20,
|
||
"lift": 14
|
||
},
|
||
"economy": {
|
||
"ratePerSec": 1,
|
||
"splitLostFraction": 0.33,
|
||
"smallSizeMaxPx": 64,
|
||
"smallPieces": 4,
|
||
"pieceFraction": 0.25,
|
||
"suckSpeedPxPerSec": 460,
|
||
"suckStaggerMs": 70
|
||
}
|
||
},
|
||
"cluster": {
|
||
"groupSize": { "min": 4, "max": 8 },
|
||
"sizes": { "min": 64, "max": 128 },
|
||
"minFullSize": 1,
|
||
"spread": 140,
|
||
"gapFactor": 1.12,
|
||
"spin": { "minDegPerSec": 0.3, "maxDegPerSec": 1.6 },
|
||
"groupSpin": { "minDegPerSec": 0.12, "maxDegPerSec": 0.4 },
|
||
"tint": {
|
||
"enabled": true,
|
||
"anchors": ["#dfe9ff", "#ffe9d6", "#e8e4f8"],
|
||
"strength": 0.5
|
||
},
|
||
"halo": {
|
||
"enabled": true,
|
||
"scale": 2.8,
|
||
"alpha": 0.26,
|
||
"color": "#7fa8d8"
|
||
},
|
||
"debris": {
|
||
"enabled": true,
|
||
"count": [18, 36],
|
||
"inner": 0.9,
|
||
"outer": 2.4,
|
||
"size": [2.5, 6],
|
||
"alpha": [0.4, 0.85]
|
||
}
|
||
},
|
||
"distribution": {
|
||
"targetObjects": 9,
|
||
"jitter": 1,
|
||
"minClusters": 1,
|
||
"maxClusters": 6,
|
||
"startingSystemMinClusters": 2
|
||
},
|
||
"placement": {
|
||
"minObjectSpacing": 1024,
|
||
"minRadius": 2048,
|
||
"maxRadius": 18432,
|
||
"tetherMargin": 96,
|
||
"maxPlacementAttempts": 400
|
||
}
|
||
}
|