window.GDD = window.GDD || {}; const { useState, useEffect, useCallback, useRef } = React; function ProgressionDemo() { const [skills, setSkills] = useState([]); const [activeCategory, setActiveCategory] = useState('all'); const [selectedSkill, setSelectedSkill] = useState(null); const [totalXP, setTotalXP] = useState(0); const [xpLog, setXpLog] = useState([]); const [simulating, setSimulating] = useState(false); const simRef = useRef(null); const allSkills = [ // Combat { name: 'Gunnery', category: 'Combat', xp: 380, level: 2, nextLevel: 500 }, { name: 'Missiles', category: 'Combat', xp: 120, level: 1, nextLevel: 500 }, { name: 'Shield Operation', category: 'Combat', xp: 50, level: 0, nextLevel: 100 }, { name: 'Armor Tanking', category: 'Combat', xp: 0, level: 0, nextLevel: 100 }, { name: 'Electronic Warfare', category: 'Combat', xp: 0, level: 0, nextLevel: 100 }, // Industry { name: 'Mining', category: 'Industry', xp: 1850, level: 3, nextLevel: 2000 }, { name: 'Refining', category: 'Industry', xp: 420, level: 2, nextLevel: 500 }, { name: 'Manufacturing', category: 'Industry', xp: 80, level: 0, nextLevel: 100 }, { name: 'Blueprint Research', category: 'Industry', xp: 0, level: 0, nextLevel: 100 }, // Navigation { name: 'Warp Drive Operation', category: 'Navigation', xp: 60, level: 0, nextLevel: 100 }, { name: 'Afterburner', category: 'Navigation', xp: 30, level: 0, nextLevel: 100 }, { name: 'Evasive Maneuvering', category: 'Navigation', xp: 0, level: 0, nextLevel: 100 }, // Trade { name: 'Market Analysis', category: 'Trade', xp: 20, level: 0, nextLevel: 100 }, { name: 'Broker Relations', category: 'Trade', xp: 45, level: 0, nextLevel: 100 }, { name: 'Hauling', category: 'Trade', xp: 0, level: 0, nextLevel: 100 }, // Leadership { name: 'Fleet Command', category: 'Leadership', xp: 0, level: 0, nextLevel: 100 }, { name: 'AI Coordination', category: 'Leadership', xp: 0, level: 0, nextLevel: 100 }, ]; const xpCurve = [100, 500, 2000, 8000, 32000]; const categoryColors = { Combat: 'var(--red)', Industry: 'var(--accent)', Navigation: 'var(--cyan)', Trade: 'var(--green)', Leadership: 'var(--purple)', }; const xpActions = [ { name: 'Mining Cycle', xp: 15, category: 'Industry', desc: 'Complete a mining laser cycle' }, { name: 'NPC Kill', xp: 40, category: 'Combat', desc: 'Destroy an NPC pirate' }, { name: 'Refine Batch', xp: 25, category: 'Industry', desc: 'Refine a batch of ore' }, { name: 'System Jump', xp: 5, category: 'Navigation', desc: 'Jump to a new system' }, { name: 'Market Trade', xp: 20, category: 'Trade', desc: 'Complete a market transaction' }, { name: 'Player Kill', xp: 120, category: 'Combat', desc: 'Destroy a player ship' }, { name: 'Manufacture Item', xp: 35, category: 'Industry', desc: 'Complete a manufacturing job' }, { name: 'Waypoint Route', xp: 30, category: 'Navigation', desc: 'Complete a multi-jump route' }, { name: 'Bounty Collect', xp: 80, category: 'Combat', desc: 'Collect a bounty reward' }, ]; useEffect(() => { setSkills(allSkills.map(s => ({ ...s }))); }, []); useEffect(() => { const total = skills.reduce((sum, s) => sum + s.xp, 0); setTotalXP(total); }, [skills]); const filteredSkills = activeCategory === 'all' ? skills : skills.filter(s => s.category === activeCategory); const categoryStats = Object.keys(categoryColors).map(cat => { const catSkills = skills.filter(s => s.category === cat); const totalXP = catSkills.reduce((sum, s) => sum + s.xp, 0); const maxXP = catSkills.reduce((sum, s) => sum + xpCurve[Math.min(s.level, 4)], 0); const avgLevel = catSkills.length > 0 ? catSkills.reduce((sum, s) => sum + s.level, 0) / catSkills.length : 0; return { category: cat, color: categoryColors[cat], totalXP, maxXP, avgLevel, count: catSkills.length }; }); const handleSimulate = useCallback(() => { if (simulating) { setSimulating(false); if (simRef.current) clearInterval(simRef.current); return; } setSimulating(true); simRef.current = setInterval(() => { const action = xpActions[Math.floor(Math.random() * xpActions.length)]; const skillName = action.category === 'Combat' ? 'Gunnery' : action.category === 'Industry' ? 'Mining' : action.category === 'Navigation' ? 'Warp Drive Operation' : action.category === 'Trade' ? 'Broker Relations' : 'Fleet Command'; setSkills(prev => prev.map(s => { if (s.name !== skillName) return s; let newXp = s.xp + action.xp; let newLevel = s.level; while (newLevel < 5 && newXp >= xpCurve[newLevel]) { newXp -= xpCurve[newLevel]; newLevel++; } return { ...s, xp: newXp, level: newLevel, nextLevel: xpCurve[Math.min(newLevel, 4)] }; })); setXpLog(prev => [{ action: action.name, xp: action.xp, skill: skillName, time: new Date().toLocaleTimeString('en', { hour12: false }), }, ...prev.slice(0, 19)]); }, 800); }, [simulating]); useEffect(() => { return () => { if (simRef.current) clearInterval(simRef.current); }; }, []); const levelColor = (lvl) => { if (lvl === 0) return 'var(--muted)'; if (lvl === 1) return 'var(--green)'; if (lvl === 2) return 'var(--cyan)'; if (lvl === 3) return 'var(--purple)'; if (lvl === 4) return 'var(--accent)'; return 'var(--red)'; }; return (
Action-based XP system across 5 categories and 17+ skills. Hit the simulate button to watch XP flow in from random activities — each action awards XP to the matching skill category.
{/* HUD-style progression strip */}