import { describe, expect, it } from "vitest"; import { MOB_ANIMATION_FAR_INTERVAL, MOB_ANIMATION_MEDIUM_INTERVAL, advanceMobAnimationCadence, createMobAnimationCadenceState, resolveMobAnimationInterval, } from "./mobAnimationCadence"; describe("mob animation cadence", () => { it("keeps nearby and combat-critical actors at render rate", () => { expect(resolveMobAnimationInterval(true, false, 20 ** 2, false)).toBe(0); expect(resolveMobAnimationInterval(true, true, 90 ** 2, false)).toBe(0); }); it("uses 30 Hz and 15 Hz tiers for visible background actors", () => { expect(resolveMobAnimationInterval(true, false, 50 ** 2, true)) .toBe(MOB_ANIMATION_MEDIUM_INTERVAL); expect(resolveMobAnimationInterval(true, false, 90 ** 2, true)) .toBe(MOB_ANIMATION_FAR_INTERVAL); }); it("freezes inactive and safely offscreen background actors", () => { expect(resolveMobAnimationInterval(false, true, 10, true)).toBeNull(); expect(resolveMobAnimationInterval(true, false, 50 ** 2, false)).toBeNull(); }); it("accumulates elapsed time so throttled clips keep real-time speed", () => { const state = createMobAnimationCadenceState(); expect(advanceMobAnimationCadence(state, 1 / 60, 1 / 30)).toBe(0); expect(advanceMobAnimationCadence(state, 1 / 60, 1 / 30)).toBeCloseTo(1 / 30); expect(state.accumulatedDelta).toBe(0); }); it("drops frozen time and caps individual frame gaps", () => { const state = createMobAnimationCadenceState(); expect(advanceMobAnimationCadence(state, 1 / 60, 1 / 15)).toBe(0); expect(advanceMobAnimationCadence(state, 5, null)).toBe(0); expect(state.accumulatedDelta).toBe(0); expect(advanceMobAnimationCadence(state, 5, 0)).toBe(0.05); }); });