Initial commit
This commit is contained in:
555
js/pages/ships.js
Normal file
555
js/pages/ships.js
Normal file
@@ -0,0 +1,555 @@
|
||||
window.GDD = window.GDD || {};
|
||||
|
||||
function ShipsPage() {
|
||||
const [activeSection, setActiveSection] = React.useState('classes');
|
||||
|
||||
const shipClasses = [
|
||||
{
|
||||
name: 'Frigate',
|
||||
hull: 400, armor: 350, shield: 300,
|
||||
highSlots: 3, medSlots: 3, lowSlots: 2,
|
||||
cpu: 120, powerGrid: 40, cargo: 150,
|
||||
speed: 280, mass: 1200,
|
||||
role: 'Fast scout and tackle. Low slot count but quick to align and warp. Good for new players.',
|
||||
examples: ['Merlin', 'Rifter', 'Incursus', 'Punisher'],
|
||||
},
|
||||
{
|
||||
name: 'Destroyer',
|
||||
hull: 650, armor: 550, shield: 500,
|
||||
highSlots: 7, medSlots: 3, lowSlots: 3,
|
||||
cpu: 180, powerGrid: 65, cargo: 300,
|
||||
speed: 210, mass: 1800,
|
||||
role: 'Anti-frigate platform. Many turret hardpoints but slow and vulnerable to larger ships.',
|
||||
examples: ['Cormorant', 'Thrasher', 'Catalyst', 'Coercer'],
|
||||
},
|
||||
{
|
||||
name: 'Cruiser',
|
||||
hull: 1200, armor: 1000, shield: 900,
|
||||
highSlots: 5, medSlots: 4, lowSlots: 4,
|
||||
cpu: 280, powerGrid: 110, cargo: 600,
|
||||
speed: 175, mass: 3500,
|
||||
role: 'Versatile workhorse. Can mine, fight, or explore. Good cargo hold and balanced slot layout.',
|
||||
examples: ['Osprey', 'Rupture', 'Vexor', 'Maller'],
|
||||
},
|
||||
{
|
||||
name: 'Battlecruiser',
|
||||
hull: 2800, armor: 2400, shield: 2000,
|
||||
highSlots: 7, medSlots: 5, lowSlots: 5,
|
||||
cpu: 380, powerGrid: 180, cargo: 1000,
|
||||
speed: 130, mass: 7000,
|
||||
role: 'Command ship. Can fit warfare links and project damage. Excellent fleet support.',
|
||||
examples: ['Drake', 'Hurricane', 'Myrmidon', 'Harbinger'],
|
||||
},
|
||||
{
|
||||
name: 'Battleship',
|
||||
hull: 6000, armor: 5000, shield: 4500,
|
||||
highSlots: 8, medSlots: 5, lowSlots: 6,
|
||||
cpu: 520, powerGrid: 280, cargo: 1800,
|
||||
speed: 90, mass: 15000,
|
||||
role: 'Heavy assault platform. Maximum firepower and tank but very slow. Fleet anchor.',
|
||||
examples: ['Rokh', 'Tempest', 'Dominix', 'Apocalypse'],
|
||||
},
|
||||
];
|
||||
|
||||
const slotTypes = [
|
||||
{
|
||||
name: 'High Slots',
|
||||
color: 'var(--red)',
|
||||
icon: '◆',
|
||||
description: 'Weapons, mining lasers, cloaks, salvagers. The things that do stuff to other things.',
|
||||
modules: ['150mm Railgun', '200mm Autocannon', 'Heavy Missile Launcher', 'Mining Laser II', 'Salvager I', 'Cloaking Device'],
|
||||
fitting: 'Turrets and launchers require both CPU and Power Grid. Heavy weapons need more of both.',
|
||||
},
|
||||
{
|
||||
name: 'Medium Slots',
|
||||
color: 'var(--cyan)',
|
||||
icon: '◇',
|
||||
description: 'Shields, propulsion, electronic warfare, tackle. The things that keep you alive or stop them.',
|
||||
modules: ['Shield Booster', '1MN Afterburner', 'Warp Scrambler', 'Stasis Webifier', 'ECM Jammer', 'Shield Extender'],
|
||||
fitting: 'Shield and propulsion modules are CPU-heavy. EWAR fits are tight on CPU, light on grid.',
|
||||
},
|
||||
{
|
||||
name: 'Low Slots',
|
||||
color: 'var(--green)',
|
||||
icon: '○',
|
||||
description: 'Armor, damage mods, cargo expanders, power diagnostics. Passive upgrades and tank.',
|
||||
modules: ['Armor Plate', 'Magnetic Field Stabilizer', 'Cargo Expander', 'Power Diagnostic System', 'Capacitor Power Relay', 'Armor Repairer'],
|
||||
fitting: 'Armor and damage modules are Power Grid-heavy. Passive modules use less CPU.',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="content-inner">
|
||||
<h1 style={{ marginBottom: '8px' }}>Ships & Fitting System</h1>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.95rem', maxWidth: '680px' }}>
|
||||
Ships are the player's primary asset. Each ship has a slot layout with CPU and Power Grid limits
|
||||
that constrain what modules can be fitted. Players own multiple ships and can assign AI crew to
|
||||
pilot them on autonomous tasks.
|
||||
</p>
|
||||
|
||||
{/* Tab navigation */}
|
||||
<div style={{ display: 'flex', gap: 'var(--sp-2)', marginBottom: 'var(--sp-6)' }}>
|
||||
{[
|
||||
{ id: 'classes', label: 'Ship Classes' },
|
||||
{ id: 'fitting', label: 'Fitting / Slots' },
|
||||
{ id: 'acquisition', label: '🚀 Acquisition' },
|
||||
{ id: 'crew', label: 'AI Crew' },
|
||||
].map(t => (
|
||||
<button key={t.id} className={`btn btn-sm${activeSection === t.id ? ' btn-primary' : ''}`}
|
||||
onClick={() => setActiveSection(t.id)}>{t.label}</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* SHIP CLASSES */}
|
||||
{activeSection === 'classes' && (
|
||||
<>
|
||||
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>MVP scope:</strong> One ship class per faction to start (Frigate). Expand to Destroyer
|
||||
and Cruiser in Phase 5+. Full roster is the launch target.
|
||||
</div>
|
||||
|
||||
<div style={{ overflowX: 'auto' }}>
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th>Hull</th>
|
||||
<th>Armor</th>
|
||||
<th>Shield</th>
|
||||
<th>High</th>
|
||||
<th>Med</th>
|
||||
<th>Low</th>
|
||||
<th>CPU</th>
|
||||
<th>Grid</th>
|
||||
<th>Speed</th>
|
||||
<th>Cargo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{shipClasses.map((ship, i) => (
|
||||
<tr key={i}>
|
||||
<td style={{ color: 'var(--accent)', fontWeight: 600 }}>{ship.name}</td>
|
||||
<td className="mono">{ship.hull}</td>
|
||||
<td className="mono">{ship.armor}</td>
|
||||
<td className="mono">{ship.shield}</td>
|
||||
<td style={{ color: 'var(--red)' }}>{ship.highSlots}</td>
|
||||
<td style={{ color: 'var(--cyan)' }}>{ship.medSlots}</td>
|
||||
<td style={{ color: 'var(--green)' }}>{ship.lowSlots}</td>
|
||||
<td className="mono">{ship.cpu}</td>
|
||||
<td className="mono">{ship.powerGrid}</td>
|
||||
<td className="mono">{ship.speed}</td>
|
||||
<td className="mono">{ship.cargo}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: 'var(--sp-6)' }}>
|
||||
<h3>Class Details</h3>
|
||||
<div className="grid-2">
|
||||
{shipClasses.slice(0, 4).map((ship, i) => (
|
||||
<div key={i} className="card">
|
||||
<h4 style={{ color: 'var(--accent)', marginBottom: 'var(--sp-2)' }}>{ship.name}</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-3) 0' }}>{ship.role}</p>
|
||||
<div style={{ fontSize: '0.75rem', color: 'var(--muted)' }}>
|
||||
<strong>Variants:</strong> {ship.examples.join(', ')}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* FITTING / SLOTS */}
|
||||
{activeSection === 'fitting' && (
|
||||
<>
|
||||
<div className="section-header">
|
||||
<span className="section-num">SHIP-FIT</span>
|
||||
<h2 style={{ margin: 0 }}>Slot Types & Fitting Constraints</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid-2" style={{ marginBottom: 'var(--sp-6)' }}>
|
||||
{slotTypes.map((slot, i) => (
|
||||
<div key={i} className="card" style={{ borderLeft: `3px solid ${slot.color}` }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 'var(--sp-3)', marginBottom: 'var(--sp-3)' }}>
|
||||
<span style={{ color: slot.color, fontSize: '1.2rem' }}>{slot.icon}</span>
|
||||
<h4 style={{ color: slot.color, margin: 0 }}>{slot.name}</h4>
|
||||
</div>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-3) 0' }}>{slot.description}</p>
|
||||
<div style={{ fontSize: '0.8rem', color: 'var(--fg-dim)', marginBottom: 'var(--sp-2)' }}>
|
||||
<strong style={{ color: 'var(--muted)' }}>Typical modules:</strong>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--sp-1)' }}>
|
||||
{slot.modules.map((m, j) => (
|
||||
<span key={j} className="pill" style={{ background: 'var(--surface-raised)', color: 'var(--fg-dim)', border: '1px solid var(--border)', fontSize: '0.7rem' }}>
|
||||
{m}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="section-header">
|
||||
<span className="section-num">SHIP-CPU</span>
|
||||
<h2 style={{ margin: 0 }}>CPU & Power Grid</h2>
|
||||
</div>
|
||||
|
||||
<div className="card card-accent">
|
||||
<h4>Fitting Mechanics</h4>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
|
||||
1. Each module has a CPU cost and a Power Grid cost.<br/>
|
||||
2. Total fitted module costs must not exceed ship's CPU and Power Grid.<br/>
|
||||
3. Some modules have ship bonuses (e.g. "+5% mining laser yield per Cruiser level").<br/>
|
||||
4. Rig slots add permanent modifications — cannot be removed, only destroyed.<br/>
|
||||
5. Fitting is only possible when docked at a station with fitting service.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid-2" style={{ marginTop: 'var(--sp-5)' }}>
|
||||
<div className="card">
|
||||
<h4 style={{ color: 'var(--accent)' }}>Example: Mining Cruiser Fit</h4>
|
||||
<table className="data-table">
|
||||
<thead><tr><th>Slot</th><th>Module</th><th>CPU</th><th>Grid</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td style={{ color: 'var(--red)' }}>High 1</td><td>Mining Laser II</td><td className="mono">30</td><td className="mono">10</td></tr>
|
||||
<tr><td style={{ color: 'var(--red)' }}>High 2</td><td>Mining Laser II</td><td className="mono">30</td><td className="mono">10</td></tr>
|
||||
<tr><td style={{ color: 'var(--cyan)' }}>Med 1</td><td>1MN Afterburner</td><td className="mono">25</td><td className="mono">15</td></tr>
|
||||
<tr><td style={{ color: 'var(--cyan)' }}>Med 2</td><td>Shield Booster I</td><td className="mono">30</td><td className="mono">10</td></tr>
|
||||
<tr><td style={{ color: 'var(--cyan)' }}>Med 3</td><td>Market Analyzer (AI)</td><td className="mono">15</td><td className="mono">0</td></tr>
|
||||
<tr><td style={{ color: 'var(--green)' }}>Low 1</td><td>Mining Upgrade I</td><td className="mono">20</td><td className="mono">5</td></tr>
|
||||
<tr><td style={{ color: 'var(--green)' }}>Low 2</td><td>Cargo Expander I</td><td className="mono">15</td><td className="mono">0</td></tr>
|
||||
<tr><td style={{ color: 'var(--green)' }}>Low 3</td><td>Nav Processor (AI)</td><td className="mono">10</td><td className="mono">0</td></tr>
|
||||
<tr style={{ borderTop: '2px solid var(--border-light)' }}>
|
||||
<td colSpan="2" style={{ fontWeight: 600 }}>Total</td>
|
||||
<td className="mono" style={{ fontWeight: 600, color: 'var(--cyan)' }}>175/280</td>
|
||||
<td className="mono" style={{ fontWeight: 600, color: 'var(--green)' }}>50/110</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style={{ marginTop: 'var(--sp-2)', fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--purple)' }}>
|
||||
AI modules: Market Analyzer (med) tracks local prices and flags arbitrage opportunities. Nav Processor (low) optimizes warp routes. See Ship AI \u2192 Module Gates tab.
|
||||
</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h4 style={{ color: 'var(--red)' }}>Example: Combat Frigate Fit</h4>
|
||||
<table className="data-table">
|
||||
<thead><tr><th>Slot</th><th>Module</th><th>CPU</th><th>Grid</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td style={{ color: 'var(--red)' }}>High 1</td><td>150mm Railgun</td><td className="mono">35</td><td className="mono">12</td></tr>
|
||||
<tr><td style={{ color: 'var(--red)' }}>High 2</td><td>200mm Autocannon</td><td className="mono">30</td><td className="mono">14</td></tr>
|
||||
<tr><td style={{ color: 'var(--cyan)' }}>Med 1</td><td>Warp Scrambler I</td><td className="mono">25</td><td className="mono">1</td></tr>
|
||||
<tr><td style={{ color: 'var(--cyan)' }}>Med 2</td><td>1MN Afterburner</td><td className="mono">25</td><td className="mono">15</td></tr>
|
||||
<tr><td style={{ color: 'var(--green)' }}>Low 1</td><td>Armor Plate I</td><td className="mono">10</td><td className="mono">20</td></tr>
|
||||
<tr><td style={{ color: 'var(--green)' }}>Low 2</td><td>Magnetic Field Stab.</td><td className="mono">15</td><td className="mono">5</td></tr>
|
||||
<tr style={{ borderTop: '2px solid var(--border-light)' }}>
|
||||
<td colSpan="2" style={{ fontWeight: 600 }}>Total</td>
|
||||
<td className="mono" style={{ fontWeight: 600, color: 'var(--cyan)' }}>140/120 ⚠</td>
|
||||
<td className="mono" style={{ fontWeight: 600, color: 'var(--green)' }}>67/40 ⚠</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="callout callout-danger" style={{ marginTop: 'var(--sp-3)', fontSize: '0.8rem' }}>
|
||||
<strong>Overfit!</strong> CPU 140/120 and Grid 67/40 — exceeds ship capacity. Drop a turret or fit lower-tier modules.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* SHIP ACQUISITION */}
|
||||
{activeSection === 'acquisition' && (<>
|
||||
<div className="section-header">
|
||||
<span className="section-num">SHIP-ACQ</span>
|
||||
<h2 style={{ margin: 0 }}>Ship Acquisition & Hangar</h2>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>Ships are the player's primary asset, and acquiring them is a core economic milestone.</strong>
|
||||
The system balances accessibility (new players always have a ship) with economic consequence
|
||||
(better ships cost real ISK and represent player investment). Players can own multiple ships
|
||||
stored in station hangars, but only fly one at a time. Switching ships requires docking.
|
||||
</div>
|
||||
|
||||
<h3 style={{ marginBottom: 'var(--sp-4)' }}>Ship Ownership Model</h3>
|
||||
<div className="grid-2" style={{ marginBottom: 'var(--sp-6)' }}>
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--green)' }}>
|
||||
<h4 style={{ color: 'var(--green)' }}>Single Active Ship</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-3) 0' }}>
|
||||
A player has exactly <strong style={{ color: 'var(--fg)' }}>one active ship</strong> at a time — the ship they're currently piloting.
|
||||
This is the ship that appears in the star system, has a position, and can perform actions (mine, fight, warp).
|
||||
The active ship cannot be traded, contracted, or stored while it is active.
|
||||
</p>
|
||||
</div>
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--cyan)' }}>
|
||||
<h4 style={{ color: 'var(--cyan)' }}>Hangar Storage</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-3) 0' }}>
|
||||
Ships not currently being piloted are stored in a <strong style={{ color: 'var(--fg)' }}>station hangar</strong>.
|
||||
Each station has a hangar per player. A player can store unlimited ships at any station they have docking access to.
|
||||
Hangar ships are safe — they cannot be destroyed or stolen while stored.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 style={{ marginBottom: 'var(--sp-4)' }}>How Players Get Ships</h3>
|
||||
<div style={{ overflowX: 'auto', marginBottom: 'var(--sp-6)' }}>
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr><th>Method</th><th>Cost</th><th>Available At</th><th>Phase</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{[
|
||||
{ method: 'Rookie Frigate (free)', cost: '0 ISK — granted on first spawn and on death respawn', available: 'Automatic on new player creation. Automatic on respawn after ship destruction.', phase: 'Phase 0', color: 'var(--green)' },
|
||||
{ method: 'NPC Market (sell orders)', cost: 'Hull base value × 1.0–1.5 (station markup)', available: 'Any station with Market service. NPC sell orders seeded at galaxy gen.', phase: 'Phase 6', color: 'var(--cyan)' },
|
||||
{ method: 'Player Market (sell orders)', cost: 'Player-set price — typically below NPC price for T1, above for T2', available: 'Any station with Market service. Player-placed sell orders.', phase: 'Phase 10', color: 'var(--accent)' },
|
||||
{ method: 'Manufacturing', cost: 'Minerals (from refining ore) + blueprint + factory fee + time', available: 'Stations with Factory service. Requires Industry skill ≥ ship class tier.', phase: 'Phase 5', color: 'var(--purple)' },
|
||||
{ method: 'Loyalty Point Store', cost: 'ISK + LP — faction ships at below-market rates', available: 'Faction stations only. Requires high standing + LP balance.', phase: 'Phase 12', color: 'var(--red)' },
|
||||
].map((row, i) => (
|
||||
<tr key={i}>
|
||||
<td style={{ fontWeight: 600, color: row.color }}>{row.method}</td>
|
||||
<td style={{ color: 'var(--fg-dim)', fontSize: '0.85rem' }}>{row.cost}</td>
|
||||
<td style={{ color: 'var(--fg-dim)', fontSize: '0.85rem' }}>{row.available}</td>
|
||||
<td className="mono">{row.phase}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 style={{ marginBottom: 'var(--sp-4)' }}>The Rookie Frigate</h3>
|
||||
<div className="grid-2" style={{ marginBottom: 'var(--sp-6)' }}>
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--green)' }}>
|
||||
<h4 style={{ color: 'var(--green)' }}>Free Ship Policy</h4>
|
||||
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>On first spawn:</strong> New player receives a Rookie Frigate at their faction's starter station.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>On death (ship destroyed):</strong> Player respawns at their home station with a <em>new</em> Rookie Frigate. Always free.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Cannot be sold or traded:</strong> The Rookie Frigate has no market value.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Cannot be insured:</strong> Insurance doesn't apply — you always get a new one free.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>Basic stats:</strong> 2 high slots, 2 mid slots, 1 low slot. 200 hull, 150 armor, 100 shield. 100 cargo. Very limited — enough for basic mining and combat, but weak.</li>
|
||||
<li><strong style={{ color: 'var(--fg)' }}>NPC market exclusion:</strong> Rookie Frigates are never sold on the NPC market — they exist only as free grants.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--red)' }}>
|
||||
<h4 style={{ color: 'var(--red)' }}>Why Free Respawn?</h4>
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: '0 0 var(--sp-3) 0' }}>
|
||||
A player without a ship has no way to earn ISK — they can't mine, fight, or trade. A permanent
|
||||
"ship-less" state is a dead-end that causes player churn. The free Rookie Frigate ensures that
|
||||
<strong style={{ color: 'var(--fg)' }}> every player always has a path back into the game</strong>, no matter how
|
||||
many times they're destroyed. The cost of death is the <em>upgraded</em> ship and modules you lost —
|
||||
not the ability to play at all.
|
||||
</p>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--muted)' }}>
|
||||
Design rule: "Never softlock the player out of the game loop." The Rookie Frigate is the safety net.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 style={{ marginBottom: 'var(--sp-4)' }}>NPC Market — Ship Pricing</h3>
|
||||
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>NPC sell orders provide baseline ship availability.</strong> At galaxy generation, the server seeds NPC sell orders
|
||||
for every ship type at stations with Factory services. These orders have <em>infinite</em> quantity (they never run out)
|
||||
but are priced at a premium over manufacturing cost. This ensures:
|
||||
(1) players can always buy a basic ship hull, (2) player manufacturers can undercut NPC prices profitably,
|
||||
(3) the economy has a known ISK sink ceiling per ship class.
|
||||
</div>
|
||||
<div style={{ overflowX: 'auto', marginBottom: 'var(--sp-6)' }}>
|
||||
<table className="data-table">
|
||||
<thead>
|
||||
<tr><th>Ship Class</th><th>Manufacturing Cost</th><th>NPC Sell Price</th><th>Insurance (Standard)</th><th>Effective Replacement</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{[
|
||||
{ cls: 'Frigate', mfg: '~8,000 ISK', npc: '~15,000 ISK', insurance: '~10,500 ISK (70%)', effective: '~4,500 ISK + modules' },
|
||||
{ cls: 'Destroyer', mfg: '~20,000 ISK', npc: '~35,000 ISK', insurance: '~24,500 ISK (70%)', effective: '~10,500 ISK + modules' },
|
||||
{ cls: 'Cruiser', mfg: '~60,000 ISK', npc: '~100,000 ISK', insurance: '~70,000 ISK (70%)', effective: '~30,000 ISK + modules' },
|
||||
{ cls: 'Battlecruiser', mfg: '~180,000 ISK', npc: '~300,000 ISK', insurance: '~210,000 ISK (70%)', effective: '~90,000 ISK + modules' },
|
||||
{ cls: 'Battleship', mfg: '~500,000 ISK', npc: '~800,000 ISK', insurance: '~560,000 ISK (70%)', effective: '~240,000 ISK + modules' },
|
||||
].map((row, i) => (
|
||||
<tr key={i}>
|
||||
<td style={{ fontWeight: 600, color: 'var(--accent)' }}>{row.cls}</td>
|
||||
<td className="mono">{row.mfg}</td>
|
||||
<td className="mono" style={{ color: 'var(--red)' }}>{row.npc}</td>
|
||||
<td className="mono" style={{ color: 'var(--green)' }}>{row.insurance}</td>
|
||||
<td className="mono" style={{ color: 'var(--fg-dim)' }}>{row.effective}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 style={{ marginBottom: 'var(--sp-4)' }}>Ship Switching Flow</h3>
|
||||
<div className="card card-accent" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<h4 style={{ marginBottom: 'var(--sp-4)' }}>Docked Ship Switch</h4>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2.2 }}>
|
||||
<span style={{ color: 'var(--cyan)' }}>1. Dock at station</span> — Player must be docked. Cannot switch ships while in space.<br/>
|
||||
<span style={{ color: 'var(--accent)' }}>2. Open Hangar panel</span> — Station Mode → Hangar tab. Shows all ships stored at this station.<br/>
|
||||
<span style={{ color: 'var(--green)' }}>3. Select a ship</span> — Shows ship name, class, fitting summary, cargo, insurance status.<br/>
|
||||
<span style={{ color: 'var(--purple)' }}>4. Activate</span> — Click "Make Active". Current active ship moves to hangar. Selected ship becomes active.<br/>
|
||||
<span style={{ color: 'var(--fg)' }}>5. Cargo transfer</span> — Prompt to transfer cargo between ships (limited by destination capacity). Remaining stays in station inventory.<br/>
|
||||
<span style={{ color: 'var(--muted)' }}>6. Undock</span> — Player undocks in the new active ship. Old ship stays in hangar.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-warn" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>Cannot switch while in space.</strong> If your ship is destroyed, you respawn at your home station
|
||||
in a Rookie Frigate — you cannot switch to a hangar ship remotely. You must fly to the station where the ship is stored and dock.
|
||||
This is intentional: it creates geographic identity ("my ships are in Amarr") and makes home station choice meaningful.
|
||||
</div>
|
||||
|
||||
<div className="section-header" style={{ marginTop: 'var(--sp-6)' }}>
|
||||
<span className="section-num">SHIP-ACQ-DB</span>
|
||||
<h2 style={{ margin: 0 }}>Backend Impact</h2>
|
||||
</div>
|
||||
<div className="card card-accent">
|
||||
<h4 style={{ marginBottom: 'var(--sp-4)' }}>Schema & Reducer Changes</h4>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
|
||||
<span style={{ color: 'var(--accent)' }}>ships</span> — add column: <code>storage_location</code> (enum: active / hangar:station_id). When active, ship has system_id/x/y/z. When in hangar, stored at station.<br/>
|
||||
<span style={{ color: 'var(--cyan)' }}>ships</span> — add column: <code>is_rookie</code> (bool, default false). Rookie frigates are untradeable, uninsurable, free-replace.<br/>
|
||||
<span style={{ color: 'var(--green)' }}>npc_sell_orders</span> — seeded at galaxy gen for every <code>ship_types</code> entry at Factory stations. Infinite quantity. Price = <code>base_hull_value × 1.5</code>.<br/>
|
||||
<span style={{ color: 'var(--purple)' }}>New reducer:</span> <code>switch_ship(player_id, target_ship_id)</code> — validate docked, validate target in same station hangar, swap active ↔ hangar.<br/>
|
||||
<span style={{ color: 'var(--red)' }}>Updated reducer:</span> <code>connect_player(display_name)</code> — on first connection, spawn Rookie Frigate at faction starter station. On subsequent, load existing active ship.<br/>
|
||||
<span style={{ color: 'var(--fg)' }}>Updated reducer:</span> <code>respawn_player(player_id)</code> — on ship destruction, create new Rookie Frigate at home station, set as active.
|
||||
</div>
|
||||
</div>
|
||||
</>)}
|
||||
|
||||
{/* AI CREW */}
|
||||
{activeSection === 'crew' && (
|
||||
<>
|
||||
<div className="callout callout-info" style={{ marginBottom: 'var(--sp-5)' }}>
|
||||
<strong>Post-MVP feature.</strong> AI crew is designed here so the ship and backend architecture
|
||||
supports it from the start, but implementation is planned after the core gameplay loop ships.
|
||||
</div>
|
||||
|
||||
<div className="section-header">
|
||||
<span className="section-num">SHIP-AI</span>
|
||||
<h2 style={{ margin: 0 }}>AI Crew System</h2>
|
||||
</div>
|
||||
|
||||
<p style={{ color: 'var(--fg-dim)', fontSize: '0.9rem', maxWidth: '680px', marginBottom: 'var(--sp-5)' }}>
|
||||
Players can own multiple ships and assign AI crew members to pilot them. AI ships execute
|
||||
autonomous tasks — mining runs, patrol routes, trade delivery — while the player controls
|
||||
their primary ship directly. AI crew gain experience over time and improve at their assigned role.
|
||||
</p>
|
||||
|
||||
<div className="grid-2" style={{ marginBottom: 'var(--sp-6)' }}>
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--accent)' }}>
|
||||
<h4 style={{ color: 'var(--accent)' }}>Crew Roles</h4>
|
||||
<table className="data-table">
|
||||
<thead><tr><th>Role</th><th>Behavior</th><th>XP Growth</th></tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span className="pill pill-amber">Miner</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Warps to belt, mines until cargo full, returns to station, sells ore.</td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Faster cycle times, better ore selection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="pill pill-cyan">Patrol</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Circulates waypoints, engages hostiles, reports contacts.</td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Better target priority, longer patrol endurance.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="pill pill-green">Hauler</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Moves cargo between stations along trade routes.</td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Faster warp align, larger cargo optimization.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span className="pill pill-red">Guard</span></td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Escorts player ship, engages threats within range.</td>
|
||||
<td style={{ color: 'var(--fg-dim)' }}>Better reaction time, coordination with fleet.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--cyan)' }}>
|
||||
<h4 style={{ color: 'var(--cyan)' }}>Crew Progression</h4>
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
|
||||
<strong style={{ color: 'var(--fg)' }}>Rank levels:</strong><br/>
|
||||
<span style={{ color: 'var(--muted)' }}>Cadet</span> → <span style={{ color: 'var(--green)' }}>Ensign</span> →{' '}
|
||||
<span style={{ color: 'var(--cyan)' }}>Lieutenant</span> →{' '}
|
||||
<span style={{ color: 'var(--purple)' }}>Commander</span> →{' '}
|
||||
<span style={{ color: 'var(--accent)' }}>Captain</span><br/><br/>
|
||||
<strong style={{ color: 'var(--fg)' }}>XP sources:</strong><br/>
|
||||
• Task completion (base XP)<br/>
|
||||
• Task success rate bonus<br/>
|
||||
• Survival bonus (ship not destroyed)<br/>
|
||||
• Player commendation (manual XP grant)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="section-header">
|
||||
<span className="section-num">SHIP-OPS</span>
|
||||
<h2 style={{ margin: 0 }}>Task Assignment Flow</h2>
|
||||
</div>
|
||||
|
||||
<div className="card card-accent">
|
||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', color: 'var(--fg-dim)', lineHeight: 2 }}>
|
||||
1. Player docks at station and opens <strong style={{ color: 'var(--fg)' }}>Crew Management</strong> panel<br/>
|
||||
2. Selects an idle ship + available crew member<br/>
|
||||
3. Assigns a <strong style={{ color: 'var(--accent)' }}>task template</strong> (mine system X, patrol route Y, haul to station Z)<br/>
|
||||
4. Crew departs autonomously — ship disappears from player's direct control<br/>
|
||||
5. Player receives periodic <strong style={{ color: 'var(--cyan)' }}>status reports</strong> in a dedicated channel<br/>
|
||||
6. Task completes (or ship is destroyed) → crew returns to station or sends distress signal<br/>
|
||||
7. Resources earned are deposited in player's station inventory
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-warn" style={{ marginTop: 'var(--sp-5)' }}>
|
||||
<strong>Risk:</strong> AI crew earning passive income could trivialize the economy. Mitigation: AI
|
||||
operations have costs (fuel, maintenance, crew wages) and diminishing returns at scale. A player
|
||||
with 10 AI miners shouldn't earn 10× a single player — there should be coordination overhead.
|
||||
</div>
|
||||
|
||||
<div className="callout callout-info" style={{ marginTop: 'var(--sp-4)' }}>
|
||||
<strong>AI Crew vs. Zora (Ship AI):</strong> These are two different systems. <strong>AI Crew</strong> (this tab) are autonomous
|
||||
pilots that fly <em>other</em> ships on your behalf — mining runs, patrol routes, hauling. <strong>Zora</strong> (see Ship AI page)
|
||||
is a companion AI installed on <em>your current ship</em> that provides market intelligence, tactical advice,
|
||||
and dialogue. Think of AI Crew as your employees and Zora as your ship's computer. They do not share
|
||||
systems, modules, or XP. A future expansion may let Zora be assigned to an AI Crew ship, but that is post-MVP scope.
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Death & Loss */}
|
||||
<div className="callout callout-info" style={{ marginTop: 'var(--sp-6)' }}>
|
||||
<strong>Slot scope note:</strong> High, Medium, and Low slots cover combat, mining, propulsion, and tank modules. Ship AI modules (Communications Processor, Market Analyzer, etc.) are a separate system — see the <em>Ship AI → Module Gates</em> tab for the full AI module catalog and how they install alongside standard fittings.
|
||||
</div>
|
||||
|
||||
<div className="section-header" style={{ marginTop: 'var(--sp-8)' }}>
|
||||
<span className="section-num">SHIP-DEATH</span>
|
||||
<h2 style={{ margin: 0 }}>Ship Destruction</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid-2">
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--red)' }}>
|
||||
<h4 style={{ color: 'var(--red)' }}>What you lose</h4>
|
||||
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
|
||||
<li>The ship hull itself (destroyed)</li>
|
||||
<li>All fitted modules (50% chance each to drop as loot)</li>
|
||||
<li>Cargo — destroyed or dropped (50/50 split)</li>
|
||||
<li>AI crew aboard — injured, require medical bay recovery time</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="card" style={{ borderLeft: '3px solid var(--green)' }}>
|
||||
<h4 style={{ color: 'var(--green)' }}>What you keep</h4>
|
||||
<ul style={{ color: 'var(--fg-dim)', fontSize: '0.85rem', margin: 0, paddingLeft: 'var(--sp-5)' }}>
|
||||
<li>Your other ships in hangars</li>
|
||||
<li>Station inventory and assets</li>
|
||||
<li>Player XP and progression</li>
|
||||
<li>ISK in wallet (₢)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-danger" style={{ marginTop: 'var(--sp-5)' }}>
|
||||
<strong>Respawn:</strong> Player respawns at their home station (or nearest friendly station) in a
|
||||
rookie frigate. Insurance policies can partially reimburse ship loss.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
window.GDD.ShipsPage = ShipsPage;
|
||||
Reference in New Issue
Block a user