Files
Space-Game/archive/legacy-static/js/fake-backend.js
francy51 316a44661b Restructure into pnpm monorepo with game shell, docs, and SpacetimeDB backend
- Restructure flat static prototype into pnpm workspace monorepo
- apps/game: playable shell with R3F 3D scene, HUD, SpacetimeDB connection
- apps/docs: design docs and prototypes
- apps/site: landing page
- packages/ui: shared Button and Panel primitives
- services/spacetimedb: backend module (9 tables, 11 reducers)
- Archive legacy static files to archive/legacy-static/
- Game loop: connect, undock, target, approach, dock, mine, sell
- Add pnpm-workspace.yaml, tsconfig.base.json, spacetime.json
2026-05-31 17:56:56 -04:00

279 lines
18 KiB
JavaScript

window.GDD = window.GDD || {};
/* ---- Fake Data ---- */
const SYSTEMS = [
{ id: 'sol', name: 'Sol', security: 1.0, x: 400, y: 300, type: 'G2V Star', planets: 8, stations: ['Jita IV - Moon 4', 'Amarr VIII'], color: '#fbbf24' },
{ id: 'amarr', name: 'Amarr', security: 0.9, x: 550, y: 220, type: 'K4V Star', planets: 6, stations: ['Amarr Prime'], color: '#f59e0b' },
{ id: 'heinoo', name: 'Hek', security: 0.7, x: 320, y: 180, type: 'M3V Star', planets: 4, stations: ['Hek VII'], color: '#22c55e' },
{ id: 'rens', name: 'Rens', security: 0.6, x: 250, y: 350, type: 'G9V Star', planets: 7, stations: ['Rens VI'], color: '#22d3ee' },
{ id: 'dodixie', name: 'Dodixie', security: 0.8, x: 480, y: 400, type: 'F7V Star', planets: 5, stations: ['Dodixie IX'], color: '#a78bfa' },
{ id: 'u-irtyr', name: 'U-IRTYR', security: 0.3, x: 150, y: 250, type: 'M7V Star', planets: 3, stations: [], color: '#ef4444' },
{ id: 'pf-346', name: 'PF-346', security: 0.2, x: 600, y: 350, type: 'K7V Star', planets: 2, stations: ['PF-346 II'], color: '#ef4444' },
{ id: 'huzzah', name: 'YZ-LQL', security: 0.1, x: 100, y: 400, type: 'M2V Star', planets: 1, stations: [], color: '#dc2626' },
{ id: 'pirates', name: 'O-WAMW', security: 0.0, x: 650, y: 150, type: 'M5V Red Giant', planets: 9, stations: [], color: '#991b1b' },
];
const CONNECTIONS = [
['sol', 'amarr'], ['sol', 'heinoo'], ['sol', 'rens'],
['amarr', 'dodixie'], ['amarr', 'pf-346'], ['amarr', 'pirates'],
['heinoo', 'u-irtyr'], ['heinoo', 'rens'],
['rens', 'u-irtyr'], ['rens', 'huzzah'],
['dodixie', 'pf-346'], ['dodixie', 'sol'],
['u-irtyr', 'huzzah'], ['pf-346', 'pirates'],
];
const ASTEROID_TYPES = ['Veldspar', 'Scordite', 'Pyroxeres', 'Kernite', 'Omber', 'Jaspet', 'Hemorphite', 'Arkonor'];
const ORE_PRICES = { Veldspar: 12, Scordite: 28, Pyroxeres: 45, Kernite: 85, Omber: 120, Jaspet: 190, Hemorphite: 340, Arkonor: 620 };
const MODULES = [
{ id: 'laser1', name: 'Mining Laser I', type: 'mining', slot: 'high', power: 40, cpu: 30, cycle: 10, active: false },
{ id: 'laser2', name: 'Mining Laser II', type: 'mining', slot: 'high', power: 50, cpu: 40, cycle: 8, active: false },
{ id: 'shield1', name: 'Shield Booster I', type: 'shield', slot: 'med', power: 30, cpu: 30, cycle: 5, active: false },
{ id: 'turret1', name: '150mm Railgun', type: 'weapon', slot: 'high', power: 50, cpu: 35, damage: 25, cycle: 3, active: false },
{ id: 'turret2', name: '200mm Autocannon', type: 'weapon', slot: 'high', power: 45, cpu: 30, damage: 35, cycle: 2.5, active: false },
{ id: 'warp1', name: '1MN Afterburner', type: 'propulsion', slot: 'med', power: 20, cpu: 25, speed: 1.5, cycle: 0, active: false },
{ id: 'scram1', name: 'Warp Scrambler I', type: 'ewar', slot: 'med', power: 25, cpu: 25, range: 20, cycle: 0, active: false },
{ id: 'armor1', name: 'Armor Plate I', type: 'armor', slot: 'low', power: 20, cpu: 10, cycle: 0, active: false },
{ id: 'magstab1', name: 'Magnetic Field Stabilizer', type: 'damage_mod', slot: 'low', power: 5, cpu: 15, cycle: 0, active: false },
{ id: 'cargo1', name: 'Cargo Expander I', type: 'cargo', slot: 'low', power: 0, cpu: 15, cycle: 0, active: false },
];
const MARKET_ORDERS = [
{ id: 1, station: 'Jita IV - Moon 4', type: 'sell', item: 'Veldspar', price: 14, quantity: 45000, seller: 'MinerKing42' },
{ id: 2, station: 'Jita IV - Moon 4', type: 'sell', item: 'Scordite', price: 32, quantity: 12000, seller: 'RockHound' },
{ id: 3, station: 'Jita IV - Moon 4', type: 'buy', item: 'Arkonor', price: 580, quantity: 500, seller: 'IndustrialMega' },
{ id: 4, station: 'Jita IV - Moon 4', type: 'sell', item: 'Kernite', price: 90, quantity: 8000, seller: 'DeepMiner' },
{ id: 5, station: 'Jita IV - Moon 4', type: 'buy', item: 'Pyroxeres', price: 42, quantity: 20000, seller: 'RefineryCorp' },
{ id: 6, station: 'Amarr Prime', type: 'sell', item: 'Omber', price: 135, quantity: 6000, seller: 'AmarrTrader' },
{ id: 7, station: 'Amarr Prime', type: 'buy', item: 'Jaspet', price: 180, quantity: 3000, seller: 'HighSecOps' },
{ id: 8, station: 'Rens VI', type: 'sell', item: 'Hemorphite', price: 360, quantity: 1200, seller: 'NullRunner' },
{ id: 9, station: 'Rens VI', type: 'sell', item: 'Veldspar', price: 11, quantity: 90000, seller: 'BulkMiner' },
{ id: 10, station: 'Dodixie IX', type: 'buy', item: 'Scordite', price: 30, quantity: 15000, seller: 'GallenteForge' },
];
const PLAYER_INVENTORY = [
{ item: 'Veldspar', quantity: 8500, unitPrice: 12 },
{ item: 'Scordite', quantity: 2300, unitPrice: 28 },
{ item: 'Kernite', quantity: 400, unitPrice: 85 },
{ item: 'Pyroxeres', quantity: 1200, unitPrice: 45 },
];
const PLAYER_SHIPS = [
{ id: 'ship1', name: 'Merlin', class: 'Frigate', system: 'Sol', status: 'active', highSlots: 3, medSlots: 3, lowSlots: 2, cpu: 120, powerGrid: 40, fitted: ['laser1', 'turret1', 'warp1'] },
{ id: 'ship2', name: 'Thrasher', class: 'Destroyer', system: 'Amarr', status: 'docked', highSlots: 7, medSlots: 3, lowSlots: 3, cpu: 180, powerGrid: 65, fitted: ['turret1', 'turret2', 'scram1'] },
];
const PLAYER_BOUNTIES = [
{ target: 'PirateKing99', pool: 125000, tier: 'Dangerous', lastHostile: '2h ago' },
{ target: 'NullSecWarlord', pool: 520000, tier: 'Most Wanted', lastHostile: '30m ago' },
];
const PLAYER_SKILLS = [
{ name: 'Gunnery', level: 2, xp: 380, nextLevel: 500, category: 'Combat' },
{ name: 'Mining', level: 3, xp: 1850, nextLevel: 2000, category: 'Industry' },
{ name: 'Refining', level: 2, xp: 420, nextLevel: 500, category: 'Industry' },
{ name: 'Navigation', level: 1, xp: 80, nextLevel: 100, category: 'Navigation' },
{ name: 'Broker Relations', level: 1, xp: 45, nextLevel: 100, category: 'Trade' },
];
const KILL_FEED = [
{ victim: 'MinerBob', killer: 'PirateKing99', ship: 'Rifter', system: 'U-IRTYR', bounty: 5000, time: '5m ago' },
{ victim: 'TraderAlice', killer: 'CMDR Worf', ship: 'Hauler', system: 'Hek', bounty: 0, time: '12m ago' },
{ victim: 'PirateScout', killer: 'CMDR Picard', ship: 'Merlin', system: 'Sol', bounty: 2000, time: '25m ago' },
];
/* ---- Simulated API ---- */
const delay = (ms) => new Promise(r => setTimeout(r, ms + Math.random() * 50));
window.GDD.api = {
getSystems: async () => { await delay(80); return SYSTEMS.map(s => ({ ...s })); },
getConnections: async () => { await delay(60); return CONNECTIONS.map(c => [...c]); },
getSystemDetail: async (id) => { await delay(100); return SYSTEMS.find(s => s.id === id) || null; },
setDestination: async (systemId) => { await delay(150); return { success: true, destination: systemId, eta: '3m 42s' }; },
getShipStatus: async () => {
await delay(100);
return {
name: 'Merlin', class: 'Frigate', system: 'Sol',
x: 400, y: 300, status: 'idle', speed: 0, maxSpeed: 250,
shields: 100, armor: 100, hull: 100, capacitor: 85,
cargo: { used: 12400, total: 25000 },
target: null,
};
},
getModules: async () => { await delay(80); return MODULES.map(m => ({ ...m, active: false })); },
toggleModule: async (moduleId) => { await delay(100); return { success: true, moduleId, active: true }; },
getNearbyEntities: async () => {
await delay(120);
return [
{ id: 'npc1', name: 'Guristas Pirate', type: 'hostile', x: 430, y: 280, shields: 100, distance: 45 },
{ id: 'asteroid1', name: 'Veldspar Asteroid', type: 'asteroid', x: 370, y: 320, resource: 'Veldspar', quantity: 8500, distance: 12 },
{ id: 'station1', name: 'Jita IV - Moon 4', type: 'station', x: 410, y: 310, distance: 8 },
{ id: 'player2', name: 'CMDR LaForge', type: 'player', x: 390, y: 260, distance: 55 },
];
},
getMarketOrders: async (stationId) => { await delay(150); return MARKET_ORDERS.filter(o => !stationId || o.station === stationId); },
getPlayerInventory: async () => { await delay(80); return PLAYER_INVENTORY.map(i => ({ ...i })); },
placeOrder: async (type, item, price, quantity) => { await delay(200); return { success: true, orderId: Date.now() }; },
sellItem: async (item, quantity, stationId) => { await delay(250); return { success: true, isk: quantity * (ORE_PRICES[item] || 10) }; },
getChatMessages: async () => {
await delay(60);
return [
{ id: 1, sender: 'CMDR Picard', body: 'Heading to Jita with a cargo of Kernite.', time: '14:22' },
{ id: 2, sender: 'CMDR Worf', body: 'Pirates spotted near U-IRTYR gate. Stay alert.', time: '14:25' },
{ id: 3, sender: 'CMDR Data', body: 'Scordite prices up 12% in Amarr this hour.', time: '14:28' },
{ id: 4, sender: 'CMDR Troi', body: 'Anyone want to form a mining fleet in Sol?', time: '14:31' },
];
},
sendMessage: async (body) => { await delay(50); return { success: true, id: Date.now() }; },
getOrePrices: async () => { await delay(80); return { ...ORE_PRICES }; },
getShipFittings: async (shipId) => { await delay(100); const ship = PLAYER_SHIPS.find(s => s.id === shipId); return ship ? ship.fitted.map(id => MODULES.find(m => m.id === id)).filter(Boolean) : []; },
getPlayerShips: async () => { await delay(100); return PLAYER_SHIPS.map(s => ({ ...s })); },
getAvailableModules: async () => { await delay(80); return MODULES.map(m => ({ ...m })); },
fitModule: async (shipId, moduleId) => { await delay(150); return { success: true, shipId, moduleId }; },
unfitModule: async (shipId, slotIndex) => { await delay(100); return { success: true, shipId, slotIndex }; },
refineOre: async (oreType, quantity) => {
await delay(200);
const prices = ORE_PRICES[oreType] || 10;
return { success: true, ore: oreType, quantity, iskEarned: Math.floor(quantity * prices * 0.7), efficiency: 0.7 };
},
manufactureItem: async (blueprintId, stationId) => { await delay(300); return { success: true, jobId: Date.now(), eta: '5m 00s' }; },
getBounties: async () => { await delay(100); return PLAYER_BOUNTIES.map(b => ({ ...b })); },
placeBounty: async (targetPlayer, amount) => { await delay(150); return { success: true, target: targetPlayer, amount }; },
getKillFeed: async () => { await delay(80); return KILL_FEED.map(k => ({ ...k })); },
getPlayerSkills: async () => { await delay(100); return PLAYER_SKILLS.map(s => ({ ...s })); },
sendPrivateMessage: async (recipient, body) => {
const dist = Math.floor(Math.random() * 20);
const lightDelay = Math.floor(Math.sqrt(dist) * 2);
await delay(50);
return { success: true, id: Date.now(), recipient, lightDelay };
},
getBookmarks: async () => {
await delay(80);
return [
{ id: 1, name: 'Safe spot Alpha', system: 'Sol', x: 380, y: 290, type: 'safe' },
{ id: 2, name: 'Good Veldspar belt', system: 'Amarr', x: 560, y: 210, type: 'mining' },
{ id: 3, name: 'Ambush point', system: 'U-IRTYR', x: 160, y: 260, type: 'tactical' },
];
},
};
const CELESTIAL_BODIES = {
'sol': {
description: 'The cradle of humanity. A stable G2V main-sequence star hosting the busiest trade hub in known space.',
faction: 'CONCORD',
population: '12.4 billion',
resources: ['Veldspar', 'Scordite', 'Pyroxeres', 'Kernite'],
bodies: [
{ name: 'Mercury', type: 'rocky', orbit: 6, period: 4, size: 0.3, color: '#a0a0a0', ecc: 0.2, inc: 0.12, moons: [] },
{ name: 'Venus', type: 'rocky', orbit: 9, period: 6.5, size: 0.5, color: '#e8c56d', ecc: 0.01, inc: 0.06, moons: [], atmosphere: '#e8c56d' },
{ name: 'Earth', type: 'terrestrial', orbit: 13, period: 10, size: 0.55, color: '#4a90d9', ecc: 0.017, inc: 0, atmosphere: '#6ac0ff', moons: [{ name: 'Luna', orbit: 2, period: 2, size: 0.15, color: '#c0c0c0' }] },
{ name: 'Mars', type: 'rocky', orbit: 17, period: 14, size: 0.4, color: '#c1440e', ecc: 0.09, inc: 0.03, moons: [{ name: 'Phobos', orbit: 1.2, period: 0.8, size: 0.08, color: '#8a7a6a' }, { name: 'Deimos', orbit: 1.8, period: 1.5, size: 0.06, color: '#7a6a5a' }] },
{ name: 'Asteroid Belt', type: 'belt', innerOrbit: 22, outerOrbit: 26, count: 80 },
{ name: 'Jupiter', type: 'gas', orbit: 32, period: 35, size: 1.2, color: '#c88b3a', ecc: 0.048, inc: 0.02 },
{ name: 'Saturn', type: 'gas', orbit: 42, period: 50, size: 1.0, color: '#d4a560', ecc: 0.054, inc: 0.04, hasRings: true },
],
},
'amarr': {
description: 'Seat of the Amarr Empire. A warm K4V star surrounded by heavily industrialized worlds.',
faction: 'Amarr Empire',
population: '9.1 billion',
resources: ['Kernite', 'Omber', 'Pyroxeres'],
bodies: [
{ name: 'Amarr I', type: 'rocky', orbit: 5, period: 3, size: 0.35, color: '#d4a040', ecc: 0.02, inc: 0.01, moons: [] },
{ name: 'Amarr II', type: 'terrestrial', orbit: 10, period: 8, size: 0.65, color: '#c06030', ecc: 0.01, inc: 0.05, atmosphere: '#c08050', moons: [] },
{ name: 'Amarr III', type: 'gas', orbit: 18, period: 22, size: 0.9, color: '#8b6914', ecc: 0.03, inc: 0.02, moons: [{ name: 'Amarr III-a', orbit: 2, period: 1.5, size: 0.12, color: '#a08040' }] },
{ name: 'Asteroid Belt', type: 'belt', innerOrbit: 24, outerOrbit: 27, count: 60 },
],
},
'heinoo': {
description: 'A frontier system popular with independent miners. Rich in common ores and frequently trafficked by haulers.',
faction: 'Minmatar Republic',
population: '340 million',
resources: ['Veldspar', 'Scordite', 'Plagioclase'],
bodies: [
{ name: 'Hek I', type: 'rocky', orbit: 5, period: 3.5, size: 0.3, color: '#7a8a6a', ecc: 0.05, inc: 0.02, moons: [] },
{ name: 'Hek II', type: 'terrestrial', orbit: 11, period: 9, size: 0.55, color: '#4a8a5a', ecc: 0.03, inc: 0.01, atmosphere: '#6aaa7a', moons: [{ name: 'Hek II-a', orbit: 2, period: 1.8, size: 0.1, color: '#8a8a7a' }] },
{ name: 'Hek III', type: 'gas', orbit: 20, period: 25, size: 0.8, color: '#5a7a9a', ecc: 0.02, inc: 0.03 },
],
},
'rens': {
description: 'Major trade hub in the Minmatar Republic. Bustling commerce and a strong naval presence keep pirates at bay.',
faction: 'Minmatar Republic',
population: '2.1 billion',
resources: ['Scordite', 'Pyroxeres', 'Kernite'],
bodies: [
{ name: 'Rens I', type: 'rocky', orbit: 6, period: 4, size: 0.35, color: '#9a7a5a', ecc: 0.03, inc: 0.01, moons: [] },
{ name: 'Rens II', type: 'terrestrial', orbit: 12, period: 10, size: 0.6, color: '#5a7aaa', ecc: 0.02, inc: 0.04, atmosphere: '#7a9acc', moons: [{ name: 'Rens II-a', orbit: 1.8, period: 1.4, size: 0.12, color: '#aaaaaa' }] },
{ name: 'Asteroid Belt', type: 'belt', innerOrbit: 18, outerOrbit: 22, count: 70 },
{ name: 'Rens III', type: 'gas', orbit: 28, period: 35, size: 1.1, color: '#aa7a3a', ecc: 0.04, inc: 0.02 },
],
},
'dodixie': {
description: 'Federation commerce hub. High-tech industry and cutting-edge research facilities orbit its F7V star.',
faction: 'Gallente Federation',
population: '3.8 billion',
resources: ['Omber', 'Kernite', 'Jaspet'],
bodies: [
{ name: 'Dodixie I', type: 'rocky', orbit: 4, period: 2.5, size: 0.25, color: '#6a5a7a', ecc: 0.01, inc: 0, moons: [] },
{ name: 'Dodixie II', type: 'terrestrial', orbit: 9, period: 7, size: 0.5, color: '#5a8aaa', ecc: 0.015, inc: 0.02, atmosphere: '#7aaacc', moons: [] },
{ name: 'Dodixie III', type: 'gas', orbit: 16, period: 18, size: 0.85, color: '#7a6aaa', ecc: 0.02, inc: 0.01, hasRings: true, moons: [{ name: 'Dodixie III-a', orbit: 2.5, period: 2, size: 0.1, color: '#9a8aba' }] },
],
},
'u-irtyr': {
description: 'Dangerous low-security system. Pirate activity is rampant and uncharted asteroid fields hide valuable ores.',
faction: 'Unclaimed',
population: '~2,000',
resources: ['Hemorphite', 'Jaspet', 'Arkonor'],
bodies: [
{ name: 'U-IRTYR I', type: 'rocky', orbit: 5, period: 3, size: 0.35, color: '#6a4a3a', ecc: 0.15, inc: 0.08, moons: [] },
{ name: 'U-IRTYR II', type: 'rocky', orbit: 10, period: 8, size: 0.3, color: '#5a3a2a', ecc: 0.12, inc: 0.1, moons: [] },
{ name: 'Asteroid Belt', type: 'belt', innerOrbit: 15, outerOrbit: 22, count: 100 },
],
},
'pf-346': {
description: 'Low-sec border system. Contested territory with valuable resources and frequent skirmishes.',
faction: 'Contested',
population: '~15,000',
resources: ['Jaspet', 'Hemorphite', 'Kernite'],
bodies: [
{ name: 'PF-346 I', type: 'rocky', orbit: 6, period: 4, size: 0.3, color: '#7a5a4a', ecc: 0.08, inc: 0.04, moons: [] },
{ name: 'PF-346 II', type: 'terrestrial', orbit: 12, period: 10, size: 0.5, color: '#4a6a5a', ecc: 0.05, inc: 0.03, moons: [{ name: 'PF-346 II-a', orbit: 1.5, period: 1.2, size: 0.08, color: '#8a8a7a' }] },
],
},
'huzzah': {
description: 'Null-sec wasteland. No law, no stations, no mercy. Rare ores attract the desperate and the bold.',
faction: 'Unclaimed',
population: '< 100',
resources: ['Arkonor', 'Bistot', 'Crokmite'],
bodies: [
{ name: 'YZ-LQL I', type: 'rocky', orbit: 5, period: 3.5, size: 0.25, color: '#4a3a2a', ecc: 0.2, inc: 0.15, moons: [] },
{ name: 'Asteroid Belt', type: 'belt', innerOrbit: 8, outerOrbit: 15, count: 120 },
],
},
'pirates': {
description: 'Deep null-sec. Pirate stronghold with hidden bases and rich, unexploited asteroid belts.',
faction: 'Guristas Pirates',
population: 'Unknown',
resources: ['Arkonor', 'Mercoxit', 'Dark Ochre'],
bodies: [
{ name: 'O-WAMW I', type: 'gas', orbit: 8, period: 6, size: 0.7, color: '#8a3a3a', ecc: 0.06, inc: 0.03, moons: [{ name: 'O-WAMW I-a', orbit: 2, period: 1.5, size: 0.12, color: '#6a4a4a' }] },
{ name: 'O-WAMW II', type: 'gas', orbit: 18, period: 20, size: 1.0, color: '#5a2a5a', ecc: 0.04, inc: 0.05, hasRings: true },
{ name: 'Asteroid Belt', type: 'belt', innerOrbit: 25, outerOrbit: 32, count: 90 },
{ name: 'O-WAMW III', type: 'rocky', orbit: 38, period: 45, size: 0.4, color: '#3a2a3a', ecc: 0.1, inc: 0.08, moons: [] },
],
},
};
window.GDD.CONSTANTS = { SYSTEMS, CONNECTIONS, ASTEROID_TYPES, ORE_PRICES, MODULES, MARKET_ORDERS, CELESTIAL_BODIES };