PURPOSE

Central TypeScript type definitions for the runtime game state — the shared shape contract between the engine loop, bridge, world simulation, player/ship systems, rendering, UI, and reward services. Ported from the legacy 02-state.js. Pure types: no runtime code, no executable logic, no exports beyond interfaces and type aliases.

OWNS

  • GameState — the top-level mutable state singleton. Carries phase, time, level, XP, kill streak, tutorial flags, artifacts, modifiers, mission state (beacons, extraction, chase, scavenge, gauntlet, holdout, infiltrate, convoy, exterminate, boss), tracking, side quest, world knobs, vision config, bonuses, revive state, hull/invert/magnet/freeze visual flags, endless-level progression fields (_currentLevel, _attackSpeedMult, _totalMissionElapsed, _levelKind, _hardMode, _sealedArenaActive, _bossLevelCleared), enemyDifficultyLevel, levelSpeedMult, overtime/portal state, sandbox toggles, tick accumulator, Wheel of Fortune overlay, weapon/leveling slot caps, and reroll/banish economy.
  • ShipState — the player ship: position/velocity/angle, hull poly, HP/shield (with regen timers, fill-time tween, recovery flag, broken timer, ripple-origin angle, hit flash colors), thrust/drag/maxSpeed, turn squash internals, heat (legacy compat fields), invulnerability + watchdog flags (_invulnWallTime, _dontStuckInvuln, _gauntletPlayerDamageDisabled), exclusive states ('starpower' | null), shooting-star boost timer, spawn intro fade, damage white/blue flash, electric-hit VFX timer, weapon fire glow, pickups (magnet, luck, luckMult), weapons + slot count, life steal, XP mult, fixed angle override, melee mult, ship class ('heavy' | 'medium' | 'light'), per-ship physics tunables (scale, ram bleeds, restitution, friction, ram thresholds/damage range, push ratio, enemy solidity, contact decel/cooldown), vehicle-feel config (rotates, accelCurve, dragCurve, shake intensities/threshold, stop spring), ability flags (superHandling, currencyBonus, objectiveSpeed), death-defiance state, warp buff + warp-puddle group id + tween warpT, entity id, _base stats snapshot.
  • WorldState — the world: seed, all entity arrays (enemies, enemy bullets, timed strikes, player bullets, structures, belt, junk, particles, xp orbs, sigils, warnings, pickups, disco balls, conn nodes, jellyfish, blossoms, gems, dmg numbers, weapon/artifact boxes, destructibles, golden stars, comets, patrols, terrain, floaters, hubs, spokes, locations, events, defer queue, starlight beams, event stars, regen stations, forecasts), chunk maps + visited set, type counts, spawn timers (proximity/patrol/trickle accum/wave timer + count), biomeId, planetId, levelRadius, comet tween cometT.
  • CameraStatex/y/zoom, targetX/targetY/targetZoom, optional toS (world→screen) and toW (screen→world) conversion methods.
  • InputState — pointer + world coords, isDown, isThrusting, mobile flag, joystick (angle/magnitude/active), touch start coords, optional revive-button flags.
  • UILayout — canvas rect (x/y/w/h), center (cx/cy), padding, safe-area insets (safeT/safeB), edge anchors (left/right/top/bottom).
  • BossRoomState, BossRoom, BossArena — boss-arena shapes. BossArena defines spatial helper vocabulary (contains, clampPoint, randomPoint, cardinalPoints, ringPoints, edgePoints, oppositePlayer, radius, diagonal, bounds) referenced by affixes/abilities/AI/spawn profiles.
  • AffixInstance, AbilityInstance — definition-id + per-host mutable state envelopes.
  • EnemyEntity — base enemy contract: alive/pos/vel/hp/radius/flash + boss flags (isBoss, sharesHealthWithBoss, untargetable), affixes, abilities, optional displayName/barColor, plus permissive index signature for behavior-specific expandos.
  • SideQuest, GameTracking, GameStats — mission/run tally shapes. GameTracking covers damage/heal/shield/lowest-HP, event counts, weapon/upgrade/artifact lists, optional per-run artifactBestTier map, ability uses, distance, detections, trap kills + pct, gates hit/required, payload/object HP-remaining pct, POIs visited, sub-zone entered, enemy bullets fired/hit. GameStats carries killsByType, totals, elite kills, damage dealt/taken, distance, coins, max level, kills alias, timeElapsed, score, deathDefianceUsed.
  • WheelSliceType, WheelSlice, WheelState — Wheel of Fortune event overlay model (phase machine 'choosing' | 'spinning' | 'result', slice config with negative/jackpot flags, spin sub-phase 'fast' | 'decel' | 'tick', tick scheduling, reward-applied latch).
  • GamePhase — string-literal union of all top-level game phases: 'playing' | 'paused' | 'dead' | 'reward' | 'levelup' | 'birth' | 'boss_intro' | 'menu' | 'failed' | 'complete' | 'level_advance' | 'level_success' | 'artifact_choice' | 'results'.

