"use strict"; // Layer: simulation/system-effects // Owns frame updates for transient visual/effect entities. (function (global) { function updateEffect(effect, dt, frameId = 0, runScale = 1) { if (!effect || effect.dead) return false; const runDt = Math.min(0.24, Math.max(0, dt * Math.max(1, Number(runScale) || 1))); effect._effectUpdatedFrame = frameId; effect.update(runDt); return true; } function updateEffects(worldRef, dt) { const effects = worldRef.effects || []; const total = effects.length; const frameId = (worldRef._effectUpdateFrameId || 0) + 1; worldRef._effectUpdateFrameId = frameId; if (total <= 56) { for (const ef of effects) updateEffect(ef, dt, frameId, 1); worldRef._effectUpdateStats = { total, updated: total, skipped: 0, batched: false }; return; } const budget = Math.max(40, Math.ceil(total * 0.42)); const runScale = Math.min(3.0, Math.max(1, total / Math.max(1, budget))); let cursor = Math.max(0, Math.floor(worldRef._effectUpdateCursor || 0)) % total; let updated = 0; let scanned = 0; while (updated < budget && scanned < total) { const ef = effects[cursor]; cursor = (cursor + 1) % total; scanned += 1; if (!ef || ef.dead) continue; updateEffect(ef, dt, frameId, runScale); updated += 1; } worldRef._effectUpdateCursor = cursor; worldRef._effectUpdateStats = { total, updated, skipped: Math.max(0, total - updated), batched: true }; } global.TarinaiEffectsSimulationSystem = Object.freeze({ phases: Object.freeze({ updateEffects }), }); })(typeof window !== "undefined" ? window : globalThis);