window.GDD = window.GDD || {}; function BackendPage() { const [activeSection, setActiveSection] = React.useState('tables'); const [galaxySubSection, setGalaxySubSection] = React.useState('galaxy-overview'); return (

SpacetimeDB Backend Model

The backend holds persistent, authoritative state and exposes server-side reducers for game actions. Clients subscribe to the rows they need and update reactively.

{[ { id: 'tables', label: 'Tables' }, { id: 'reducers', label: 'Reducers' }, { id: 'movement', label: 'Movement Model' }, { id: 'galaxy', label: 'Galaxy Simulation' }, { id: 'er', label: 'ER Diagram' }, ].map(t => ( ))}
{activeSection === 'tables' && ( <>

Data Tables

{[ { name: 'players', purpose: 'Player account/session profile', fields: 'player_id, identity, display_name, current_system_id, created_at' }, { name: 'ships', purpose: 'Active ship state', fields: 'ship_id, owner_player_id, system_id, x/y/z, destination, speed, status' }, { name: 'regions', purpose: 'Galaxy regions (core, frontier, deep null)', fields: 'region_id, name, description, faction_id, security_profile, x/y/z (galaxy coords)' }, { name: 'constellations', purpose: 'Star clusters within regions', fields: 'constellation_id, region_id, name, gate_connections (json), x/y/z (region coords)' }, { name: 'factions', purpose: 'NPC factions with territory, goals, and military/economic strength', fields: 'faction_id, name, ideology, territory_region_ids (json), military_strength (f64), economy_strength (f64), diplomatic_stance (enum)' }, { name: 'systems', purpose: 'Star systems within the single galaxy', fields: 'system_id, name, region_id, constellation_id, security_level, x/y/z (galaxy coords), star_type, description' }, { name: 'planets', purpose: 'Planets orbiting stars', fields: 'planet_id, system_id, name, planet_type, orbit_radius, orbit_period, resources' }, { name: 'moons', purpose: 'Moons orbiting planets', fields: 'moon_id, planet_id, name, moon_type, orbit_radius, resources' }, { name: 'orbiting_objects', purpose: 'Stations, belts, anomalies in orbital slots', fields: 'object_id, parent_body_id, object_type, orbit_radius, name, state' }, { name: 'stations', purpose: 'Docking and trading locations', fields: 'station_id, system_id, name, x/y/z, services' }, { name: 'asteroids', purpose: 'Mineable resource nodes', fields: 'asteroid_id, system_id, resource_type, quantity, x/y/z' }, { name: 'inventory_items', purpose: 'Player/station item storage', fields: 'item_id, owner_player_id, location, item_type, quantity' }, { name: 'market_orders', purpose: 'Buy/sell orders', fields: 'order_id, station_id, seller_id, item_type, price, quantity, status' }, { name: 'chat_messages', purpose: 'Local/system chat stream', fields: 'message_id, channel_id, sender_id, body, created_at' }, { name: 'active_actions', purpose: 'Long-running actions', fields: 'action_id, player_id, action_type, target_id, started_at, completes_at' }, { name: 'faction_relations', purpose: 'Dynamic NPC faction relationship matrix', fields: 'faction_a_id, faction_b_id, standing (-10 to +10), trend (rising/falling/stable), last_event_id' }, { name: 'world_events', purpose: 'Active world simulation events', fields: 'event_id, event_type, system_id, severity, started_at, expires_at, state, participants' }, { name: 'galaxy_story_log', purpose: 'Persistent server story timeline', fields: 'log_id, event_id, chapter, headline, body, timestamp' }, { name: 'bookmarks', purpose: 'Player-saved locations', fields: 'bookmark_id, player_id, system_id, x/y/z, name, created_at' }, { name: 'waypoints', purpose: 'Multi-stop navigation routes', fields: 'route_id, player_id, stops (ordered system list), name, shared' }, { name: 'bounties', purpose: 'Bounty pool per target', fields: 'target_player_id, total_pool, tier, last_hostile_act' }, { name: 'bounty_contributions', purpose: 'Individual bounty payments', fields: 'contribution_id, target_id, contributor_id, amount, timestamp' }, { name: 'kill_feed', purpose: 'Ship destruction events', fields: 'kill_id, victim_id, killer_id, ship_type, system_id, bounty_collected, timestamp' }, { name: 'player_skills', purpose: 'XP and levels per skill', fields: 'player_id, skill_name, xp, level, last_action_at' }, { name: 'fleet_beacons', purpose: 'Temporary fleet rally points (post-MVP)', fields: 'beacon_id, fleet_id, creator_id, system_id, x/y/z, expires_at' }, { name: 'ship_ai_soul', purpose: 'Soul document and personality state per ship', fields: 'ship_id, soul_md (text), growth_vectors (json), personality_state (json), soul_depth (u32), created_at, last_updated_at' }, { name: 'ship_ai_modules', purpose: 'Installed AI modules and fitting state', fields: 'module_id, ship_id, module_type (enum), tier, slot (med/low), cpu_cost, grid_cost, active, fitted_at' }, { name: 'ship_ai_tools', purpose: 'Tool registry derived from fitted modules', fields: 'tool_id, ship_id, tool_name, source_module_id, parameters_schema (json), return_schema (json)' }, { name: 'ship_ai_memory', purpose: 'Event log and conversation history', fields: 'memory_id, ship_id, category, content, related_event_id, timestamp, importance_score' }, { name: 'ship_ai_directives', purpose: 'Player-set goals for autonomous mode', fields: 'directive_id, ship_id, description, priority, deadline, status, created_at' }, { name: 'ship_ai_agent_runtime', purpose: 'Per-ship agent loop state and tick schedule', fields: 'ship_id, implementation_tier (0/1/2), tick_interval_ms, next_tick_at, token_budget, status' }, { name: 'ship_ai_soul_events', purpose: 'Audit log of soul-shaping events', fields: 'event_id, ship_id, event_type, soul_md_delta, applied_at' }, { name: 'ship_types', purpose: 'Ship class definitions (stats, slot layout)', fields: 'type_id, name, class, hull, armor, shield, high_slots, med_slots, low_slots, cpu, power_grid, cargo, speed, mass, base_hull_value' }, { name: 'modules_catalog', purpose: 'Module definitions (stats, slot type, costs)', fields: 'module_id, name, slot_type (high/med/low), cpu_cost, grid_cost, category, tier, effects_json' }, { name: 'ship_fittings', purpose: 'Which modules are fitted to which ship slots', fields: 'fitting_id, ship_id, slot_index, module_id, online (bool)' }, { name: 'npc_entities', purpose: 'Active NPC pirates and hostiles', fields: 'npc_id, system_id, class_id, behavior_template, x/y/z, hull/armor/shield, target_id, state, spawn_location, spawn_time' }, { name: 'npc_class_templates', purpose: 'NPC type definitions and stats', fields: 'class_id, name, tier, hull_base, armor_base, shield_base, speed, damage, behavior, loot_table_id, bounty' }, { name: 'loot_tables', purpose: 'Drop tables for NPC kills and wrecks', fields: 'table_id, entries (item_type, min_qty, max_qty, drop_chance), security_band' }, { name: 'blueprints', purpose: 'Manufacturing recipes', fields: 'bp_id, product_type, product_qty, materials_json, time_seconds, skill_requirements' }, { name: 'manufacturing_jobs', purpose: 'Active manufacturing queues', fields: 'job_id, player_id, station_id, bp_id, started_at, completes_at, status, output_location' }, { name: 'skills_catalog', purpose: 'Skill definitions and XP curves', fields: 'skill_id, name, category, xp_curve (array), unlocks_json, max_level' }, { name: 'chat_channels', purpose: 'Channel definitions and properties', fields: 'channel_id, name, type (local/trade/private/corp), scope, owner_id, created_at' }, { name: 'insurance_policies', purpose: 'Active ship insurance contracts', fields: 'policy_id, player_id, ship_id, tier, premium_paid, payout_value, purchased_at, expires_at, active' }, { name: 'ship_type_base_values', purpose: 'Base hull values for insurance', fields: 'ship_type_id, base_hull_value, insurance_premium_mult' }, { name: 'station_commodity_demand', purpose: 'Per-station per-commodity demand state for NPC pricing', fields: 'station_id, commodity_id, flow_ema (f64), demand_pressure (f64, [0.8–1.4]), volume_sold_to_npc, volume_bought_from_npc, npc_stock_remaining, last_tick' }, { name: 'commodity_price_params', purpose: 'Base prices and adjustment parameters per commodity', fields: 'commodity_id, base_price (f64), buy_spread (f64, [0.65–0.85]), sell_spread (f64, [1.10–1.35]), ema_alpha (f64), pressure_beta (f64), decay_gamma (f64)' }, { name: 'regional_price_seeds', purpose: 'Static regional modifiers set at galaxy generation', fields: 'region_id, commodity_id, modifier (f64, [0.6–1.5])' }, { name: 'npc_agents', purpose: 'NPC agents at stations offering missions', fields: 'agent_id, name, faction_id, station_id, specialty (kill/courier/mining/survey/trade/escort), quality (u32), mission_levels_offered, dialogue_seed' }, { name: 'mission_templates', purpose: 'Mission type definitions and objectives', fields: 'template_id, type (enum), level (1–4), title, description_template, objectives_json, reward_base, time_limit_seconds, security_band_min, skill_requirements_json, faction_id' }, { name: 'active_missions', purpose: 'Currently active player missions', fields: 'mission_id, player_id, agent_id, template_id, objectives_state_json, status (active/completed/failed/expired), accepted_at, expires_at, completed_at' }, { name: 'player_standing', purpose: 'Player standing with agents and factions', fields: 'player_id, entity_id, entity_type (agent/faction), standing (f64, −10 to +10), last_mission_at' }, { name: 'player_loyalty_points', purpose: 'Faction loyalty point balances', fields: 'player_id, faction_id, lp_balance (u64), lifetime_earned (u64)' }, { name: 'mission_offers', purpose: 'Current mission offerings at stations', fields: 'offer_id, agent_id, station_id, template_id, reward_modifier, expires_at, generated_at' }, { name: 'balance_metrics', purpose: 'Balancing Agent metric tracking', fields: 'metric_name, current_value (f64), healthy_min, healthy_max, last_updated, trend (rising/falling/stable)' }, { name: 'balance_levers', purpose: 'Balancing Agent control levers', fields: 'lever_name, current_multiplier (f64), target_multiplier (f64), clamp_min, clamp_max, last_adjusted_at' }, { name: 'balance_audit', purpose: 'Balancing Agent intervention log', fields: 'audit_id, tick_time, metrics_snapshot_json, adjustments_json, reason' }, ].map((row, i) => ( ))}
TablePurposeKey Fields
{row.name} {row.purpose} {row.fields}
)} {activeSection === 'reducers' && ( <>

Reducers (Server Commands)

{[ { name: 'connect_player(display_name)', trigger: 'Player opens app', resp: 'Create/update player row, spawn initial ship if needed.' }, { name: 'set_destination(ship_id, x, y, z)', trigger: 'Click in space', resp: 'Validate ownership/status, update destination/vector.' }, { name: 'dock(station_id)', trigger: 'Click dock', resp: 'Check distance, set ship docked, update location/state.' }, { name: 'start_mining(asteroid_id)', trigger: 'Click mine', resp: 'Check range, asteroid quantity, ship status, create active action.' }, { name: 'complete_mining(action_id)', trigger: 'Timer/event', resp: 'Transfer ore into inventory, reduce asteroid quantity.' }, { name: 'sell_item(item_type, qty, station)', trigger: 'Sell from UI', resp: 'Validate inventory and station, exchange ore for ISK.' }, { name: 'place_market_order(...)', trigger: 'Market UI', resp: 'Reserve inventory, create sell order.' }, { name: 'send_chat(channel_id, body)', trigger: 'Chat box', resp: 'Validate/rate-limit, append chat message row.' }, { name: 'world_tick(ctx)', trigger: 'Server timer (5 min)', resp: 'Evaluate galaxy state, player density, faction matrix. Conditionally spawn PvE events (faction conflicts, anomalies, migrations, raids). Propagate active events.' }, { name: 'spawn_world_event(event_type, system_id, params)', trigger: 'World tick evaluation', resp: 'Create world_event row, generate story log entry, notify nearby players via sensors, set expiration timer.' }, { name: 'resolve_world_event(event_id, outcome)', trigger: 'Event timer or player action', resp: 'Update galaxy state based on outcome, write story log chapter, adjust faction relations, trigger cascading events.' }, ].map((row, i) => ( ))}
ReducerClient TriggerServer Responsibility
{row.name} {row.trigger} {row.resp}
)} {activeSection === 'movement' && ( <>

Movement Model

Avoid sending per-frame movement. Store destination and speed. Clients interpolate visually; the backend periodically updates authoritative positions.

Movement Flow

1. Client calls set_destination(ship_id, x, y, z)
2. Server validates ownership + ship status
3. Server updates ships.destination + calculates velocity vector
4. Server broadcasts updated ship state to subscribers
5. Client interpolates visual position between last known + destination
6. Server periodically updates authoritative x/y/z position

Client-side interpolation

Smooth visual movement between authoritative position updates. Uses dead reckoning with periodic server correction. Handles latency spikes gracefully.

Server authority

Backend is the source of truth for all positions. Clients never modify their own position directly — they submit intentions and wait for confirmation.

)} {activeSection === 'galaxy' && ( <>
{[ { id: 'galaxy-overview', label: 'Overview' }, { id: 'galaxy-gen', label: 'Galaxy Generation' }, { id: 'galaxy-events', label: 'World Events' }, ].map(g => ( ))}
{galaxySubSection === 'galaxy-overview' && (<>

Galaxy Simulation Layer

Single galaxy, simulated world. The server maintains one persistent galaxy with a connected graph of star systems, each containing planets, moons, asteroid belts, and stations. A world simulation layer runs on top, spawning dynamic PvE events that create a unique story per server. This is not instanced content — every player in the galaxy shares the same world state.

Galaxy Topology

Galaxy → contains Regions (4–8 regions, each with distinct character)
Region → contains Constellations (3–6 per region, connected clusters)
Constellation → contains Systems (2–8 per constellation, gate-connected)
System → contains Star + Planets + Moons + Belts + Stations + Anomalies
Planet → has orbiting_objects (stations, moon mining outposts, customs offices)

World Simulation Tables

Overlap note: faction_relations, world_events, and galaxy_story_log also appear in the Tables tab with abbreviated field descriptions. The definitions below are the expanded versions with full field detail. Both tabs describe the same underlying tables.
{[ { name: 'regions', purpose: 'Galaxy regions (core, frontier, deep null)', fields: 'region_id, name, description, faction_id, security_profile' }, { name: 'constellations', purpose: 'Star clusters within regions', fields: 'constellation_id, region_id, name, gate_connections' }, { name: 'factions', purpose: 'NPC factions with territory and goals', fields: 'faction_id, name, ideology, territory_region_ids, military_strength, economy_strength' }, { name: 'faction_relations', purpose: 'Dynamic relationship matrix', fields: 'faction_a_id, faction_b_id, standing (-10 to +10), trend (rising/falling/stable), last_event_id' }, { name: 'world_events', purpose: 'Active PvE events in the galaxy', fields: 'event_id, event_type, system_id, severity (1–5), started_at, expires_at, state, participants_json, params_json' }, { name: 'world_event_templates', purpose: 'Event blueprints with spawn conditions', fields: 'template_id, type, name, min_severity, max_severity, spawn_weight, required_faction_state, cooldown_hours' }, { name: 'galaxy_story_log', purpose: 'Persistent server timeline — the “history” of this galaxy', fields: 'log_id, event_id, chapter_index, headline, body, affected_systems, timestamp' }, { name: 'space_fauna', purpose: 'Migrating space creatures', fields: 'fauna_id, species, current_system_id, migration_route (json), next_waypoint, arrival_at, cycle_phase' }, { name: 'anomalies', purpose: 'Temporary spatial phenomena', fields: 'anomaly_id, type (wormhole/nebula/storm/void), system_id, x/y/z, severity, expires_at, loot_table' }, ].map((row, i) => ( ))}
TablePurposeKey Fields
{row.name} {row.purpose} {row.fields}

Event Spawn Logic

World Tick Reducer — Pseudocode
// Runs every 5 minutes on the server
reducer world_tick(ctx) {'{'}
  // 1. Evaluate faction tension matrix
  for each faction_pair {'{'}
    if standing {'<'} -5 && random {'<'} tension_weight {'{'}
      spawn_event("faction_skirmish", contested_system);
      log_story({'"'}Hostilities erupt between {'{'}A{'}'} and {'{'}B{'}'} in {'{'}system{'}'}{'"'});
    {'}'}
  {'}'}

  // 2. Check anomaly spawn slots
  if active_anomalies {'<'} max_anomalies {'{'}
    pick random system weighted by distance_from_hub;
    spawn_anomaly(system, random_type);
  {'}'}

  // 3. Advance fauna migration routes
  for each fauna {'{'}
    if now {'>='} next_waypoint.arrival_at {'{'}
      advance fauna to next system in route;
      log_story({'"'}{'{'}species{'}'} migration enters {'{'}system{'}'}{'"'});
    {'}'}
  {'}'}

  // 4. Cascade: check if any active events should trigger follow-ons
  for each active_event near expiry {'{'}
    evaluate_outcome(participants, event_state);
    resolve_event(event_id, outcome);
    // outcome may shift faction relations → future events
  {'}'}
{'}'}
)} {galaxySubSection === 'galaxy-gen' && (<>
GALAXY-GEN

Galaxy Generation — Seeded Parameters & Algorithm

Every galaxy begins with a seed. The galaxy generation algorithm is deterministic: the same seed always produces the same galaxy. This means server operators can share a seed for a known-good galaxy layout, or generate a unique one. Generation runs once at server bootstrap and writes immutable topology tables (regions, constellations, systems, stargates, planets, moons, stations, asteroid belts). Faction territories and NPC agent placement are also seeded at this stage.

Galaxy Parameters

{[ { param: 'Regions', mvp: '4', full: '6–8', reason: 'Core, Frontier, Null, Deep Null for MVP. Add 2–4 faction-specific regions at launch.' }, { param: 'Constellations per region', mvp: '3–4', full: '4–8', reason: 'Minimum 3 for gate connectivity. More in Core region, fewer in Deep Null.' }, { param: 'Systems per constellation', mvp: '2–5', full: '3–8', reason: 'Density varies by region type. Core constellations are denser (trade hubs).' }, { param: 'Total systems (MVP)', mvp: '~50', full: '~300–500', reason: '4 regions × 3.5 const × 3.5 sys ≈ 49 systems. Enough for economic loops without barren stretches.' }, { param: 'Stargates per system', mvp: '1–4', full: '1–6', reason: 'Minimum 1 (no dead ends). Hub systems get 4+. Frontier gets 2–3.' }, { param: 'Stations per system', mvp: '1–3', full: '1–6', reason: 'High-sec: 2–3 stations. Low-sec: 1–2. Null: 0–1 NPC stations. Stations are where the economy lives.' }, { param: 'Planets per system', mvp: '1–5', full: '2–8', reason: 'Aesthetic + resource variety. Orbital mechanics run on a slow tick (no gameplay impact in MVP).' }, { param: 'Asteroid belts per system', mvp: '1–3', full: '1–5', reason: 'Belts are where mining happens. More belts in lower-sec = better ore = risk/reward.' }, { param: 'Factions', mvp: '4', full: '4–6', reason: 'One per region in MVP. Each has territory, ideology, and agent networks.' }, { param: 'NPC agents per station', mvp: '1–2', full: '1–4', reason: 'Mission-givers. Specialty and quality randomized from seed.' }, ].map((row, i) => ( ))}
ParameterMVP ValueFull LaunchRationale
{row.param} {row.mvp} {row.full} {row.reason}

Galaxy Shape & Layout

Spiral galaxy with 4 arms. The galaxy is rendered as a top-down 2D map (with a Z-depth dimension for 3D system coordinates within each system). Regions are assigned to spiral arm segments: Core (center), Frontier (inner arms), Null (outer arms), Deep Null (tips and gaps between arms). Systems within a region are placed using a Poisson disk distribution to ensure minimum spacing while maintaining natural clustering.

Region Assignment Rules

  • Core (sec +0.8 → +1.0): Center of galaxy map. Dense, high station count, trade hub. Starter systems live here. 1 region.
  • Frontier (sec +0.1 → +0.7): Inner spiral arms. Moderate density. Faction border zones. Mission territory. 1–2 regions.
  • Null (sec 0.0 → −0.4): Outer spiral arms. Sparse stations. Rich belts. PvP-free. 1 region.
  • Deep Null (sec −0.5 → −1.0): Tips and gaps. Very sparse. Wormhole connections only. Elite content. 1 region.

System Placement Algorithm

1. Place constellation centroids via Poisson disk (min 40px apart on map)
2. For each centroid, place 2–5 systems in a cluster (Gaussian offset from centroid, σ = 15px)
3. Assign security level band based on region assignment
4. Add jitter to security within band (±0.1 random) for natural variation
5. Place star type (O/B/A/F/G/K/M) weighted by frequency — G/K most common
6. System name generated from faction language + sequential number

Stargate Topology

No disconnected components. Every system must be reachable from every other system. The stargate graph is the transportation backbone. If a system has only one gate, it\'s a dead-end — risky because you can\'t flee without going back through the same gate. The algorithm ensures minimum 2 gates per system (MVP) and creates "choke point" systems with 4+ gates that become natural trade hubs and conflict zones.

Stargate Connectivity Algorithm

Phase 1 — Minimum Spanning Tree: Compute MST over all systems using Euclidean distance. This guarantees full connectivity with minimum total gate length.
Phase 2 — Intra-constellation edges: For each constellation, add 1–2 extra gates between systems within the constellation. This creates local redundancy and multiple routes within a cluster.
Phase 3 — Inter-region choke points: Identify 2–4 systems on region boundaries. Add gates between them to create known choke points. These become strategic PvP locations.
Phase 4 — Shortcut edges: Add 10–15% extra gates weighted toward connecting high-sec systems to create trade route variety. Never add shortcuts into/out of Deep Null (wormhole-only access preserved).
Validation: After generation, verify: (a) graph is fully connected (BFS from any node reaches all), (b) no system has <2 gates, (c) Deep Null systems have no direct high-sec gates, (d) average path length <15 jumps for MVP galaxy.

Starter System Template

Starter System Layout

Security: +1.0 (maximum safety)
Stations: 3 — Home Station, Trade Hub, Factory
Belts: 3 — Veldspar/Scordite (easy ore)
NPC agents: 2 — Tutorial agent + Level 1 kill agent
Gates: 3 — connects to 3 adjacent high-sec systems
NPC pirates: None (CONCORD-protected + no belt spawns in 1.0)
Services: Refinery, Factory, Market, Fitting, Insurance, Medical

New Player Spawn Rules

  • New players always spawn in a starter system (sec 1.0)
  • Each faction has exactly 1 starter system in their Core region
  • Player receives a Rookie Frigate (free, uninsurable, untradeable)
  • Player receives the tutorial mission sequence from the tutorial agent
  • Starter system is guaranteed to have Veldspar and Scordite at NPC buy prices that make the first-30-minute walkthrough viable
  • Multiple new players can share the same starter system (no instancing)

Station & Belt Placement Rules

{[ { entity: 'Station', rule: 'Orbiting a planet or moon. Placed at galaxy gen, never moved.', density: 'High-sec: 2–3/station. Low: 1–2. Null: 0–1 NPC. Player stations (post-MVP) can be anchored.', notes: 'Stations define where economy happens. Every station has a Market. Refinery and Factory depend on station size.' }, { entity: 'Asteroid Belt', rule: 'Circular orbit around star. 3–5 asteroids per belt.', density: 'High-sec: 1–2. Low: 2–3. Null: 2–4. Deep Null: 3–5.', notes: 'Belt ore quality scales with sec level. High-sec: Veldspar/Scordite only. Null: adds Arkonor/Megacyte.' }, { entity: 'Moon', rule: 'Orbiting planets. 0–3 moons per planet.', density: '1–3 moons per planet (uniform distribution).', notes: 'Moons have moon minerals (post-MVP). MVP: moons exist for visual flavor and as station anchors.' }, { entity: 'Stargate', rule: 'At system edge, paired with gate in target system. Placed at fixed (x,y) = system edge toward destination.', density: 'Matches graph topology. 2–4 per system typically.', notes: 'Gates are always paired. Jumping gate A→B always works. No fuel cost for jumping (MVP).' }, { entity: 'NPC Agent', rule: 'Located at a station. 1–2 per station in MVP.', density: 'High-sec stations: 2. Low-sec: 1. Null: 1 or 0.', notes: 'Agent specialty drawn from faction pool. Quality randomized from seed.' }, ].map((row, i) => ( ))}
EntityPlacement RuleDensity by SecNotes
{row.entity} {row.rule} {row.density} {row.notes}

Faction Territory Seeding

Faction Assignment at Galaxy Gen

1. Assign regions: Each faction claims 1 region as home territory. The Core region is shared (contested).
2. Place capitals: Each faction gets a capital station in their home region — largest station, most agents, best services.
3. Seed diplomatic stance: Initial faction relations set to baseline matrix (allies: +5, neutral: 0, rivals: −3). This drifts via world simulation.
4. Distribute agents: NPC agents placed at stations within faction territory. Specialty weighted by faction ideology (militarist → kill agents, trader → trade/escort agents).
5. Set regional price seeds: regional_price_seeds table populated at gen time. Each region gets commodity modifiers (0.6–1.5) that create baseline price differences for traders to discover.
6. Faction military/economy: Initial military_strength and economy_strength set from faction template. These are the starting values the world simulation modifies.

Generation Pseudocode

Galaxy Generation — Pseudocode
fn generate_galaxy(seed: u64) {'{'}
  let rng = SeededRng::new(seed);

  // 1. Create regions
  let regions = ['{'Core, Frontier_A, Null, Deep_Null'}'];
  for region in regions {'{'}
    insert region row (id, name, faction_id, security_profile);
  {'}'}

  // 2. Place constellation centroids (Poisson disk)
  let centroids = poisson_disk(min_dist=40, rng);
  for centroid in centroids {'{'}
    let region = assign_region(centroid.position);
    insert constellation row (region_id, centroid.x, centroid.y);
  {'}'}

  // 3. Place systems within constellations (Gaussian cluster)
  for constellation in constellations {'{'}
    let count = rng.range(2..5); // MVP: 2–5 systems per constellation
    for i in 0..count {'{'}
      let offset = gaussian(σ=15, rng);
      let sec = assign_security(constellation.region) + rng.range(-0.1..+0.1);
      insert system row (name, constellation_id, sec, star_type, x, y);
      place_planets(system, rng);
      place_stations(system, sec, rng);
      place_belts(system, sec, rng);
    {'}'}
  {'}'}

  // 4. Stargate topology
  let mst = minimum_spanning_tree(all_systems, euclidean_distance);
  for edge in mst {'{'} insert_gate(edge.a, edge.b); {'}'}
  add_intra_constellation_edges(rng); // +1–2 per constellation
  add_region_chokepoints(rng); // 2–4 cross-region gates
  add_shortcut_edges(percentage=0.12, rng); // 12% extra high-sec shortcuts
  validate_connectivity(); // BFS from node 0 reaches all?

  // 5. Faction seeding
  seed_faction_territories(factions, regions);
  seed_capital_stations(factions);
  seed_diplomatic_matrix(factions);
  seed_npc_agents(stations, factions, rng);
  seed_regional_prices(regions, commodities, rng);
{'}'}
Determinism guarantee: Given the same seed, generate_galaxy always produces identical topology. This enables: (1) shared "known-good" galaxy seeds for competitive servers, (2) reproducible bug reports with exact galaxy layout, (3) automated testing against fixed galaxy configurations. The seed is stored in a single galaxy_meta table row: {'{'} seed: u64, generated_at: timestamp, system_count: u32, total_gates: u32 {'}'}.
MVP scope note: For Phase 0, the galaxy can be hand-authored (a 5–10 system "mini galaxy") as long as it follows these rules. The procedural generator ships when the galaxy needs to scale beyond ~50 systems (Phase 7+). Hand-authored galaxies must still pass the same connectivity validation.
)} {galaxySubSection === 'galaxy-events' && (<>

World Simulation Tables

Overlap note: faction_relations, world_events, and galaxy_story_log also appear in the Tables tab with abbreviated field descriptions. The definitions below are the expanded versions with full field detail.
{[ { name: 'faction_relations', purpose: 'Dynamic relationship matrix', fields: 'faction_a_id, faction_b_id, standing (-10 to +10), trend, last_event_id' }, { name: 'world_events', purpose: 'Active PvE events in the galaxy', fields: 'event_id, event_type, system_id, severity (1–5), started_at, expires_at, state, participants_json' }, { name: 'world_event_templates', purpose: 'Event blueprints with spawn conditions', fields: 'template_id, type, name, spawn_weight, required_faction_state, cooldown_hours' }, { name: 'galaxy_story_log', purpose: 'Persistent server timeline', fields: 'log_id, event_id, chapter_index, headline, body, affected_systems, timestamp' }, { name: 'space_fauna', purpose: 'Migrating space creatures', fields: 'fauna_id, species, current_system_id, migration_route (json), cycle_phase' }, { name: 'anomalies', purpose: 'Temporary spatial phenomena', fields: 'anomaly_id, type, system_id, x/y/z, severity, expires_at, loot_table' }, ].map((row, i) => ( ))}
TablePurposeKey Fields
{row.name} {row.purpose} {row.fields}
)} )} {activeSection === 'er' && ( <>
BACKEND-ER

Entity-Relationship Diagram

50+ tables organized into 5 clusters. This diagram shows the core entity relationships and how data flows between clusters. Each cluster is color-coded. Foreign key relationships shown as arrows. Subscription patterns indicate which tables clients subscribe to for reactive updates.
{[ { name: 'Player & Identity', color: 'var(--cyan)', desc: 'Core player data, ships, inventory, skills, and session state.', tables: [ { name: 'players', pk: 'player_id', fk: '', note: 'Root entity. One row per identity.' }, { name: 'ships', pk: 'ship_id', fk: '\u2192 players.player_id', note: 'Multiple ships per player. owner_player_id.' }, { name: 'ship_fittings', pk: 'fitting_id', fk: '\u2192 ships.ship_id, \u2192 modules_catalog.module_id', note: 'Many-to-many: ships \u2194 modules.' }, { name: 'inventory_items', pk: 'item_id', fk: '\u2192 players.player_id', note: 'Location field: ship cargo or station hangar.' }, { name: 'player_skills', pk: 'player_id + skill_name', fk: '\u2192 players.player_id', note: 'XP and level per skill per player.' }, { name: 'player_standing', pk: 'player_id + entity_id', fk: '\u2192 players.player_id', note: 'Standing with agents and factions.' }, { name: 'player_loyalty_points', pk: 'player_id + faction_id', fk: '\u2192 players.player_id', note: 'LP balance per faction.' }, ], }, { name: 'Economy & Industry', color: 'var(--green)', desc: 'Market, manufacturing, blueprints, and NPC pricing.', tables: [ { name: 'market_orders', pk: 'order_id', fk: '\u2192 stations.station_id, \u2192 players.player_id', note: 'Buy/sell orders. Core market table.' }, { name: 'blueprints', pk: 'bp_id', fk: '', note: 'Manufacturing recipes. Materials JSON.' }, { name: 'manufacturing_jobs', pk: 'job_id', fk: '\u2192 players.player_id, \u2192 stations.station_id, \u2192 blueprints.bp_id', note: 'Active production queues.' }, { name: 'station_commodity_demand', pk: 'station_id + commodity_id', fk: '\u2192 stations.station_id', note: 'Per-station demand state for NPC pricing.' }, { name: 'commodity_price_params', pk: 'commodity_id', fk: '', note: 'Base prices and EMA parameters.' }, { name: 'regional_price_seeds', pk: 'region_id + commodity_id', fk: '', note: 'Static modifiers from galaxy gen.' }, { name: 'insurance_policies', pk: 'policy_id', fk: '\u2192 players.player_id, \u2192 ships.ship_id', note: 'Active insurance contracts.' }, ], }, { name: 'World & Galaxy', color: 'var(--accent)', desc: 'Galaxy topology, world events, factions, anomalies, and fauna.', tables: [ { name: 'systems', pk: 'system_id', fk: '\u2192 regions.region_id', note: 'Star systems. Security level immutable.' }, { name: 'stations', pk: 'station_id', fk: '\u2192 systems.system_id', note: 'Docking locations with services.' }, { name: 'asteroids', pk: 'asteroid_id', fk: '\u2192 systems.system_id', note: 'Mineable resource nodes.' }, { name: 'factions', pk: 'faction_id', fk: '', note: 'NPC factions with territory.' }, { name: 'faction_relations', pk: 'faction_a_id + faction_b_id', fk: '\u2192 factions.faction_id (\u00d72)', note: 'Dynamic relationship matrix.' }, { name: 'world_events', pk: 'event_id', fk: '\u2192 systems.system_id', note: 'Active PvE events. Severity, state, params.' }, { name: 'galaxy_story_log', pk: 'log_id', fk: '\u2192 world_events.event_id', note: 'Persistent server timeline.' }, { name: 'anomalies', pk: 'anomaly_id', fk: '\u2192 systems.system_id', note: 'Temporary spatial phenomena.' }, { name: 'space_fauna', pk: 'fauna_id', fk: '\u2192 systems.system_id', note: 'Migrating creatures. Route JSON.' }, ], }, { name: 'Social & PvP', color: 'var(--red)', desc: 'Chat, bounty, kill feed, waypoints, and missions.', tables: [ { name: 'chat_channels', pk: 'channel_id', fk: '', note: 'Channel definitions: local, trade, private.' }, { name: 'chat_messages', pk: 'message_id', fk: '\u2192 chat_channels.channel_id, \u2192 players.player_id', note: 'Message stream with delay.' }, { name: 'bounties', pk: 'target_player_id', fk: '\u2192 players.player_id', note: 'Bounty pool per target.' }, { name: 'bounty_contributions', pk: 'contribution_id', fk: '\u2192 bounties.target_player_id, \u2192 players.player_id', note: 'Individual payments into pools.' }, { name: 'kill_feed', pk: 'kill_id', fk: '\u2192 players.player_id (victim + killer)', note: 'Ship destruction events.' }, { name: 'npc_agents', pk: 'agent_id', fk: '\u2192 factions.faction_id, \u2192 stations.station_id', note: 'NPC agents at stations.' }, { name: 'active_missions', pk: 'mission_id', fk: '\u2192 players.player_id, \u2192 npc_agents.agent_id', note: 'Player mission state.' }, { name: 'waypoints', pk: 'route_id', fk: '\u2192 players.player_id', note: 'Multi-stop routes.' }, ], }, { name: 'Ship AI (Zora)', color: 'var(--purple)', desc: 'Soul state, modules, tools, memory, directives, and runtime.', tables: [ { name: 'ship_ai_soul', pk: 'ship_id', fk: '\u2192 ships.ship_id', note: 'One-to-one with ships. Soul document + personality.' }, { name: 'ship_ai_modules', pk: 'module_id', fk: '\u2192 ships.ship_id', note: 'Installed AI modules. Medium/low slots.' }, { name: 'ship_ai_tools', pk: 'tool_id', fk: '\u2192 ship_ai_modules.module_id', note: 'Derived from modules. Tool registry.' }, { name: 'ship_ai_memory', pk: 'memory_id', fk: '\u2192 ships.ship_id', note: 'Event log. Category + importance scoring.' }, { name: 'ship_ai_directives', pk: 'directive_id', fk: '\u2192 ships.ship_id', note: 'Player-set goals for autonomous mode.' }, { name: 'ship_ai_agent_runtime', pk: 'ship_id', fk: '\u2192 ships.ship_id', note: 'Per-ship agent loop state. One-to-one.' }, ], }, ].map((cluster, ci) => (

{cluster.name} {cluster.desc}

{cluster.tables.map((t, ti) => ( ))}
TablePKFK RelationshipsNotes
{t.name} {t.pk} {t.fk || '\u2014'} {t.note}
))}
Cross-cluster flows: The most important cross-cluster relationships are: (1) players \u2192 market_orders \u2192 stations (the economic loop), (2) ships \u2192 systems \u2192 chat_messages (the spatial-social loop), (3) ship_ai_soul \u2192 market_orders (Zora reads market data for intelligence). Every reducer call touches at least two clusters.
)}
); } window.GDD.BackendPage = BackendPage;