45 lines
1.9 KiB
TypeScript
45 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { useGameStore } from "./store";
|
|
|
|
describe("runtime performance budgets", () => {
|
|
it.each([
|
|
{ label: "dual-boss", bossIds: ["emberfox", "sandglass-scorpion"] as const, maxElapsedMs: 3_500 },
|
|
{ label: "Rogue Trials trio", bossIds: ["emberfox", "sandglass-scorpion", "tempestscale-dragon"] as const, maxElapsedMs: 5_000 },
|
|
])("keeps ten minutes of $label simulation bounded", ({ bossIds, maxElapsedMs }) => {
|
|
const store = useGameStore.getState();
|
|
store.configureHealer("priest", "Perf", [], bossIds);
|
|
store.startEncounter();
|
|
useGameStore.setState((state) => ({
|
|
boss: { ...state.boss, hp: 1_000_000_000, maxHp: 1_000_000_000 },
|
|
additionalBosses: state.additionalBosses.map((entry) => ({
|
|
...entry,
|
|
boss: { ...entry.boss, hp: 1_000_000_000, maxHp: 1_000_000_000 },
|
|
})),
|
|
party: state.party.map((member) => ({ ...member, absorb: 1_000_000_000 })),
|
|
}));
|
|
|
|
let maxHazards = 0;
|
|
let maxDamageEvents = 0;
|
|
let maxCombatLog = 0;
|
|
const startedAt = performance.now();
|
|
for (let step = 0; step < 6_000; step += 1) {
|
|
useGameStore.getState().tick(0.1);
|
|
const state = useGameStore.getState();
|
|
const hazards = state.bossMotion.hazards.length
|
|
+ state.additionalBosses.reduce((sum, entry) => sum + entry.motion.hazards.length, 0);
|
|
maxHazards = Math.max(maxHazards, hazards);
|
|
maxDamageEvents = Math.max(maxDamageEvents, state.partyDamageEvents.length);
|
|
maxCombatLog = Math.max(maxCombatLog, state.combatLog.length);
|
|
}
|
|
const elapsedMs = performance.now() - startedAt;
|
|
const result = useGameStore.getState();
|
|
|
|
expect(result.phase).toBe("combat");
|
|
expect(result.time).toBeCloseTo(600, 5);
|
|
expect(maxHazards).toBeLessThanOrEqual(64);
|
|
expect(maxDamageEvents).toBeLessThanOrEqual(24);
|
|
expect(maxCombatLog).toBeLessThanOrEqual(12);
|
|
expect(elapsedMs).toBeLessThan(maxElapsedMs);
|
|
});
|
|
});
|