perf(simulation): Optimize worker thread logic for faster simulation updates

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-03-26 01:06:56 -07:00
parent b89f9b98e0
commit 1bc7fa9349

View file

@ -17,6 +17,7 @@ import {
applyVolcanicWinterForcing,
generate as generateMap,
ClimatePhysics,
EcologyPhysics,
GRID_WIDTH,
GRID_HEIGHT,
} from '@magic-civ/engine-ts'
@ -32,6 +33,7 @@ interface ScenarioState {
checkpoints: Map<number, GridState>
grid: GridState
physics: ClimatePhysics
ecology: EcologyPhysics | null
cursorScenarioTurn: number
totalScenarioTurns: number
worldSeed: number
@ -85,6 +87,7 @@ function stepOneTurn(state: ScenarioState, scenarioTurn: number): { stats: TurnS
const absTurn = state.config.worldAge + scenarioTurn
if (state.isVolcanicWinter) applyVolcanicWinterForcing(state.grid)
const events = state.physics.processStep(state.grid, absTurn, state.worldSeed)
if (state.ecology) state.ecology.processStep(state.grid)
const stats = computeTurnStats(state.grid)
state.cursorScenarioTurn = scenarioTurn + 1
return { stats, events }
@ -114,6 +117,7 @@ function seekToTurn(state: ScenarioState, targetSt: number): void {
const absTurn = state.config.worldAge + st
if (state.isVolcanicWinter) applyVolcanicWinterForcing(state.grid)
state.physics.processStep(state.grid, absTurn, state.worldSeed)
if (state.ecology) state.ecology.processStep(state.grid)
}
state.cursorScenarioTurn = targetSt
return
@ -141,6 +145,7 @@ function seekToTurn(state: ScenarioState, targetSt: number): void {
const absTurn = state.config.worldAge + st
if (state.isVolcanicWinter) applyVolcanicWinterForcing(state.grid)
state.physics.processStep(state.grid, absTurn, state.worldSeed)
if (state.ecology) state.ecology.processStep(state.grid)
}
state.cursorScenarioTurn = targetSt
}
@ -163,6 +168,7 @@ async function prebufferFrames(state: ScenarioState, scenarioId: string, frameCo
const tmpGrid = cloneGridState(cp0)
const tmpPhysics = new ClimatePhysics(climateParams, terrainCache)
const tmpEcology = new EcologyPhysics()
for (let batchStart = 0; batchStart < count; batchStart += PREBUFFER_BATCH) {
if (cancelFlags.get(scenarioId)) break
@ -176,6 +182,7 @@ async function prebufferFrames(state: ScenarioState, scenarioId: string, frameCo
const absTurn = state.config.worldAge + st
if (state.isVolcanicWinter) applyVolcanicWinterForcing(tmpGrid)
tmpPhysics.processStep(tmpGrid, absTurn, state.worldSeed)
tmpEcology.processStep(tmpGrid)
}
const snap = encodeSnapshot(tmpGrid, st)
@ -244,11 +251,13 @@ async function handleRun(scenarioId: string, turns: number, prebufferFrameCount:
// Generate map from seed using transpiled GDScript pipeline
const grid = generateMap(WORLD_SEED, GRID_WIDTH, GRID_HEIGHT, terrainCache, climateParams, 'continents')
const physics = new ClimatePhysics(climateParams, terrainCache)
const ecology = new EcologyPhysics()
// Phase 1: Geological history
// Phase 1: Geological history (climate + ecology)
for (let turn = 0; turn < worldAge; turn++) {
if (cancelFlags.get(scenarioId)) return
physics.processStep(grid, turn, WORLD_SEED)
ecology.processStep(grid)
if (turn % CHUNK_SIZE === 0) {
post({ type: 'progress', scenarioId, turn, total: totalAbsTurns, phase: 'geology' })
@ -264,6 +273,7 @@ async function handleRun(scenarioId: string, turns: number, prebufferFrameCount:
// Phase 3: Scenario simulation
const state: ScenarioState = {
config, grid, physics,
ecology,
stats: [], events: [],
checkpoints: new Map(),
cursorScenarioTurn: 0,
@ -361,6 +371,7 @@ function handleFrame(scenarioId: string, turn: number, lookahead: number): void
// Encode frames from a temporary grid copy so we don't pollute the cursor
const tmpGrid = cloneGridState(state.grid)
const tmpPhysics = new ClimatePhysics(climateParams, terrainCache)
const tmpEcology = new EcologyPhysics()
const frames: FramePayload[] = []
const transferables: ArrayBuffer[] = []
@ -372,6 +383,7 @@ function handleFrame(scenarioId: string, turn: number, lookahead: number): void
const absTurn = state.config.worldAge + st
if (state.isVolcanicWinter) applyVolcanicWinterForcing(tmpGrid)
tmpPhysics.processStep(tmpGrid, absTurn, state.worldSeed)
tmpEcology.processStep(tmpGrid)
}
const snap = encodeSnapshot(tmpGrid, st)