Update 3D game 2026-07-10 21:20

This commit is contained in:
Warren H
2026-07-10 21:20:17 -04:00
parent 141ec64963
commit e0be0458aa
720 changed files with 366857 additions and 0 deletions
+125
View File
@@ -0,0 +1,125 @@
import type { BossCollection, GameModeId, GameSettings, HunterSave, SaveSlotId } from "./types";
import { BOSS_ORDER } from "../game/bossCatalog";
import { createClassInventory } from "../game/healers";
import type { BossId } from "../game/types";
export const DEFAULT_SETTINGS: GameSettings = {
masterVolume: 80,
reducedMotion: false,
damageNumbers: true,
largeText: false,
};
export const DEFAULT_COLLECTIONS: BossCollection[] = [
{
bossId: "bulldrome",
bossName: "Bulldrome",
defeated: true,
drops: [
{ id: "bull-horn", name: "Cinder Horn", icon: "♜", rarity: "Common", count: 7 },
{ id: "bull-hide", name: "Ember Hide", icon: "▧", rarity: "Uncommon", count: 3 },
{ id: "bull-idol", name: "Vault Idol", icon: "◇", rarity: "Rare", count: 1 },
{ id: "bull-heart", name: "Furnace Heart", icon: "✦", rarity: "Mythic", count: 0 },
],
},
{
bossId: "vexa",
bossName: "Vexa",
defeated: false,
drops: [
{ id: "vexa-silk", name: "Living Silk", icon: "⌁", rarity: "Common", count: 0 },
{ id: "vexa-venom", name: "Widow Venom", icon: "✣", rarity: "Uncommon", count: 0 },
{ id: "vexa-eye", name: "Loom Eye", icon: "◉", rarity: "Rare", count: 0 },
{ id: "vexa-heart", name: "Webmother Heart", icon: "✦", rarity: "Mythic", count: 0 },
],
},
{
bossId: "cindermaw",
bossName: "Cindermaw",
defeated: true,
drops: [
{ id: "maw-scale", name: "Soot Scale", icon: "◈", rarity: "Common", count: 4 },
{ id: "maw-gland", name: "Mending Gland", icon: "+", rarity: "Uncommon", count: 2 },
{ id: "maw-crest", name: "Ashen Crest", icon: "⌁", rarity: "Rare", count: 0 },
{ id: "maw-breath", name: "Bottled Breath", icon: "☀", rarity: "Mythic", count: 0 },
],
},
];
export const MODE_COPY: Record<GameModeId, { eyebrow: string; title: string; description: string; detail: string; status: string }> = {
"roguelike-pve": {
eyebrow: "14 hunters · randomized PVE",
title: "PVE",
description: "Enter without an encounter briefing, adapt to two randomized guardians, and build toward a full roguelike run.",
detail: "Two bosses selected when the run begins",
status: "Playable prototype",
},
dungeons: {
eyebrow: "14 hunters · chosen encounter",
title: "Dungeons",
description: "Choose a guardian, review its mechanics, and bring a prepared healing loadout into a focused encounter.",
detail: "Bulldrome · Vexa · Cindermaw",
status: "Playable now",
},
"roguelike-pvp": {
eyebrow: "3v3 · mirrored expeditions",
title: "Roguelike PvP",
description: "Race a rival squad through shifting rooms. Send hazards across the veil while keeping your own formation alive.",
detail: "Draft order, rival pressure, and sudden-death rules",
status: "Mode shell ready",
},
"stadium-pvp": {
eyebrow: "5v5 · objective arena",
title: "Stadium PvP",
description: "Bring a prepared loadout into short team battles where positioning, interrupts, and clutch healing decide the round.",
detail: "Best of five rounds / normalized gear",
status: "Mode shell ready",
},
};
export function selectRandomBoss(random: () => number = Math.random): BossId {
return BOSS_ORDER[Math.floor(random() * BOSS_ORDER.length)] ?? BOSS_ORDER[0];
}
export function selectRandomBossPair(random: () => number = Math.random): readonly [BossId, BossId] {
const firstIndex = Math.floor(random() * BOSS_ORDER.length) % BOSS_ORDER.length;
const secondOffset = 1 + Math.floor(random() * (BOSS_ORDER.length - 1));
return [BOSS_ORDER[firstIndex], BOSS_ORDER[(firstIndex + secondOffset) % BOSS_ORDER.length]];
}
export const MAX_HUNTER_NAME_LENGTH = 20;
export function normalizeHunterName(value: string): string {
return value
.replace(/[\u0000-\u001f\u007f]/g, "")
.replace(/\s+/g, " ")
.trim()
.slice(0, MAX_HUNTER_NAME_LENGTH);
}
export function createHunterSave(slotId: SaveSlotId, now: string, hunterName: string): HunterSave {
const normalizedName = normalizeHunterName(hunterName);
if (!normalizedName) throw new Error("Hunter name is required.");
return {
schemaVersion: 2,
slotId,
hunterName: normalizedName,
activeClassId: "priest",
healers: {
priest: { level: 12, inventory: createClassInventory("priest") },
druid: { level: 1, inventory: createClassInventory("druid") },
shaman: { level: 1, inventory: createClassInventory("shaman") },
},
location: "Ember Vault Approach",
playSeconds: 8 * 60 * 60 + 42 * 60,
updatedAt: now,
stats: {
totalBossKills: 16,
flawlessClears: 5,
alliesSaved: 143,
healingDone: 284_650,
bossKills: { Bulldrome: 12, Vexa: 0, Cindermaw: 4 },
},
collections: structuredClone(DEFAULT_COLLECTIONS),
};
}