/** * @file About panel component displaying changelog and how-to-play guide. * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ /* eslint-disable max-lines-per-function -- HOW_TO_PLAY data and render logic */ /* eslint-disable max-lines -- HOW_TO_PLAY data makes this file long */ import { type JSX, useEffect, useState } from "react"; import { getAbout } from "../../api/client.js"; import type { AboutResponse } from "@elysium/types"; const howToPlay = [ { body: "Hire adventurers to earn gold and essence automatically. Each tier is" + " more powerful than the last. Adventurers also contribute combat" + " power for boss fights — the more you recruit, the stronger your" + " party becomes.", title: "âš”ī¸ Adventurers", }, { body: "Click the guild hall to earn gold manually. Upgrades and equipment can" + " dramatically increase your gold per click. Clicking is especially" + " powerful in the early game and when saving up for big purchases.", title: "👆 Clicking", }, { body: "Purchase upgrades to multiply the gold and essence output of specific" + " adventurer tiers, or boost your whole guild. Upgrades are permanent" + " for the current run and compound with each other.", title: "🔧 Upgrades", }, { body: "Send your guild on quests that complete over time and reward gold," + " essence, crystals, equipment, and upgrades. Multiple quests can run" + " simultaneously. Completing quests also unlocks new zones.", title: "📜 Quests", }, { body: "Challenge zone bosses to earn large one-time rewards and unlock new" + " zones. Your party's combat power is based on the number and tier of" + " adventurers you've recruited. Defeated bosses cannot be re-fought," + " but undefeated bosses regenerate HP over time.", title: "👹 Boss Fights", }, { body: "New zones unlock when you defeat the final boss AND complete the final" + " quest of the previous zone. Each zone contains new bosses and" + " quests with progressively greater rewards.", title: "đŸ—ēī¸ Zones", }, { body: "Earn equipment from boss drops and quest rewards. Each piece provides" + " bonuses to gold income, click power, or combat. Rarer equipment" + " provides stronger bonuses. Equip matching set pieces (2 or 3 of a" + " named set) to unlock escalating set bonuses shown at the top of the" + " Equipment panel.", title: "đŸ—Ąī¸ Equipment & Sets", }, { body: "When you've progressed far enough, you can prestige to earn runestones" + " — a permanent currency that persists across all runs. Prestige" + " resets your current run but grants a production multiplier that" + " stacks with every prestige.", title: "⭐ Prestige", }, { body: "Spend runestones in the Prestige Shop on permanent upgrades that carry" + " over across all future runs. These upgrades multiply income, click" + " power, essence, and crystal gain — making each new run more powerful" + " than the last.", title: "🔮 Runestones & Prestige Upgrades", }, { body: "Purchase the Autonomous Ascension upgrade in the Prestige Shop" + " (100 runestones) to unlock the Auto-Prestige toggle. When enabled," + " you will automatically ascend the moment you reach the prestige" + " threshold, using your current character name. Toggle it on and off" + " freely from the Prestige Shop.", title: "âš™ī¸ Auto-Prestige", }, { body: "Earn achievements by hitting milestones — total gold earned, bosses" + " defeated, quests completed, and more. Achievements are purely" + " cosmetic and track your long-term progress across all prestige runs.", title: "🏆 Achievements", }, { body: "Complete daily challenges for bonus rewards including gold, essence," + " crystals, and runestones. Challenges reset each day and vary in" + " difficulty. Completing all daily challenges gives an extra bonus" + " reward.", title: "📅 Daily Challenges", }, { body: "Send scouts to explore areas within each zone. Explorations run in" + " real-time and reward gold, essence, and crafting materials when" + " collected. Each area has a set duration — short explorations are" + " faster but longer ones offer rarer finds. A 📖 icon marks areas" + " you've collected from at least once, unlocking a Codex entry.", title: "đŸ—ēī¸ Exploration", }, { body: "Use materials gathered from exploration to craft permanent bonuses." + " Each recipe provides a multiplier to gold income, essence income," + " click power, or combat power — all of which stack and persist across" + " prestige runs. Check the Crafting tab to see your material inventory" + " and available recipes per zone.", title: "âš—ī¸ Crafting", }, { body: "Defeating bosses, completing quests, acquiring equipment, hiring" + " adventurers, purchasing upgrades, unlocking prestige upgrades," + " discovering new zones, collecting from exploration areas, and" + " crafting recipes all permanently unlock lore entries in the Codex." + " A badge appears on the Codex tab and a toast notification pops up" + " each time new lore is discovered. Collect all 472 entries to build" + " a complete picture of the world of Elysium.", title: "📖 Codex", }, { body: "Visit the Character tab to write about your character and guild. Fill" + " in your character's name, pronouns, race, class, and backstory," + " then create a guild with its own name and lore. Your character sheet" + " is visible on your public profile page.", title: "📋 Character Sheet", }, { body: "Earn Titles by reaching milestones — defeating bosses, completing" + " quests, prestiging, and more. Once unlocked, titles are yours" + " forever and are never lost on prestige or transcendence resets. Set" + " your active title from the Character tab to display it on your" + " character sheet and public profile.", title: "🏅 Titles", }, { body: "Defeat bosses to earn equipment drops: weapons, armour, and trinkets." + " Each item provides bonuses to gold income, combat power, or click" + " power. Only one item per slot can be equipped at a time — visit the" + " Equipment panel to manage your loadout. Your currently equipped" + " items are displayed on your character sheet and public profile.", title: "đŸ—Ąī¸ Equipment", }, { body: "Compete with other adventurers on the public Leaderboards page!" + " Categories include Lifetime Gold, Bosses Defeated, Quests" + " Completed, Achievements, Prestige Count, Transcendence Count, and" + " Apotheosis Count. Click any player's row to view their character" + " sheet. You can opt out of appearing on leaderboards via the Privacy" + " section in your profile settings.", title: "🏆 Leaderboards", }, { body: "Log in every day to earn escalating rewards! Each consecutive day" + " awards more gold, and the 7th day of your streak grants bonus" + " crystals. Your streak resets if you miss a day. A week multiplier" + " increases all rewards the longer your overall streak runs. Your" + " current streak is displayed on your character sheet.", title: "đŸ”Ĩ Daily Login Bonus", }, { body: "Toggle automation in the Quests and Boss Encounters panels! Auto-Quest" + " automatically sends your party on the highest-zone available quest" + " as soon as one completes, skipping quests whose combat power" + " requirement isn't met. Auto-Boss automatically challenges the" + " highest available boss as soon as one is ready. Both can be toggled" + " on or off at any time using the 🤖 Auto button in each panel" + " header.", title: "🤖 Auto-Quest & Auto-Boss", }, { body: "Unlock companions by reaching certain milestones across all your runs." + " Each companion provides a powerful permanent bonus: increased" + " passive gold, click gold, boss damage, essence income, or reduced" + " quest time. You can only have one companion active at a time —" + " choose wisely based on your current strategy! Companions are" + " unlocked permanently once their condition is met and will never be" + " lost.", title: "đŸ‘Ĩ Companions", }, { body: "Your progress is automatically saved to the cloud every 30 seconds" + " whilst you play. You can also force a manual save at any time using" + " the sync button in the resource bar. Your save is protected by HMAC" + " validation to ensure data integrity.", title: "â˜ī¸ Cloud Saves", }, { body: "Transcendence is the ultimate prestige layer, unlocked by defeating" + " The Absolute One (requires Prestige 90). Transcending performs a" + " nuclear reset — wiping resources, prestige, runestones, upgrades," + " and equipment — but grants Echoes based on your prestige count" + " (fewer prestiges = more Echoes). Echoes are permanent and survive" + " all future resets. Spend them in the Echo Shop on lasting" + " multipliers: passive income, combat power, prestige" + " quality-of-life, and Echo meta upgrades that amplify future Echo" + " yields.", title: "🌌 Transcendence", }, { body: "Apotheosis is the final act — a complete dissolution of everything you" + " have built, including your prestige and transcendence progress. It" + " is unlocked once you have purchased every Transcendence upgrade. In" + " exchange for this total reset, you receive the Apotheosis badge:" + " pure bragging rights, a mark of reaching the absolute pinnacle of" + " the game. Apotheosis can be achieved multiple times; each cycle" + " requires purchasing all Transcendence upgrades again. Your Codex" + " entries and lifetime profile statistics are always preserved.", title: "✨ Apotheosis", }, { body: "The Story tab contains 22 chapters that unlock as you progress. The" + " first 18 unlock when you defeat the final boss of each zone." + " Chapters 19 and 20 unlock after your first and fifth prestige" + " respectively. Chapter 21 unlocks on your first transcendence, and" + " Chapter 22 on your first apotheosis. Each chapter presents a" + " narrative moment and three choices — the choice you make is recorded" + " on your Character Sheet and shapes your guild's story. Story" + " progress is permanent and survives all resets.", title: "📖 Story", }, ]; const formatDate = (dateString: string): string => { return new Date(dateString).toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric", }); }; /** * Renders the about panel with changelog and how-to-play sections. * @returns The JSX element. */ const aboutPanel = (): JSX.Element => { const [ about, setAbout ] = useState(null); const [ error, setError ] = useState(null); const [ expandedRelease, setExpandedRelease ] = useState(null); useEffect(() => { getAbout(). then(setAbout). catch((caughtError: unknown) => { setError( caughtError instanceof Error ? caughtError.message : "Failed to load about data.", ); }); }, []); return (

{"â„šī¸ About"}

{"📋 Changelog"}

{error !== null &&

{error}

} {about === null && error === null &&

{"Loading changelog..."}

} {about !== null && about.releases.length === 0 &&

{"No releases yet."}

} {about !== null && about.releases.length > 0 &&
    {about.releases.map((release) => { function handleToggle(): void { setExpandedRelease( expandedRelease === release.tag_name ? null : release.tag_name, ); } return (
  • {expandedRelease === release.tag_name &&
    {release.body}
    }
  • ); })}
}

{"📖 How to Play"}

    {howToPlay.map((section) => { return (
  • {section.title}

    {section.body}

  • ); })}
); }; export { aboutPanel as AboutPanel };