PUBLIC KNOWLEDGE BASEChapter Markdown ↓

MANDRIS / DESIGN REFERENCE

Technical design

How the current game is built and what new systems need to account for.

Snapshot: · Source ca26d81327a1

The game may have changed since this snapshot. Routine deployments do not update this reference.

Runtime architecture #

The active project uses TypeScript, Three.js, Vite, and plain DOM screens. Supabase supplies private co-op transport, room coordination, and optional accounts. The preserved Phaser/Vue project is a separate legacy reference and is not imported by the active game.

Input becomes player commands. A fixed-step deterministic simulation advances rules, returns snapshots, and queues semantic events. Rendering interpolates snapshots, while audio and effects consume events. Presentation must not alter simulation state or consume its randomness.

  • src/content/: stable definitions, balance, models, and presentation catalogs.
  • src/simulation/: combat, state, seeded randomness, collision, pickups, economy, checkpoints.
  • src/ThreeCombatRenderer.ts and presentation modules: 3D scene, interpolation, effects, lighting.
  • src/network/: transport, private rooms, ordered commands, checkpoints, and recovery.
  • src/ui/: DOM screens and UI lifecycle. src/main.ts coordinates the application.

Source reference: ARCHITECTURE.md · src/main.ts · src/simulation/MissionSimulation.ts

Determinism and compatibility #

Content, simulation, and network identifiers are stable strings rather than display names. Seeded simulation and independent scenery generation allow reproducible scenarios. Network changes must preserve command ordering and ownership, and deterministic state must survive checkpoint restoration.

The host applies store commands using per-pilot sequence tracking and bounded receipts so delayed or duplicated purchases cannot charge twice. Run identity, stage identity, mission preparation, and readiness are tracked through transitions. New deterministic systems need explicit state, snapshot, event, and restoration behavior.

Protocol and checkpoint versions are separate. A feature that changes message compatibility or restored state must update the relevant version and account for co-op clients on older builds.

Source reference: src/simulation/types.ts · src/network/contracts.ts · src/simulation/RunState.ts · ARCHITECTURE.md

Blender models and presentation #

Editable Blender projects and reproducible Python builders live in art/. Runtime assets live in public/assets/. Models use glTF/GLB, meters, Y-up coordinates, and forward -Z. Named mounts, collision objects, and animation clips form an asset contract.

Player hulls expose muzzle, thruster, and collision nodes; enemies expose Muzzle, Thruster, Collision, and role-specific nodes such as launch bays. The unit reference names the runtime model for each craft. Thumbnails are generated from the actual models and copied into this snapshot so future replacements do not alter this reference.

Silhouette, readable attack windups, visible weapon aim, hit reactions, damage panels, explosions, and debris communicate game state. The browser renderer uses bounded effect pools and reduced-motion alternatives. A large visual blast is not automatically evidence of a matching damage volume.

Source reference: src/content/actorModels.ts · src/content/crucible.ts · src/ThreeCombatRenderer.ts · art/ · ARCHITECTURE.md

Audio and cinematic presentation #

Audio is routed through event definitions, category controls, and per-mission sound sets that combine recorded, generated, and synthesized sounds. Source recipes and third-party credits are maintained alongside the asset pipeline.

Mission introductions and promotional media are presentation layers. They remain skippable or optional and must not delay reliable control.

Source reference: src/AudioDirector.ts · src/audio/catalog.ts · src/audio/foundryCues.ts

Constraints for new ideas #

  • Keep combat rules independent of Three.js, DOM, audio, and transport.
  • Budget active enemies, projectiles, summons, explosions, lights, and transparent effects. More simultaneous effects can hurt readability before they exhaust hardware.
  • Treat player count, overlapping abilities, boss phases, ground/air restrictions, and energy depletion as core design cases.
  • Telegraph enemy attacks on the unit, not with floor lanes or sweep fans that predict movement.
  • Provide visual cues beyond color alone, keyboard focus, readable contrast, and reduced-motion behavior.
  • New hulls and enemy families need model mounts, animations, tuning, collision, UI, audio, VFX, and co-op behavior.
  • The current main application and simulation modules are large. Prefer bounded modules and clear ownership when adding new systems.

Source reference: PRODUCT.md · ARCHITECTURE.md · CONTEXT_MAP.md

Development labs and tuning #

The admin library contains unit comparisons and model inspection, audio review, the Graphics, HUD, Orb, and Garmo labs. These tools make visual and balance review possible without repeatedly editing presentation code by hand.

This knowledge base is a separate, manual reference snapshot. It has no connection to live lab saves, player accounts, or gameplay state.

Source reference: src/ui/DevHub.ts · src/ui/OrbLab.ts · src/ui/HudLab.ts

Versions and simulation dimensions #

Source constants at snapshot time
ConstantValue
Fixed simulation step16.667 ms (60 Hz)
Network protocol122
Deterministic checkpoint115
Combat content1
Upgrade catalog28
Pilot flight altitude3.8 m
Field half width30 m

Source reference: src/simulation/types.ts · src/content/combat.ts · src/content/upgrades.ts

Specialized ability parameters #

The following are named configuration fields for implementation discussion. Ms suffixes mean milliseconds; distances and speeds use meters and meters/second, angles use radians, and fractions are dimensionless. Capacity and pool fields are bounds, not damage values. Only ability families used by ships in rotation are included.

Healing

CLASS_ABILITIES.healing
FieldValue
cooldownMs0
shieldPerSecond20
energyPerSecond34
startupEnergy10
range20
selfTargetDistanceRatio0.5

Salvo

