2026-05-14 20:15:23 +09:00
const elementIds = [
"world" , "toggleRun" , "stepOnce" , "resetWorld" ,
"speed" , "agentCount" , "worldSize" , "viewMode" , "year" , "activeGroups" , "urbanPopulation" ,
"ethnicities" , "cities" , "polities" , "wars" , "routes" , "farmingKnowledge" , "metallurgyKnowledge" ,
"deaths" , "frameCost" , "ethnicityList" , "legend" , "tooltip" , "stateGraph" , "historyRange" ,
"historyFilter" , "historySort" , "historyMetric" , "toggleActiveStates" , "togglePastStates" ,
"stateGraphInfo" , "stateGraphTooltip"
] ;
const els = Object . fromEntries ( elementIds . map ( id => [ id === "world" ? "canvas" : id , document . getElementById ( id ) ] ) ) ;
els . sim = document . querySelector ( ".sim" ) ;
const ctx = els . canvas . getContext ( "2d" , { alpha : false } ) ;
let sim ;
let running = true ;
let lastStatsAt = 0 ;
let lastGraphRenderAt = 0 ;
let lastRenderAt = 0 ;
let lastSimTickAt = 0 ;
let renderDirty = true ;
let loopTimer = null ;
let loopScheduled = false ;
let hoverState = null ;
let renderImage = null ;
let renderImageSize = 0 ;
const LoopConfig = Object . freeze ( {
simTickMs : 33 ,
renderMs : 66 ,
stepBudgetMs : 4.5 ,
idlePollMs : 180 ,
hiddenPollMs : 1000
} ) ;
const graphState = {
filter : "all" ,
sort : "oldest" ,
metric : "power" ,
showActive : true ,
showPast : true ,
hoverPolityId : null ,
rows : [ ] ,
markers : [ ] ,
scale : null
} ;
const legendByMode = {
terrain : ( ) => terrainInfo . map ( t => ` <span><i style="background: rgb( ${ t . color . join ( "," ) } )"></i> ${ t . name } </span> ` ) . join ( "" ) ,
2026-05-17 21:08:03 +09:00
ethnicity : ( ) => "<span>Color = tile-level dominant ethnicity. Stronger color marks higher local population; mixed areas are muted.</span>" ,
2026-05-14 20:15:23 +09:00
pressure : ( ) => "<span><i style=\"background:#d24943\"></i>High local population pressure</span>" ,
2026-05-17 21:08:03 +09:00
polities : ( ) => "<span>Color = territorial state control. Brighter areas are stronger control; pale borders mark frontiers; contested areas are unstable.</span>" ,
2026-05-14 20:15:23 +09:00
technology : ( ) => "<span><i style=\"background:#5fab5b\"></i>Farming knowledge</span><span><i style=\"background:#caa966\"></i>Metallurgy knowledge</span>" ,
pheromone : ( ) => "<span><i style=\"background:#d8b156\"></i>Pheromone strength</span><span><i style=\"background:#ffd75a\"></i>Formal trade routes</span>" ,
resources : ( ) => "<span><i style=\"background:#6bbc55\"></i>Regenerating local resource stock</span>"
} ;