At a glance
StellarFronts is built around logistics, expansion, economy, research, and market trading — not direct combat. The full stack starts with a single npm run dev:all that brings up the React client, the HTTP auth server, the WebSocket game server, and the orchestrator together.
Architecture
The codebase is split clean down the middle: src/ is the React UI, shared gameplay types, and the BabylonJS scene layer; server/ is the auth server, the game server, and the orchestrator that ties everything together behind one public gateway. Each process has a single clear responsibility — and they fail independently.
WebSocket Protocol (V2 / Schema V20)
Game loop & time compression
The server runs a setInterval tick every 100ms. Each tick advances the game clock by a configurable amount — from 1 game-hour per second (detail mode) up to 360 game-days per second (fast-forward). Everything — economy production, fleet movement, construction progress, combat resolution — is calculated against elapsed game-time, so the simulation is consistent regardless of speed.
100ms server tick
Game state advances every 100ms real-time. All simulation — fleet movement, economy, combat, events — resolves in each tick against elapsed game-days.
9 speed presets
1hr/s through 360 days/s. Clock is always in game-years + fractional days. Client interpolates displayed year from last-known server clock to avoid stale reads.
30s dirty-write save
State is only written to disk when marked dirty. Full JSON snapshot per game in game_states/{id}/state.json. Timestamped backups before any destructive operation.
Faction-scoped snapshots
Server computes visible star IDs via BFS up to N hyperlane jumps from faction territory. Snapshot and update messages are filtered per client — other factions' unseen territory is never sent.
Client-side interpolation
The client doesn't wait for a server tick to update the displayed game year — it calls estimateClockYear() to linearly interpolate from the last known server timestamp and speed setting. The UI always feels live, even at 100ms tick intervals.
In-game events & situations
Events (short-term: one-off modifiers, crises, opportunities) and Situations (long-running: persistent states that evolve over time) fire based on game state conditions each tick. They dynamically alter demand, dispute risk, research rates, and deal difficulty — no two games play the same.
Economy simulation
Every planet runs a full job-and-building economy. Six strategic resources flow through production chains, population grows under demographic pressure, and buildings unlock via a 64-technology research tree. The economy resolves at two cadences: per-hour for resource flows and per-quarter for population growth.
12 job types · 3 classes
Upper (admin, researcher), Middle (artisan, metallurgist, entertainer, technician, clerk), Lower (farmer, miner, enforcer). Unemployment and crime are modelled as job types with negative effects.
14 building types · 5 levels
Four district types (City, Mining, Generator, Agriculture) each host specific buildings. Unlocking level 2–5 requires matching research. Higher levels multiply job output rather than add slots.
6-factor growth model
Housing, amenities, stability, crime, employment, and capacity pressure all feed a monthly growth rate. 1 pop unit = 1 million people. New colonies start at 500M; developed worlds at 10B.
Penalty modifiers on scarcity
When a resource runs critically low, output penalties propagate — a food shortage cuts farm output further, tightening the squeeze. Forces players to prioritise supply chains.
4 district types · land-use zoning
City, Mining, Generator, and Agriculture districts each host specific building sets. District slots are finite on each planet — choosing which to build shapes the planet's economic identity for the whole game.
10+ species · trait modifiers
Each species has a habitability modifier per planet class, a growth rate multiplier, and production trait bonuses. Civil rights level (enslaved → full) affects happiness, job distribution, and faction-wide output.
Research & technology tree
64+ technologies across seven categories. Research isn't a flat rate — it's a dynamic modifier system where your military strength, fleet size, active wars, resource surpluses, and job counts all feed live multipliers on your research speed, making the rate a direct reflection of your empire's current state.
Context-aware speed
Active war → research bonus. Large fleet → bonus. High researcher job count → multiplier. All modifier contributions are reported in a breakdown so the player sees exactly why their speed is what it is.
80% active · 20% passive
Each tech receives active focus allocation from the queue, plus a passive bleed. Passive progress is capped at 80% of active pace, so you can't finish techs purely via passive — maintaining queue priority matters.
Buildings, hulls, modules
Technologies unlock building levels 1–5, ship hulls (corvette → battleship), ship modules (weapons/defense/utilities), starbase buildings, and job output multipliers.
1.0× min · 2.0× max
Research multipliers are bounded to prevent degenerate fast or slow states. Even a fully isolated empire produces research; even a warring one can't infinitely accelerate.
Start-of-game tech baseline
Every empire starts with Spacefaring Foundations (corvettes, construction ships, colonisation ships), Directed Energy Weapons (lasers), Missile Ordnance, and Defensive Systems (shields, armour, sensors) — playable from turn one.
Research Campus building
A dedicated building type that unlocks Research Annex slots on starbases. Stacks with researcher job count and leader bonuses. The campus is the primary way to push the research rate past its baseline.
Market & trade dynamics
The galactic market uses a dual-decay pressure system: every trade causes immediate price impact that decays quickly, plus a slower persistent trend that reflects long-run supply/demand. Prices are bounded (0.25× – 4.0× base) and carry a 5% fee. Energy and research are intentionally non-tradeable — they're internal chokepoints that force infrastructure investment.
Base prices per resource
Food 1.1 · Minerals 1.4 · Goods 3.2 · Alloys 5.5 · Research 6.5 (non-tradeable). Multiplier shifts with trade pressure, bounded at 0.25×–4.0× base.
Two-speed decay model
Temporary pressure (per-trade impact) decays at 0.96× per hour. Persistent pressure (trend) decays at 0.995× per hour. Large trades have outsized impact scaled by √(amount/liquidity).
1,200–10,000 units per resource
Base liquidity determines how much a trade moves the price. Small empires can't whale the market; large coordinated trading does shift prices meaningfully.
180 price snapshots · 6hr interval
30 days of market history per resource stored server-side. Clients subscribe to receive market detail updates and can render price trend graphs.
Server-side hourly resolution
Factions can set standing buy/sell orders that resolve automatically each hour. Auto-trade pressure impact (0.01× √(amount/liquidity)) is gentler than manual trades, keeping AI participation from dominating price signals.
5% fee · 320 transaction history
All trades carry a 5% market fee — a consistent sink that drains wealth from hyperactive traders. Transaction history is capped at 320 entries per resource; oldest trades are evicted to prevent unbounded memory growth.
Combat engine
Combat resolves in discrete rounds. Weapons hit based on range-band accuracy rolls modified by dodge chance and range-to-optimal distance. Damage penetrates a three-layer defence stack: shields (regenerating), armour (permanent until repaired), and hull (ship destroyed at 0). Fleet tactics — stance, formation, retreat policy — meaningfully alter engagement outcomes.
| Weapon | Range bands | Cooldown | Characteristic |
|---|---|---|---|
| Laser | Close–Medium (6–30u) | 1 round | High accuracy, rapid fire, balanced damage |
| Missile | Medium–Long (16–46u) | 2 rounds | Flight time, interceptable, high burst damage |
| Point Defence | Point blank–Close (0–16u) | 1 round | Anti-projectile, degrades incoming missile salvos |
| Railgun | Close–Long (6–46u) | 1 round | Armour penetration, effective against hardened hulls |
| Plasma | Medium–Long (16–64u) | 2 rounds | Hybrid shield + hull damage, high energy cost |
Distance → mechanic mapping
Point blank (0–6u), Close (6–16u), Medium (16–30u), Long (30–46u), Extreme (46–64u), Out of range. Each weapon has an optimal band where accuracy peaks; performance degrades outside it.
Shield → Armour → Hull
Shields regenerate slowly over time. Armour is permanent damage until ship is repaired at a starbase. Hull hits are crits — ship destroyed at 0. Weapon types have different penetration profiles against each layer.
5 combat behaviours
Artillery (long-range standoff), Line (coordinated broadside), Brawler (close-range mass), Swarm (redundancy through numbers), Defender (hold position, prioritise survival). Stance affects effective DPS and positioning.
Configurable withdrawal threshold
None · Low (20% HP) · Medium (40% HP) · High (60% HP). Combined with chase policy (pursue into friendly/neutral/enemy systems) — lets you build aggressive or defensive fleet doctrines.
Hull + module system
Six hull classes (corvette → destroyer → cruiser → battleship → construction → colonisation). Each hull has weapon, defence, and utility module slots. Unlocking higher hulls and modules via research shapes your fleet's tactical role.
Leader traits → combat multipliers
Each fleet can be assigned a leader with trait bonuses — e.g. "Genius" adds +25% to speed, attack, or shields. Leader assignment is a non-trivial optimisation: the right trait on the right fleet significantly changes engagement outcomes.
3D rendering pipeline
The game switches between two scenes: a galaxy view showing the full star map with faction ownership overlays, and a system view where you zoom into a single star system with 3D ships, starbases, planets, and live combat effects. BabylonJS automatically selects WebGPU if the browser supports it, falling back to WebGL2 — no configuration needed.
WebGPU → WebGL2 auto-fallback
SceneManager.ts detects WebGPU support at startup. If available, the modern API runs with better GPU utilisation. WebGL2 handles everything else. Single code path handles both.
500+ stars · ownership overlay
Stars rendered as sprites with type-specific colours. Hyperlane connections drawn as dynamic 2D lines. Faction ownership painted onto a 2400×2400 procedural texture updated per-tick. Fog of war fades unseen territory.
5,200-line renderer
Orbital ring meshes, planet spheres with procedural textures, star coronas and particle effects (including pulsar beams and black hole accretion disks), ship model trails, weapon beam effects, and dynamic label overlays — all in one scene.
10 GLB models — ships + starbases
6 ship hulls (corvette, destroyer, cruiser, battleship, construction, colonisation) and 4 starbase tiers. SystemAssetRegistry.ts loads and normalises each model to a target size via bounding-box scaling, then clones on demand — no re-loading per spawn.
Perlin-noise skybox
Both scenes generate their space background procedurally from a seed — no external texture asset. The nebula colours vary with the nearby star type, giving each system a distinct atmosphere without artist-authored sky assets.
Asset instancing + lazy scenes
GLB templates loaded once, cloned on-demand. Asset warm-up runs on the auth screen so the first system view boots instantly. Only the active scene runs a render loop — the inactive one is fully disposed.
What you can do in-game
Claim a country
Normal accounts pick from generated factions on join — each with a procedurally generated flag, species, and home system. Observers and admins enter without claiming.
Explore the galaxy
BabylonJS 7 command view with a procedural skybox, loaded GLB ship and starbase models, and HUD overlays. Fog of war limits visibility to 3 hyperlane jumps from your territory.
Expand with starbases
Build Outpost → Starbase → Starhold → Starfortress. Each tier adds building slots. Starbases produce resources, host ship construction queues, and assert territorial control.
Run an economy
Manage 6 resources across 14 building types on every colony. Assign jobs, build districts, keep population happy, and route surpluses to the galactic market.
Research technologies
Queue 64+ techs across 7 categories. Unlock ship hulls, building levels, module types, and job bonuses. Research speed reflects your current empire state dynamically.
Trade on the market
Buy and sell 4 tradeable resources on the galactic market. Price impact scales with trade volume. Watch 30 days of price history to time your moves.
Build and command fleets
Design ships from hull + module combinations. Set stances, formations, and retreat thresholds. Assign a fleet leader with traits that multiply speed, attack, and shields.
Manage diplomacy
Declare wars, negotiate peace terms (reparations, system transfers, vassalage), propose trade treaties, and set border policies. Faction reputation affects AI responses.
Hold sessions
Game state persists per-game on a dirty-write timer. Leave and return — your country, fleets, and economy are exactly where you left them.
Accounts & visibility
| Role | Can claim country | Map visibility | Debug commands |
|---|---|---|---|
| Player | Yes — one generated country per game | Scoped to held territory (3-jump BFS) | No |
| Observer | No | Full read-only | No |
| Admin | Optional | Full | Yes — in-game console + /dev panel |
Seeded accounts on a fresh setup: observer / observer, an admin account at the configured admin password, and color_1 through color_15 as player accounts.
Full stack
React 19 + Vite + TypeScript
Pathname-driven routing in App.tsx. Single useAppFlow hook owns auth state, loading progress, and scene transitions. No external state library — React state + WS events are sufficient.
BabylonJS 7
WebGPU/WebGL2 auto-selection. GalaxyScene and SystemScene each 2,600–5,200 lines. GLB asset loading with bounding-box normalisation and clone-on-demand instancing.
Node.js WebSocket server
Long-lived Node process. Auth and game servers are separate — login can't take the game server down. Incremental update protocol keeps bandwidth low at scale.
PBKDF2-SHA512 · 210,000 iterations
64-byte keys. Session tokens hashed with SHA-256. Timing-safe comparison on every login. HttpOnly cookies with 7-day TTL. CORS-gated endpoints. Enterprise-grade security for a game project.
SQLite + JSON state
Accounts and dev stats in SQLite (auth.sqlite). Per-game world state written to JSON on a 30s dirty-write timer. Schema versioned to V20 with backward-compatible migration path to V1.
Git-worktree orchestrator
Multi-version process management. Each version = isolated git worktree + Node process. Public WS gateway proxies to correct version. Crash recovery, backup-before-destructive-ops, compatibility-gated updates.
16 test files · 92 test cases
Every major server system has its own test file: economy, market, state, diplomacy, combat, government, species, technology, events, tactical-formation, ship-designs, versioning, auth-store, admin-commands, system-view, and system-view-store. All 92 pass before any merge. Catches balance regressions and protocol breaks before they ship to live games.
Vercel Analytics
Lightweight client-side analytics on the React app for usage signals. No custom telemetry — keeps the codebase lean and privacy-safe.
Galaxy · skybox · flags · planets
Star maps seeded per-game (500+ systems, procedural hyperlane graph). Perlin-noise skybox per scene — no texture assets. Faction flags generated via SVG from pattern + colour presets. Planet textures derived from class type. Zero art assets for environments.
Development progress
139 commits, Feb 26 – Jun 17 2026. The real story isn't the total — it's the shape: a slow start while the 3D prototype proved the concept, then a single month (May) that delivered 102 commits and the entire game engine. That's sustained focus: the commit log shows 8–10 pushes on individual days, week after week, for the entire month.
Status
Actively in development and live at stellarfronts.com. The full loop — login, claim, explore, expand, run an economy, research, trade, persist — is wired end-to-end. Systems and balance are explicitly still a work in progress. Google and Microsoft OAuth endpoints are stubbed and return 501 until turned on. Next priorities: OAuth, balance passes, and expanding the content pool.
Play it. Read the code.
The game is live at stellarfronts.com. The full source — including the orchestrator, game server, auth server, and React client — is on GitHub.