CLASS_ABILITIES.salvo
FieldValue
energy60
count3
intervalMs0
damage23.94
range320
speed38
lifeMs8000
guidanceDelayMs180
acquisitionRange32
retentionRange48
turnRate3.142
maxActive64
groundY0.9
groundDescentMs250
radius6
fullRadius2
edgeDamageFraction0.5

Burst

CLASS_ABILITIES.burst
FieldValue
energy10
crossingCooldownReduction0.3
durationMs400
cooldownMs4000
movement2.8
missileCount4
missileDamage18
acquisitionRange32
missileSpeed22
missileRange54
missileLifeMs3000
steering0.18
bobAmplitude0.65
bobPeriodMs900
bobSettleRange6

Pods

CLASS_ABILITIES.pods
FieldValue
energy50
drainPerSecond0
durationMs10000
cooldownMs6000
damage8
rateMs125
range32
speed45

Twin Lasers

CLASS_ABILITIES.twinLasers
FieldValue
range44
drainPerSecond0
damage3.84
rateMs100

Event Horizon

CLASS_ABILITIES.eventHorizon
FieldValue
energy30
cooldownMs25000
durationMs5000
speed8
minRadius2.275
maxRadius9.5
absorptionCap20
pullRadius12
pullSpeed24
damage40
damagePerShot3
blastRadiusMultiplier1.8
collapseMs350
explosionMs800
enemyMass4
captureCap64
captureDamagePerSecond18
captureTickMs250
intakeMs1000
growthTimeMs450
captureRadiusMultiplier1.2
ejectSpeed32
ejectDurationMs900

Wrath

CLASS_ABILITIES.wrath
FieldValue
cooldownMs35000
flightMs3000
buildupMs1200
lingerMs1800
damage100
friendlyDamage20

Garmo

Garmo
FieldValue
primary.burstCount3
primary.spacingMs50
primary.muzzleSide1.35
primary.muzzleForward2.65
primary.pierce3
primary.blastRadius2.25
primary.blastFraction0.4
splinter.count3
splinter.acquisitionRange7
splinter.damageFraction0.35
splinter.speed36
splinter.lifeMs280
splinter.range10
splinter.radius0.09
splinter.maxActive96
conductive.durationMs4000
conductive.maxMarks64
conductive.detonationCooldownMs1200
conductive.damage18
conductive.radius3
arc.minimumEnergy8
arc.energyPerSecond32
arc.minimumChargeMs200
arc.chargeMs1000
arc.recoveryMs300
arc.minDamage40
arc.maxDamage140
arc.minTargets3
arc.maxTargets7
arc.range42
arc.acquisitionRadius4
arc.aimHalfAngle0.262
arc.jumpRange8
arc.conductiveJumpRange13
arc.falloff0.8
arc.flashMs300
pulse.damage12
pulse.radius9
pulse.energy12
pulse.drainPerSecond24
pulse.intervalMs400
pulse.cooldownMs1500
pulse.visualMs400
pulse.enterMs250
pulse.exitMs180
anchor.damage12
anchor.radius12
anchor.placementRange32
anchor.energy25
anchor.cooldownMs6000
anchor.durationMs15000
anchor.intervalMs700
anchor.pickRadius3
anchor.targets3
anchor.enterMs350
anchor.exitMs300
fracture.visualMs520
fracture.maxActive96

Michen

Michen
FieldValue
scale1.25
plating0.1
phoenix.countdownMs3000
phoenix.hullFraction0.5
phoenix.immunityMs1000
phoenix.damage600
phoenix.radius22
phoenix.aftermathMs1500
phoenix.wingspan24
photon.delayMs2000
photon.intervalMs4000
photon.damage60
photon.blastRadius6
photon.fullDamageRadius2
photon.edgeDamageFraction0.5
photon.speed24
photon.minTargetRange24
photon.acquisitionRange64
photon.range96
photon.lifeMs5000
photon.radius0.45
photon.maxActive2
photon.maxHits256
photon.steering6
photon.weaveAngle0.21
photon.weaveHz1.25
execution.threshold0.15
execution.durationMs650
execution.reducedDurationMs200
execution.maxRadius7
execution.poolSize32
flame.range16.8
flame.halfAngle0.393
flame.damagePerSecond63
flame.energyPerSecond36
flame.ignitionMs2000
flame.burnDamagePerSecond15
flame.burnDurationMs3000
flame.burnTickMs250
armor.energy35
armor.durationMs4000
armor.cooldownMs18000
armor.reduction0.8
armor.attractionRange10
armor.steeringPerSecond8
armor.reserveCap400
armor.damageFraction0.5
armor.shieldReturnFraction0.2
armor.minRadius6
armor.maxRadius18
warp.energy30
warp.cooldownMs10000
warp.chargeMs300
warp.damage40
warp.radius7
warp.visualMs900
slag.threshold60
slag.trailMs3000
slag.trailRadius1.6
slag.damagePerSecond24
slag.tickMs250
anvil.stunMs600
furnace.holdMs1500
furnace.cooldownMs4000
furnace.radius8
furnace.damage45
furnace.knockbackSpeed18
furnace.knockbackMs400

Holy Bolt

Holy Bolt
FieldValue
energyCost30
acquisitionRadius8
guidanceDelayMs100
steering0.24
speed34
outwardSpeed7
damage28
lifetimeMs1800
blastRadius5
fullDamageRadius2
edgeDamageFraction0.5
arrivalRadius0.6

Source reference: src/content/combat.ts: CLASS_ABILITIES, HOLY_BOLT · src/content/garmo.ts · src/content/michen.ts