44 lines
1.6 KiB
JavaScript
44 lines
1.6 KiB
JavaScript
"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);
|