"use strict"; const assert = require("assert"); const fs = require("fs"); const path = require("path"); const ROOT = path.resolve(__dirname, ".."); const read = rel => fs.readFileSync(path.join(ROOT, rel), "utf8"); const creatureSource = read("js/simulation_creature_system.js"); assert(creatureSource.includes("_creatureScheduledWorkCursor"), "rotating scheduled-work cursor is missing"); assert(creatureSource.includes("creatureCount >= 80"), "high-population guard for rotating AI work is missing"); assert(creatureSource.includes("perfProfile.aiBudget"), "AI budget is not used as the low-overhead rotation step"); assert(!creatureSource.includes("sortScheduledAi"), "AI spreading introduced an unnecessary sort queue"); console.log("[OK] high-cost creature work uses a rotating, queue-free budget order"); const renderSource = read("js/render.js"); assert(renderSource.includes("creatureSortRect = visibleWorldRect(world, 72)"), "narrow creature depth-sort rectangle is missing"); assert(renderSource.includes("nearbyRectInto(worldRef.spatial.tarinaiCells, creatureSortRect"), "Tarinai sort candidates are not limited before sorting"); assert(renderSource.includes("nearbyRectInto(worldRef.spatial.antCells, creatureSortRect"), "ant sort candidates are not limited before sorting"); assert(renderSource.includes("collectVisibleRenderStack(world, visibleRect, creatureSortRect)"), "render stack does not receive the narrowed creature sort rectangle"); console.log("[OK] creature depth sorting is limited to near-viewport candidates before list insertion"); const relationSource = read("js/tarinai_identity_social.js"); assert(relationSource.includes("lazyDropDeadRelationPeer"), "lazy dead relationship deletion helper is missing"); assert(relationSource.includes("pruneDeadRelationshipRefs(deadIds)"), "dead-ID batch relationship cleanup is missing"); assert(!/entry\.ownCount\s*=\s*Math\.max\(entry\.ownCount,\s*Object\.keys\(this\.relationships\)\.length\)/.test(relationSource), "relation insertion still enumerates all relationship keys"); console.log("[OK] dead relationship references are lazily removed without per-insert full key enumeration"); class World {} global.World = World; global.TarinaiHistory = { trimMemory() { return 0; } }; require(path.join(ROOT, "js/world_spatial_budget.js")); const world = new World(); world.time = 100; const aliveA = { id: "A", dead: false, relationships: { D1: { affinity: 1 }, C: { affinity: 2 } }, relationCache: { stale: true } }; const aliveC = { id: "C", dead: false, relationships: { A: { affinity: 2 }, X: { affinity: 9 } }, relationCache: { stale: true } }; world.tarinai = [aliveA, aliveC]; world.liveTarinai = new Map([["A", { target: aliveA }], ["C", { target: aliveC }]]); world._deadTarinaiIdsPendingCleanup = new Set(["D1"]); world.tarinaiCollisionMemo = new Map(); world.relationNotices = {}; world.fightPairCooldowns = {}; world.resolvedFightIds = {}; world.queueTarinaiRuntimeCachePrune("audit", { resetRelationPeerCaches: true }); assert(world._tarinaiRuntimePruneJob, "threshold cleanup job was not queued"); world.processTarinaiRuntimeCachePruneStep(1); assert(world._tarinaiRuntimePruneJob, "threshold cleanup was not split across frames"); while (world._tarinaiRuntimePruneJob) world.processTarinaiRuntimeCachePruneStep(1); assert(!Object.prototype.hasOwnProperty.call(aliveA.relationships, "D1"), "known dead relationship was not removed"); assert(Object.prototype.hasOwnProperty.call(aliveA.relationships, "C"), "live relationship was incorrectly removed"); assert(Object.prototype.hasOwnProperty.call(aliveC.relationships, "X"), "unrelated stale reference was scanned/removed by targeted cleanup"); assert.strictEqual(world._deadTarinaiIdsPendingCleanup.size, 0, "processed dead-ID set was not released after chunked cleanup"); console.log("[OK] threshold cleanup is split across frames and removes only queued dead IDs"); const deathSource = read("js/tarinai_social_move_life.js"); assert(deathSource.includes("noteTarinaiDeathForRuntimeCleanup?.(this.id)"), "death hook does not queue the dead Tarinai ID"); console.log("Performance 5-7 regression audit passed.");