generated from nhcarrigan/template
feat: initial prototype — core game systems (#30)
## Summary This PR represents the full v1 prototype, implementing the core game systems for Elysium. - Full idle/clicker RPG loop: resource collection, crafting, boss fights, exploration, and quests - Adventurer hiring with batch size selector and progressive tier cost scaling - Prestige, transcendence, and apotheosis systems with auto-prestige support - Character sheet, titles, leaderboards, companion system, and daily login bonuses - Auto-quest and auto-boss toggles - Discord webhook notifications on prestige/transcendence/apotheosis - Discord role awarded on apotheosis - Responsive design and overarching story/lore system - In-game sound effects and browser notifications for key events - Support link button in the resource bar - Full test coverage (100% on `apps/api` and `packages/types`) - CI pipeline: lint → build → test ## Closes Closes #1 Closes #2 Closes #3 Closes #4 Closes #5 Closes #6 Closes #7 Closes #8 Closes #9 Closes #10 Closes #11 Closes #12 Closes #13 Closes #14 Closes #16 Closes #19 Closes #20 Closes #21 Closes #22 Closes #23 Closes #24 Closes #25 Closes #26 Closes #27 Closes #29 ✨ This issue was created with help from Hikari~ 🌸 Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com> Reviewed-on: #30 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #30.
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file Initial game state data.
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
import { defaultAchievements } from "./achievements.js";
|
||||
import { defaultAdventurers } from "./adventurers.js";
|
||||
import { defaultBosses } from "./bosses.js";
|
||||
import { defaultEquipment } from "./equipment.js";
|
||||
import { defaultExplorations } from "./explorations.js";
|
||||
import { defaultQuests } from "./quests.js";
|
||||
import { currentSchemaVersion } from "./schemaVersion.js";
|
||||
import { defaultUpgrades } from "./upgrades.js";
|
||||
import { defaultZones } from "./zones.js";
|
||||
import type {
|
||||
ApotheosisData,
|
||||
ExplorationState,
|
||||
GameState,
|
||||
Player,
|
||||
PrestigeData,
|
||||
TranscendenceData,
|
||||
} from "@elysium/types";
|
||||
|
||||
const initialPrestige: PrestigeData = {
|
||||
count: 0,
|
||||
productionMultiplier: 1,
|
||||
purchasedUpgradeIds: [],
|
||||
runestones: 0,
|
||||
};
|
||||
|
||||
const initialTranscendence: TranscendenceData = {
|
||||
count: 0,
|
||||
echoCombatMultiplier: 1,
|
||||
echoIncomeMultiplier: 1,
|
||||
echoMetaMultiplier: 1,
|
||||
echoPrestigeRunestoneMultiplier: 1,
|
||||
echoPrestigeThresholdMultiplier: 1,
|
||||
echoes: 0,
|
||||
purchasedUpgradeIds: [],
|
||||
};
|
||||
|
||||
const initialApotheosis: ApotheosisData = {
|
||||
count: 0,
|
||||
};
|
||||
|
||||
const initialExploration: ExplorationState = {
|
||||
areas: defaultExplorations.map((area) => {
|
||||
return {
|
||||
id: area.id,
|
||||
status:
|
||||
area.zoneId === "verdant_vale"
|
||||
? ("available" as const)
|
||||
: ("locked" as const),
|
||||
};
|
||||
}),
|
||||
craftedClickMultiplier: 1,
|
||||
craftedCombatMultiplier: 1,
|
||||
craftedEssenceMultiplier: 1,
|
||||
craftedGoldMultiplier: 1,
|
||||
craftedRecipeIds: [],
|
||||
materials: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds an initial game state for a new player.
|
||||
* @param player - The player data from Discord OAuth.
|
||||
* @param characterName - The character name chosen by the player.
|
||||
* @returns A fresh GameState object.
|
||||
*/
|
||||
const initialGameState = (
|
||||
player: Player,
|
||||
characterName: string,
|
||||
): GameState => {
|
||||
return {
|
||||
achievements: structuredClone(defaultAchievements),
|
||||
adventurers: structuredClone(defaultAdventurers),
|
||||
apotheosis: { ...initialApotheosis },
|
||||
baseClickPower: 1,
|
||||
bosses: structuredClone(defaultBosses),
|
||||
companions: { activeCompanionId: null, unlockedCompanionIds: [] },
|
||||
equipment: structuredClone(defaultEquipment),
|
||||
exploration: structuredClone(initialExploration),
|
||||
lastTickAt: Date.now(),
|
||||
player: {
|
||||
...player,
|
||||
characterName: characterName,
|
||||
totalClicks: 0,
|
||||
totalGoldEarned: 0,
|
||||
},
|
||||
prestige: initialPrestige,
|
||||
quests: structuredClone(defaultQuests),
|
||||
resources: {
|
||||
crystals: 0,
|
||||
essence: 0,
|
||||
gold: 0,
|
||||
runestones: 0,
|
||||
},
|
||||
schemaVersion: currentSchemaVersion,
|
||||
transcendence: { ...initialTranscendence },
|
||||
upgrades: structuredClone(defaultUpgrades),
|
||||
zones: structuredClone(defaultZones),
|
||||
};
|
||||
};
|
||||
|
||||
export { initialExploration, initialGameState };
|
||||
Reference in New Issue
Block a user