level-config.ts
What
Type definitions, defaults, and runtime data shapes for the Voidstar level system. Defines a LevelConfig — the single object a designer touches to author one level tier. Everything visual and gameplay-related (palette, pattern, terrain, spawn pools, illumination behavior, lantern preset) derives from this config plus a seed. Same seed + same config = identical world (deterministic).
No runtime logic, no functions — purely types, enums, two default constants.
Topology
Hub-and-spoke on an infinite 2D plane divided into chunks. Hubs are circular clearings; spokes are corridors connecting hub pairs. Zones (wilds, spoke_dark, spoke_lit, hub_dark, hub_lit) drive zone-based enemy spawning.
Enums / String unions
| Type | Values |
|---|---|
PatternType | chaotic, rings, grid, zigzag |
SpokeStyleId | highway, energy, ghost |
HubStyleId | station, nexus, crater |
TerrainTypeId | asteroids, city, voidstar_mix, pillars, debris, crystals, organic, mechanical |
HubParticleType | none, dust, embers, data, spores |
LanternPresetId | solar_flare, dawn, shatter |
WorldMode | precomputed, scripted |
TriggerType | dialogue, spawn_wave, spawn_zone, checkpoint, event |
ZoneType | wilds, spoke_dark, spoke_lit, hub_dark, hub_lit |
Interfaces
ColorPalette
4-color palette — the single highest-leverage control. Every visual element samples exclusively from these 4 colors at varying opacities.
| Field | Used for |
|---|---|
base | Background, dark fills, wilds terrain tint, spoke fill |
line | Spoke edges, hub rims, structure lines, grid patterns |
accent | Particles, active glow effects, enemy tint, UI highlights |
illuminated | Lantern glow, lit hub wash, lit spoke edges, beacon color |
ZonePool / ZonePoolEntry
Per-zone spawn pool. spawnRate is enemies/second pre-director-modulation. pool is weighted entries; weights are relative, not percentages (comment recommends summing to 100 for readability).
SpawnZoneConfig
Five ZonePool slots: wilds, spoke_dark, spoke_illuminated, hub_dark, hub_illuminated. Backbone of zone-based spawning.
SpokeFlowConfig
enabled: boolean, speed: number (0-1; 0.2 barely perceptible, 0.5 clear current, 1.0 rushing stream).
ScriptedHub / ScriptedSpoke
Explicit placements for worldMode: 'scripted'. Hub has x, y, r, id. Spoke connects two hub IDs (aId, bId).
TriggerPayload / LevelTrigger
Proximity-based events. LevelTrigger fields: id, type, x, y, radius, optional oneShot, payload. Payload is a union grab-bag: text, speakerId, duration (dialogue); enemies, spawnRadius, pool, spawnRate (spawn_wave / spawn_zone); eventType (event).
Hub (runtime)
x, y, r, id, chunkKey. ID format "cx,cy:index".
Spoke (runtime)
a, b — indices into the allHubs array.
PrecomputedWorld
World data produced at level load: hubs[], spokes[], chunkSize, chunkHubIndices (Map "cx,cy" → indices), illuminationMap (Map hub.id → lit), eventCompletionMap (Map event.id → completed).
LevelConfig (the master object)
| Section | Fields |
|---|---|
| Identity | seed, pattern |
| Geometry knobs (0-1) | hubSize, spokeWidth, density (chaotic), ringRadius / ringCount (rings; ringCount maps to 1-3), blockSize (grid), stepSize / amplitude (zigzag) |
| 11 Designer Controls | palette (1), spokeStyle (2), hubStyle (3), terrainDensity (4), terrainType (5), illuminationColor (6), illuminationSpeed (7), spokeFlow (9), hubParticles (10), dangerTint (11) |
| Wilds | pathableWilds (when true, terrain fills only wilds zone with 75px minimum gap — ensures navigable corridors) |
| World mode | worldMode?, scriptedHubs?, scriptedSpokes? |
| Triggers | triggers? |
| Lantern VFX | lanternPreset |
| Spawning | spawnZones |
| Derived limits (set per terrain type, not user-tunable) | hubRMin, hubRMax, spokeWMin, spokeWMax |
Note: comments number designer controls 1–11 but skip “Control 8” — only 10 controls are present in source (palette, spokeStyle, hubStyle, terrainDensity, terrainType, illuminationColor, illuminationSpeed, spokeFlow, hubParticles, dangerTint).
illuminationSpeed: 0 = instant, 1 = 2s slow bloom.
dangerTint: 0 = neutral, 1 = oppressive red on unlit hubs/spokes.
Exported defaults
DEFAULT_SPAWN_ZONES
Placeholder until per-planet tuning. Spawn rates by zone:
| Zone | Rate (enemies/s) | Pool |
|---|---|---|
wilds | 0.4 | orb_common 50, charger_common 30, shooter_common 20 |
spoke_dark | 0.6 | orb_common 45, shooter_common 25, charger_common 20, mortar_common 10 |
spoke_illuminated | 0.2 | orb_common 75, shooter_common 25 |
hub_dark | 0.8 | shooter_common 35, orb_common 30, mortar_common 20, charger_common 15 |
hub_illuminated | 0.1 | orb_common 70, shooter_common 30 |
Pattern: dark zones spawn faster and pull harder enemies (mortars, chargers); illuminated zones spawn slow + only the soft pool (orbs + shooters). Hub_dark is the spike (0.8/s); hub_illuminated is the floor (0.1/s).
DEFAULT_PALETTE
Derelict Station — deep navy + cold blue + bright blue + warm gold.
| Field | Hex |
|---|---|
base | #0a0e1a |
line | #1e40af |
accent | #60a5fa |
illuminated | #fbbf24 |
DEFAULT_LEVEL_CONFIG
Chaotic pattern, Derelict Station preset. Hub/spoke sizes scaled for ~5000px world, terrain 100-960px.
| Field | Value |
|---|---|
seed | 42 |
pattern | chaotic |
hubSize / spokeWidth | 0.4 / 0.5 |
density | 0.5 |
ringRadius / ringCount | 0.5 / 0.3 |
blockSize | 0.5 |
stepSize / amplitude | 0.5 / 0.5 |
palette | DEFAULT_PALETTE |
spokeStyle / hubStyle | highway / station |
terrainDensity / terrainType | 0.5 / asteroids |
illuminationColor | #fbbf24 |
illuminationSpeed | 0.5 |
spokeFlow | { enabled: true, speed: 0.5 } |
hubParticles | data |
dangerTint | 0.5 |
pathableWilds | true |
worldMode | precomputed |
lanternPreset | solar_flare |
spawnZones | DEFAULT_SPAWN_ZONES |
hubRMin / hubRMax | 300 / 800 |
spokeWMin / spokeWMax | 120 / 400 |
How it is used
- Designer authors a
LevelConfigliteral per planet/tier. - World generator consumes
seed,pattern, geometry knobs, andworldModeto emit aPrecomputedWorld(or honorscriptedHubs/scriptedSpokes). - Renderer consumes
palette,spokeStyle,hubStyle,terrainType,hubParticles,spokeFlow,dangerTint,lanternPresetfor all visuals. - AI Director multiplies
spawnZones[zone].spawnRateat runtime; pool weights are sampled when a slot fires. - Illumination system reads
illuminationColorandilluminationSpeedto drive the golden-wash bloom when a lantern is lit. - Trigger system polls
triggers[]against player position vsradius; firespayloadbased ontype.
EXTRACT-CANDIDATE
- Per-planet
LevelConfigliterals. This file holds the schema and one default. Each planet/tier should live in its own data file (e.g.data/levels/derelict-station.ts,data/levels/<planet>.ts) exporting a fully-populatedLevelConfig. Keeps planet content in tables, schema in code. - Spawn pool tables.
DEFAULT_SPAWN_ZONESis flagged in-source as a placeholder. Extract per-planet spawn pools to a data table keyed by planet ID + zone, so balancing doesn’t touch type files. - Palette presets.
DEFAULT_PALETTEis hand-coded as “Derelict Station.” Apalettes.tstable mapping preset ID →ColorPalette(Derelict Station, plus future biomes) would let configs referencepalette: PALETTES.derelict_stationinstead of inline hex. - Lantern preset table.
LanternPresetIdis a string union but the preset bodies (timings, curves, particle counts) presumably live elsewhere; if they’re inlined in renderer code, lift to alanternPresets.tsdata table. - Terrain-type → derived-limits table. Comment says
hubRMin/Max,spokeWMin/Maxare “set per terrain type, not user-tunable.” That implies aTerrainTypeId→ limits lookup table is the right home, not free fields onLevelConfig. - Numbered-comment drift. Comments label designer controls 1, 2, 3, 4, 5, 6, 7, 9, 10, 11 — Control 8 is missing. Either the numbering is stale or a control was removed. Reconcile.