READS FROM

  • ../../data/run-config — imports RunDefinition (used as the type of GameState.runDef).
  • ../../data/level-progression — imports LevelKind (used as the type of GameState._levelKind).

PUSHES TO

Nothing — this is a types-only module. Consumers import these interfaces directly; there are no runtime side effects, exports of values, or registrations.

DOES NOT

  • Define default values, factory functions, or constructors. Initial state lives elsewhere (bridge/state init).
  • Contain behavior, validation, or invariants. Index signatures ([key: string]: any on EnemyEntity) and any[] fields are permissive by design.
  • Provide narrow types for weapons, artifacts, activeModifiers, rewardQueue, currentReward, missionGems, beacons, extractionPayload, chaseTarget, scavengeCaches, scavengeMilestones, gauntletGates, defendObject, infiltrateTarget, patrols, convoyPayload, hazards, baitItems, activeEvent — all typed any / any[].
  • Define the world chunks or entity sub-shapes — WorldState.chunks is Record<string, any>, all entity arrays in WorldState are any[].
  • Track or own runtime state itself — only describes its shape.

Signals

None. This module emits no signals (no imports from ./signals or any pub/sub system).

Entry points

None. Type-only module — no functions, no default export, no runtime entry. Importers reference named interfaces and type aliases directly.

Pattern notes

  • Underscore-prefixed fields (_dt, _rawDt, _simFrame, _stepsThisFrame, _hullFlash, _invertScreenTimer, _magnetIconTimer, _weaponChestFreeze, _hitFreezeTimer, _currentLevel, _attackSpeedMult, _totalMissionElapsed, _levelKind, _hardMode, _sealedArenaActive, _bossLevelCleared, _baseSpeedMult, _baseDamageMult, _baseHpMult, _tick1sAccum, _wheelState, _postRewardLevelAdvance, _activeBossDefId, _bossSpawnerDisabled, _testSpeedMult, _pendingBarDamage, _sandboxSpawnerEnabled, _currentMissionId) mark engine-internal scratch fields not meant for game-logic consumers.
  • Ship _base: Record<string, number> snapshots starting stats so per-run modifiers can recompute deltas off a stable baseline.
  • Boss state is split: BossRoom owns the closing/locked animation (shape, currentR/targetR, currentW/currentH), while BossArena wraps it and exposes the spatial-helper API. Patterns/affixes use BossArena only — never raw screen size or world coords.
  • AffixInstance and AbilityInstance share the same definition-id + mutable state: Record<string, unknown> envelope. Behavior registry lives outside; the enemy carries only data.
  • EnemyEntity keeps shared combat/runtime fields explicit while allowing arbitrary expandos via [key: string]: any for behavior-specific data.
  • GameState.runDef: RunDefinition | null is the canonical source of truth for run composition (facilities, codex, vision, event/weapon pools) — comment instructs reading from it instead of copying into game state.
  • Optional fields (?) flag values populated lazily by the engine (_dt, _rawDt, _simFrame, _stepsThisFrame, _postRewardLevelAdvance, _exclusiveStateMaxTimer, _shootingStarBoostTimer, _dontStuckInvuln, _gauntletPlayerDamageDisabled, _sandboxSpawnerEnabled, artifactBestTier, revivePressed, reviveDismiss, displayName, barColor, camera toS/toW).
  • WheelState.spinSubPhase is a three-stage state machine ('fast' | 'decel' | 'tick') wrapped by an outer phase machine ('choosing' | 'spinning' | 'result').
  • ShipState.exclusiveState: 'starpower' | null is currently a single-value union — designed to expand as more exclusive states are added.
  • ShipState.shipClass: 'heavy' | 'medium' | 'light' governs speed-bleed on collision: heavy = 5% loss (piercers), medium = 15% (default), light = 50% (fragile).
  • Heat fields on ShipState (heat, heatBurnRate, heatCoolRate, heatSpeedTarget, heatBoostMult, heatCurve, burnoutSeverity, stalled, coolingAccel, stallSpin, stallSpinDecay) are kept for legacy compatibility but not actively used.
  • ASCII banner comments (════…) section the file into GAME STATE / WHEEL / SHIP / WORLD / CAMERA / INPUT / UI LAYOUT / GAME PHASES.