@v12-engine/engine 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abilities/amounts.d.ts +28 -0
- package/dist/abilities/amounts.js +74 -0
- package/dist/abilities/amounts.js.map +1 -0
- package/dist/abilities/buffs.d.ts +106 -6
- package/dist/abilities/buffs.js +443 -0
- package/dist/abilities/buffs.js.map +1 -0
- package/dist/abilities/castTold.d.ts +2 -0
- package/dist/abilities/castTold.js +66 -0
- package/dist/abilities/castTold.js.map +1 -0
- package/dist/abilities/chance.d.ts +38 -0
- package/dist/abilities/chance.js +77 -0
- package/dist/abilities/chance.js.map +1 -0
- package/dist/abilities/charges.d.ts +18 -0
- package/dist/abilities/charges.js +101 -0
- package/dist/abilities/charges.js.map +1 -0
- package/dist/abilities/control.d.ts +28 -0
- package/dist/abilities/control.js +113 -0
- package/dist/abilities/control.js.map +1 -0
- package/dist/abilities/dispel.js +51 -0
- package/dist/abilities/dispel.js.map +1 -0
- package/dist/abilities/effectFields.d.ts +1 -1
- package/dist/abilities/effectFields.js +676 -0
- package/dist/abilities/effectFields.js.map +1 -0
- package/dist/abilities/effectIndex.d.ts +27 -0
- package/dist/abilities/effectIndex.js +64 -0
- package/dist/abilities/effectIndex.js.map +1 -0
- package/dist/abilities/effects/buff.d.ts +9 -3
- package/dist/abilities/effects/buff.js +84 -0
- package/dist/abilities/effects/buff.js.map +1 -0
- package/dist/abilities/effects/conditions.d.ts +2 -0
- package/dist/abilities/effects/conditions.js +41 -0
- package/dist/abilities/effects/conditions.js.map +1 -0
- package/dist/abilities/effects/core.js +54 -0
- package/dist/abilities/effects/core.js.map +1 -0
- package/dist/abilities/effects/damage.d.ts +1 -1
- package/dist/abilities/effects/damage.js +43 -0
- package/dist/abilities/effects/damage.js.map +1 -0
- package/dist/abilities/effects/heal.d.ts +2 -2
- package/dist/abilities/effects/heal.js +51 -0
- package/dist/abilities/effects/heal.js.map +1 -0
- package/dist/abilities/effects/missile.d.ts +13 -1
- package/dist/abilities/effects/missile.js +104 -0
- package/dist/abilities/effects/missile.js.map +1 -0
- package/dist/abilities/effects/morph.d.ts +5 -0
- package/dist/abilities/effects/morph.js +43 -0
- package/dist/abilities/effects/morph.js.map +1 -0
- package/dist/abilities/effects/moves.d.ts +16 -4
- package/dist/abilities/effects/moves.js +212 -0
- package/dist/abilities/effects/moves.js.map +1 -0
- package/dist/abilities/effects/passives.d.ts +19 -9
- package/dist/abilities/effects/passives.js +131 -0
- package/dist/abilities/effects/passives.js.map +1 -0
- package/dist/abilities/effects/proxy.d.ts +5 -0
- package/dist/abilities/effects/proxy.js +60 -0
- package/dist/abilities/effects/proxy.js.map +1 -0
- package/dist/abilities/effects/sight.d.ts +2 -2
- package/dist/abilities/effects/sight.js +39 -0
- package/dist/abilities/effects/sight.js.map +1 -0
- package/dist/abilities/effects/spawn.d.ts +5 -2
- package/dist/abilities/effects/spawn.js +40 -0
- package/dist/abilities/effects/spawn.js.map +1 -0
- package/dist/abilities/effects/timed.d.ts +2 -2
- package/dist/abilities/effects/timed.js +96 -0
- package/dist/abilities/effects/timed.js.map +1 -0
- package/dist/abilities/effects/trade.d.ts +1 -1
- package/dist/abilities/effects/trade.js +25 -0
- package/dist/abilities/effects/trade.js.map +1 -0
- package/dist/abilities/effects.d.ts +97 -23
- package/dist/abilities/effects.js +860 -0
- package/dist/abilities/effects.js.map +1 -0
- package/dist/abilities/land.d.ts +38 -4
- package/dist/abilities/land.js +189 -0
- package/dist/abilities/land.js.map +1 -0
- package/dist/abilities/recast.d.ts +45 -0
- package/dist/abilities/recast.js +118 -0
- package/dist/abilities/recast.js.map +1 -0
- package/dist/abilities/scaled.js +40 -0
- package/dist/abilities/scaled.js.map +1 -0
- package/dist/abilities/screen.d.ts +6 -0
- package/dist/abilities/screen.js +83 -0
- package/dist/abilities/screen.js.map +1 -0
- package/dist/abilities/shapes.d.ts +66 -0
- package/dist/abilities/shapes.js +122 -0
- package/dist/abilities/shapes.js.map +1 -0
- package/dist/abilities/text.d.ts +14 -2
- package/dist/abilities/text.js +204 -0
- package/dist/abilities/text.js.map +1 -0
- package/dist/abilities/triggers.d.ts +98 -0
- package/dist/abilities/triggers.js +351 -0
- package/dist/abilities/triggers.js.map +1 -0
- package/dist/abilityChanges.d.ts +131 -0
- package/dist/abilityChanges.js +345 -0
- package/dist/abilityChanges.js.map +1 -0
- package/dist/ai/area.d.ts +4 -1
- package/dist/ai/brain.d.ts +4 -1
- package/dist/ai/brain.js +844 -0
- package/dist/ai/brain.js.map +1 -0
- package/dist/ai/budget.js +74 -0
- package/dist/ai/budget.js.map +1 -0
- package/dist/ai/checks.d.ts +9 -1
- package/dist/ai/checks.js +242 -0
- package/dist/ai/checks.js.map +1 -0
- package/dist/ai/computer.d.ts +11 -4
- package/dist/ai/computer.js +251 -0
- package/dist/ai/computer.js.map +1 -0
- package/dist/ai/defence.d.ts +4 -0
- package/dist/ai/defence.js +430 -0
- package/dist/ai/defence.js.map +1 -0
- package/dist/ai/define.d.ts +3 -2
- package/dist/ai/define.js +31 -0
- package/dist/ai/define.js.map +1 -0
- package/dist/ai/economy.d.ts +10 -7
- package/dist/ai/economy.js +780 -0
- package/dist/ai/economy.js.map +1 -0
- package/dist/ai/geometry.js +38 -0
- package/dist/ai/geometry.js.map +1 -0
- package/dist/ai/goals.d.ts +1 -0
- package/dist/ai/goals.js +560 -0
- package/dist/ai/goals.js.map +1 -0
- package/dist/ai/knowledge.d.ts +72 -7
- package/dist/ai/knowledge.js +804 -0
- package/dist/ai/knowledge.js.map +1 -0
- package/dist/ai/lanes.d.ts +10 -2
- package/dist/ai/lanes.js +715 -0
- package/dist/ai/lanes.js.map +1 -0
- package/dist/ai/melee/build.js +264 -0
- package/dist/ai/melee/build.js.map +1 -0
- package/dist/ai/melee/goals.d.ts +7 -0
- package/dist/ai/melee/goals.js +720 -0
- package/dist/ai/melee/goals.js.map +1 -0
- package/dist/ai/melee/heroes.js +68 -0
- package/dist/ai/melee/heroes.js.map +1 -0
- package/dist/ai/melee/index.d.ts +1 -1
- package/dist/ai/melee/index.js +51 -0
- package/dist/ai/melee/index.js.map +1 -0
- package/dist/ai/melee/production.js +29 -0
- package/dist/ai/melee/production.js.map +1 -0
- package/dist/ai/melee/surrender.js +64 -0
- package/dist/ai/melee/surrender.js.map +1 -0
- package/dist/ai/micro.d.ts +9 -0
- package/dist/ai/micro.js +1316 -0
- package/dist/ai/micro.js.map +1 -0
- package/dist/ai/mission.d.ts +9 -2
- package/dist/ai/mission.js +538 -0
- package/dist/ai/mission.js.map +1 -0
- package/dist/ai/missionRules.d.ts +1 -1
- package/dist/ai/missionRules.js +26 -0
- package/dist/ai/missionRules.js.map +1 -0
- package/dist/ai/module.d.ts +6 -2
- package/dist/ai/module.js +37 -0
- package/dist/ai/module.js.map +1 -0
- package/dist/ai/options.d.ts +3 -3
- package/dist/ai/plans/build.d.ts +20 -1
- package/dist/ai/plans/build.js +608 -0
- package/dist/ai/plans/build.js.map +1 -0
- package/dist/ai/plans/placement.d.ts +4 -1
- package/dist/ai/plans/placement.js +295 -0
- package/dist/ai/plans/placement.js.map +1 -0
- package/dist/ai/plans/plans.d.ts +9 -0
- package/dist/ai/plans/plans.js +110 -0
- package/dist/ai/plans/plans.js.map +1 -0
- package/dist/ai/plans/production.d.ts +14 -2
- package/dist/ai/plans/production.js +434 -0
- package/dist/ai/plans/production.js.map +1 -0
- package/dist/ai/plans/purse.d.ts +6 -3
- package/dist/ai/plans/purse.js +139 -0
- package/dist/ai/plans/purse.js.map +1 -0
- package/dist/ai/plans/tech.d.ts +6 -0
- package/dist/ai/plans/tech.js +122 -0
- package/dist/ai/plans/tech.js.map +1 -0
- package/dist/ai/profiles.d.ts +4 -4
- package/dist/{profiles-B3NS9jwk.js → ai/profiles.js} +3 -98
- package/dist/ai/profiles.js.map +1 -0
- package/dist/ai/reach.js +54 -0
- package/dist/ai/reach.js.map +1 -0
- package/dist/ai/report.d.ts +8 -0
- package/dist/ai/report.js +87 -0
- package/dist/ai/report.js.map +1 -0
- package/dist/ai/roles.d.ts +4 -0
- package/dist/ai/roles.js +207 -0
- package/dist/ai/roles.js.map +1 -0
- package/dist/ai/rules.d.ts +8 -2
- package/dist/ai/rules.js +416 -0
- package/dist/ai/rules.js.map +1 -0
- package/dist/ai/scouting.d.ts +6 -0
- package/dist/ai/scouting.js +324 -0
- package/dist/ai/scouting.js.map +1 -0
- package/dist/ai/settings.js +99 -0
- package/dist/ai/settings.js.map +1 -0
- package/dist/ai/squads.d.ts +21 -2
- package/dist/ai/squads.js +916 -0
- package/dist/ai/squads.js.map +1 -0
- package/dist/ai/strength.js +320 -0
- package/dist/ai/strength.js.map +1 -0
- package/dist/ai/task.d.ts +3 -1
- package/dist/ai/task.js +17 -0
- package/dist/ai/task.js.map +1 -0
- package/dist/ai/tasks/attack.js +24 -0
- package/dist/ai/tasks/attack.js.map +1 -0
- package/dist/ai/tasks/capture.d.ts +3 -3
- package/dist/ai/tasks/capture.js +37 -0
- package/dist/ai/tasks/capture.js.map +1 -0
- package/dist/ai/tasks/creep.js +29 -0
- package/dist/ai/tasks/creep.js.map +1 -0
- package/dist/ai/tasks/defend.js +61 -0
- package/dist/ai/tasks/defend.js.map +1 -0
- package/dist/ai/tasks/drop.js +81 -0
- package/dist/ai/tasks/drop.js.map +1 -0
- package/dist/ai/tasks/escort.js +59 -0
- package/dist/ai/tasks/escort.js.map +1 -0
- package/dist/ai/tasks/gather.js +48 -0
- package/dist/ai/tasks/gather.js.map +1 -0
- package/dist/ai/tasks/harass.js +39 -0
- package/dist/ai/tasks/harass.js.map +1 -0
- package/dist/ai/tasks/hold.js +32 -0
- package/dist/ai/tasks/hold.js.map +1 -0
- package/dist/ai/tasks/index.js +34 -0
- package/dist/ai/tasks/index.js.map +1 -0
- package/dist/ai/tasks/move.js +26 -0
- package/dist/ai/tasks/move.js.map +1 -0
- package/dist/ai/tasks/patrol.js +59 -0
- package/dist/ai/tasks/patrol.js.map +1 -0
- package/dist/ai/tasks/retreat.js +28 -0
- package/dist/ai/tasks/retreat.js.map +1 -0
- package/dist/ai/tasks/scout.js +73 -0
- package/dist/ai/tasks/scout.js.map +1 -0
- package/dist/ai/tasks/shared.d.ts +1 -1
- package/dist/ai/tasks/shared.js +137 -0
- package/dist/ai/tasks/shared.js.map +1 -0
- package/dist/ai/team.d.ts +18 -1
- package/dist/ai/team.js +492 -0
- package/dist/ai/team.js.map +1 -0
- package/dist/ai/threat.d.ts +6 -0
- package/dist/ai/threat.js +206 -0
- package/dist/ai/threat.js.map +1 -0
- package/dist/ai/view.d.ts +21 -7
- package/dist/ai/view.js +677 -0
- package/dist/ai/view.js.map +1 -0
- package/dist/ai/waves.d.ts +6 -0
- package/dist/ai/waves.js +410 -0
- package/dist/ai/waves.js.map +1 -0
- package/dist/ai.js +54 -6239
- package/dist/aiTesting.d.ts +6 -3
- package/dist/aiTesting.js +229 -0
- package/dist/aiTesting.js.map +1 -0
- package/dist/areas.d.ts +4 -1
- package/dist/areas.js +295 -0
- package/dist/areas.js.map +1 -0
- package/dist/attacks.d.ts +3 -3
- package/dist/attacks.js +127 -0
- package/dist/attacks.js.map +1 -0
- package/dist/burning.d.ts +267 -0
- package/dist/burning.js +795 -0
- package/dist/burning.js.map +1 -0
- package/dist/bytes.js +21 -0
- package/dist/bytes.js.map +1 -0
- package/dist/callings.d.ts +71 -0
- package/dist/callings.js +157 -0
- package/dist/callings.js.map +1 -0
- package/dist/cameraOrders.d.ts +78 -0
- package/dist/cameraOrders.js +114 -0
- package/dist/cameraOrders.js.map +1 -0
- package/dist/camps.d.ts +70 -4
- package/dist/camps.js +501 -0
- package/dist/camps.js.map +1 -0
- package/dist/capture.d.ts +15 -3
- package/dist/capture.js +304 -0
- package/dist/capture.js.map +1 -0
- package/dist/cellLayers.d.ts +78 -13
- package/dist/cellLayers.js +275 -0
- package/dist/cellLayers.js.map +1 -0
- package/dist/cellPatches.d.ts +24 -0
- package/dist/cellPatches.js +73 -0
- package/dist/cellPatches.js.map +1 -0
- package/dist/cinematics.d.ts +10 -5
- package/dist/cinematics.js +161 -0
- package/dist/cinematics.js.map +1 -0
- package/dist/clock.d.ts +2 -2
- package/dist/clock.js +78 -0
- package/dist/clock.js.map +1 -0
- package/dist/commands.d.ts +36 -4
- package/dist/commands.js +636 -0
- package/dist/commands.js.map +1 -0
- package/dist/components.d.ts +31 -10
- package/dist/components.js +74 -0
- package/dist/components.js.map +1 -0
- package/dist/computers.d.ts +4 -4
- package/dist/computers.js +194 -0
- package/dist/computers.js.map +1 -0
- package/dist/concealment.d.ts +25 -2
- package/dist/concealment.js +409 -0
- package/dist/concealment.js.map +1 -0
- package/dist/coreComponents.js +130 -0
- package/dist/coreComponents.js.map +1 -0
- package/dist/createGame.d.ts +306 -0
- package/dist/createGame.js +405 -0
- package/dist/createGame.js.map +1 -0
- package/dist/dashing.d.ts +18 -2
- package/dist/dashing.js +41 -0
- package/dist/dashing.js.map +1 -0
- package/dist/debug.d.ts +8 -0
- package/dist/debug.js +5 -3
- package/dist/debug2.js +76 -0
- package/dist/debug2.js.map +1 -0
- package/dist/debugCommands.d.ts +6 -6
- package/dist/debugCommands.js +537 -0
- package/dist/debugCommands.js.map +1 -0
- package/dist/debugging.d.ts +1 -0
- package/dist/defaultSets.d.ts +183 -0
- package/dist/defaultSets.js +216 -0
- package/dist/defaultSets.js.map +1 -0
- package/dist/definitions.d.ts +6 -0
- package/dist/definitions.js +78 -0
- package/dist/definitions.js.map +1 -0
- package/dist/defs.d.ts +1895 -165
- package/dist/defs.js +380 -0
- package/dist/defs.js.map +1 -0
- package/dist/denying.d.ts +4 -4
- package/dist/denying.js +106 -0
- package/dist/denying.js.map +1 -0
- package/dist/destructibles.d.ts +2 -2
- package/dist/destructibles.js +36 -0
- package/dist/destructibles.js.map +1 -0
- package/dist/determinism.d.ts +4 -4
- package/dist/determinism.js +247 -0
- package/dist/determinism.js.map +1 -0
- package/dist/dialog.d.ts +17 -2
- package/dist/dialog.js +108 -0
- package/dist/dialog.js.map +1 -0
- package/dist/effectRefs.js +28 -0
- package/dist/effectRefs.js.map +1 -0
- package/dist/effects.d.ts +27 -11
- package/dist/effects.js +110 -0
- package/dist/effects.js.map +1 -0
- package/dist/endings.d.ts +1 -1
- package/dist/endings.js +78 -0
- package/dist/endings.js.map +1 -0
- package/dist/engagement.d.ts +40 -6
- package/dist/engagement.js +530 -0
- package/dist/engagement.js.map +1 -0
- package/dist/engineEvents.d.ts +72 -9
- package/dist/engineEvents.js +520 -0
- package/dist/engineEvents.js.map +1 -0
- package/dist/entity.d.ts +275 -26
- package/dist/entity.js +441 -0
- package/dist/entity.js.map +1 -0
- package/dist/entityIndex.d.ts +10 -3
- package/dist/entityIndex.js +149 -0
- package/dist/entityIndex.js.map +1 -0
- package/dist/errors.d.ts +6 -2
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +11 -5
- package/dist/events.js +158 -0
- package/dist/events.js.map +1 -0
- package/dist/exactMath.js +273 -0
- package/dist/exactMath.js.map +1 -0
- package/dist/features.d.ts +1 -1
- package/dist/features.js +127 -0
- package/dist/features.js.map +1 -0
- package/dist/fields.d.ts +25 -5
- package/dist/fields.js +140 -0
- package/dist/fields.js.map +1 -0
- package/dist/fixture.d.ts +3 -3
- package/dist/fixture.js +512 -0
- package/dist/fixture.js.map +1 -0
- package/dist/fog.d.ts +26 -3
- package/dist/fog.js +333 -0
- package/dist/fog.js.map +1 -0
- package/dist/foliage.d.ts +476 -0
- package/dist/foliage.js +1478 -0
- package/dist/foliage.js.map +1 -0
- package/dist/foliageDebug.d.ts +57 -0
- package/dist/foliageDebug.js +172 -0
- package/dist/foliageDebug.js.map +1 -0
- package/dist/foliageRegrowth.d.ts +20 -0
- package/dist/foliageRegrowth.js +332 -0
- package/dist/foliageRegrowth.js.map +1 -0
- package/dist/formState.d.ts +67 -0
- package/dist/formState.js +65 -0
- package/dist/formState.js.map +1 -0
- package/dist/formation.d.ts +46 -8
- package/dist/formation.js +297 -0
- package/dist/formation.js.map +1 -0
- package/dist/forms.d.ts +58 -0
- package/dist/forms.js +146 -0
- package/dist/forms.js.map +1 -0
- package/dist/friendlyFire.d.ts +2 -2
- package/dist/friendlyFire.js +37 -0
- package/dist/friendlyFire.js.map +1 -0
- package/dist/game.d.ts +141 -48
- package/dist/game.js +834 -0
- package/dist/game.js.map +1 -0
- package/dist/gameData.d.ts +96 -22
- package/dist/gameData.js +1690 -0
- package/dist/gameData.js.map +1 -0
- package/dist/gameFiles.d.ts +3 -3
- package/dist/gameFiles.js +14 -0
- package/dist/gameFiles.js.map +1 -0
- package/dist/gates.js +92 -0
- package/dist/gates.js.map +1 -0
- package/dist/generate.d.ts +28 -1
- package/dist/generate.js +1062 -0
- package/dist/generate.js.map +1 -0
- package/dist/generateWorker.d.ts +7 -3
- package/dist/generateWorker.js +86 -0
- package/dist/generateWorker.js.map +1 -0
- package/dist/grid.d.ts +9 -0
- package/dist/grid.js +102 -0
- package/dist/grid.js.map +1 -0
- package/dist/ground.d.ts +17 -1
- package/dist/ground.js +375 -0
- package/dist/ground.js.map +1 -0
- package/dist/groundObjects.d.ts +70 -0
- package/dist/groundObjects.js +371 -0
- package/dist/groundObjects.js.map +1 -0
- package/dist/groundSpeed.d.ts +20 -3
- package/dist/groundSpeed.js +117 -0
- package/dist/groundSpeed.js.map +1 -0
- package/dist/hero.d.ts +126 -10
- package/dist/hero.js +432 -0
- package/dist/hero.js.map +1 -0
- package/dist/holds.d.ts +94 -0
- package/dist/holds.js +305 -0
- package/dist/holds.js.map +1 -0
- package/dist/home.d.ts +1 -1
- package/dist/home.js +30 -0
- package/dist/home.js.map +1 -0
- package/dist/hooks.d.ts +339 -57
- package/dist/hooks.js +105 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hotReload.d.ts +6 -5
- package/dist/hotReload.js +145 -0
- package/dist/hotReload.js.map +1 -0
- package/dist/ids.d.ts +3 -3
- package/dist/ids.js +30 -0
- package/dist/ids.js.map +1 -0
- package/dist/idsFile.d.ts +36 -0
- package/dist/idsFile.js +134 -0
- package/dist/idsFile.js.map +1 -0
- package/dist/index.d.ts +105 -68
- package/dist/index.js +194 -4701
- package/dist/inspect.d.ts +29 -2
- package/dist/{inspect-D9dWHmZ0.js → inspect.js} +21 -12
- package/dist/inspect.js.map +1 -0
- package/dist/inventory.d.ts +14 -1
- package/dist/inventory.js +84 -0
- package/dist/inventory.js.map +1 -0
- package/dist/items.d.ts +136 -8
- package/dist/items.js +585 -0
- package/dist/items.js.map +1 -0
- package/dist/lanes.d.ts +12 -3
- package/dist/lanes.js +496 -0
- package/dist/lanes.js.map +1 -0
- package/dist/life.d.ts +6 -2
- package/dist/life.js +287 -0
- package/dist/life.js.map +1 -0
- package/dist/log.d.ts +26 -3
- package/dist/log.js +192 -0
- package/dist/log.js.map +1 -0
- package/dist/manaBurn.d.ts +2 -2
- package/dist/manaBurn.js +75 -0
- package/dist/manaBurn.js.map +1 -0
- package/dist/map/file.d.ts +56 -3
- package/dist/map/file.js +264 -0
- package/dist/map/file.js.map +1 -0
- package/dist/map/images.js +61 -0
- package/dist/map/images.js.map +1 -0
- package/dist/map/look.d.ts +1 -1
- package/dist/map/look.js +30 -0
- package/dist/map/look.js.map +1 -0
- package/dist/map/pathProfile.js +183 -0
- package/dist/map/pathProfile.js.map +1 -0
- package/dist/map/resize.d.ts +4 -0
- package/dist/map/resize.js +136 -0
- package/dist/map/resize.js.map +1 -0
- package/dist/map/schema.js +257 -0
- package/dist/map/schema.js.map +1 -0
- package/dist/map/terrain.js +214 -0
- package/dist/map/terrain.js.map +1 -0
- package/dist/map/types.d.ts +92 -13
- package/dist/map/types.js +251 -0
- package/dist/map/types.js.map +1 -0
- package/dist/mapCheck/cells.js +94 -0
- package/dist/mapCheck/cells.js.map +1 -0
- package/dist/mapCheck/rules/foliage.d.ts +9 -0
- package/dist/mapCheck/rules/foliage.js +83 -0
- package/dist/mapCheck/rules/foliage.js.map +1 -0
- package/dist/mapCheck/rules/names.js +39 -0
- package/dist/mapCheck/rules/names.js.map +1 -0
- package/dist/mapCheck/rules/objects.d.ts +1 -1
- package/dist/mapCheck/rules/objects.js +56 -0
- package/dist/mapCheck/rules/objects.js.map +1 -0
- package/dist/mapCheck/rules/paths.js +32 -0
- package/dist/mapCheck/rules/paths.js.map +1 -0
- package/dist/mapCheck/rules/players.js +20 -0
- package/dist/mapCheck/rules/players.js.map +1 -0
- package/dist/mapCheck/rules/races.js +56 -0
- package/dist/mapCheck/rules/races.js.map +1 -0
- package/dist/mapCheck/rules/random.js +47 -0
- package/dist/mapCheck/rules/random.js.map +1 -0
- package/dist/mapCheck/rules/regions.js +30 -0
- package/dist/mapCheck/rules/regions.js.map +1 -0
- package/dist/mapCheck/rules/targets.js +31 -0
- package/dist/mapCheck/rules/targets.js.map +1 -0
- package/dist/mapCheck/rules/walking.js +45 -0
- package/dist/mapCheck/rules/walking.js.map +1 -0
- package/dist/mapCheck.d.ts +2 -2
- package/dist/mapCheck.js +63 -0
- package/dist/mapCheck.js.map +1 -0
- package/dist/mapFields.d.ts +25 -2
- package/dist/mapFields.js +134 -0
- package/dist/mapFields.js.map +1 -0
- package/dist/mapFile.js +176 -0
- package/dist/mapFile.js.map +1 -0
- package/dist/mapMeasure.d.ts +8 -0
- package/dist/mapMeasure.js +283 -0
- package/dist/mapMeasure.js.map +1 -0
- package/dist/mapMerge.d.ts +1 -0
- package/dist/mapMerge.js +172 -0
- package/dist/mapMerge.js.map +1 -0
- package/dist/mapObjectives.js +138 -0
- package/dist/mapObjectives.js.map +1 -0
- package/dist/mapObjects.js +80 -0
- package/dist/mapObjects.js.map +1 -0
- package/dist/math.d.ts +37 -7
- package/dist/math.js +155 -0
- package/dist/math.js.map +1 -0
- package/dist/messages.d.ts +71 -4
- package/dist/messages.js +29 -0
- package/dist/messages.js.map +1 -0
- package/dist/missionRules.d.ts +10 -2
- package/dist/{missionRules-C-bGxm0Q.js → missionRules.js} +30 -150
- package/dist/missionRules.js.map +1 -0
- package/dist/mods.d.ts +39 -20
- package/dist/mods.js +271 -0
- package/dist/mods.js.map +1 -0
- package/dist/moves.d.ts +87 -0
- package/dist/moves.js +539 -0
- package/dist/moves.js.map +1 -0
- package/dist/names.d.ts +7 -0
- package/dist/names.js +122 -0
- package/dist/names.js.map +1 -0
- package/dist/navigation/agentParams.js +14 -0
- package/dist/navigation/agentParams.js.map +1 -0
- package/dist/navigation/air.d.ts +7 -3
- package/dist/navigation/air.js +401 -0
- package/dist/navigation/air.js.map +1 -0
- package/dist/navigation/builds.d.ts +34 -2
- package/dist/navigation/builds.js +287 -0
- package/dist/navigation/builds.js.map +1 -0
- package/dist/navigation/groundAreas.d.ts +59 -1
- package/dist/navigation/groundAreas.js +407 -0
- package/dist/navigation/groundAreas.js.map +1 -0
- package/dist/navigation/navigation.d.ts +98 -9
- package/dist/navigation/recast.d.ts +194 -18
- package/dist/navigation/recast.js +1379 -0
- package/dist/navigation/recast.js.map +1 -0
- package/dist/navigation/sidePaths.d.ts +8 -3
- package/dist/navigation/sidePaths.js +241 -0
- package/dist/navigation/sidePaths.js.map +1 -0
- package/dist/navigation/sized.js +243 -0
- package/dist/navigation/sized.js.map +1 -0
- package/dist/nearest.js +32 -0
- package/dist/nearest.js.map +1 -0
- package/dist/noise.js +59 -0
- package/dist/noise.js.map +1 -0
- package/dist/objectives.d.ts +12 -3
- package/dist/objectives.js +144 -0
- package/dist/objectives.js.map +1 -0
- package/dist/orders/basic.d.ts +5 -5
- package/dist/orders/basic.js +417 -0
- package/dist/orders/basic.js.map +1 -0
- package/dist/orders/build.js +278 -0
- package/dist/orders/build.js.map +1 -0
- package/dist/orders/cast.d.ts +13 -3
- package/dist/orders/cast.js +558 -0
- package/dist/orders/cast.js.map +1 -0
- package/dist/orders/facts.js +16 -0
- package/dist/orders/facts.js.map +1 -0
- package/dist/orders/harvest.d.ts +21 -5
- package/dist/orders/harvest.js +540 -0
- package/dist/orders/harvest.js.map +1 -0
- package/dist/orders/idle.d.ts +3 -1
- package/dist/orders/idle.js +234 -0
- package/dist/orders/idle.js.map +1 -0
- package/dist/orders/items.js +92 -0
- package/dist/orders/items.js.map +1 -0
- package/dist/orders/queue.js +108 -0
- package/dist/orders/queue.js.map +1 -0
- package/dist/orders/waiting.d.ts +39 -0
- package/dist/orders/waiting.js +149 -0
- package/dist/orders/waiting.js.map +1 -0
- package/dist/pack.schema.js +13 -0
- package/dist/pack.schema.js.map +1 -0
- package/dist/pack.schema.json +7622 -841
- package/dist/packs/director/index.d.ts +13 -5
- package/dist/packs/director/index.js +204 -0
- package/dist/packs/director/index.js.map +1 -0
- package/dist/packs/heroes/campaign.d.ts +3 -2
- package/dist/packs/heroes/campaign.js +241 -0
- package/dist/packs/heroes/campaign.js.map +1 -0
- package/dist/packs/heroes/carry.d.ts +6 -0
- package/dist/packs/heroes/carry.js +112 -0
- package/dist/packs/heroes/carry.js.map +1 -0
- package/dist/packs/heroes/commands.js +115 -0
- package/dist/packs/heroes/commands.js.map +1 -0
- package/dist/packs/heroes/fallen.d.ts +43 -0
- package/dist/packs/heroes/fallen.js +61 -0
- package/dist/packs/heroes/fallen.js.map +1 -0
- package/dist/packs/heroes/hire.js +60 -0
- package/dist/packs/heroes/hire.js.map +1 -0
- package/dist/packs/heroes/index.d.ts +7 -6
- package/dist/packs/heroes/index.js +130 -0
- package/dist/packs/heroes/index.js.map +1 -0
- package/dist/packs/heroes/loop.d.ts +95 -0
- package/dist/packs/heroes/loop.js +250 -0
- package/dist/packs/heroes/loop.js.map +1 -0
- package/dist/packs/heroes/making.d.ts +6 -3
- package/dist/packs/heroes/making.js +55 -0
- package/dist/packs/heroes/making.js.map +1 -0
- package/dist/packs/heroes/respawn.d.ts +3 -3
- package/dist/packs/heroes/respawn.js +87 -0
- package/dist/packs/heroes/respawn.js.map +1 -0
- package/dist/packs/heroes/sets.d.ts +32 -0
- package/dist/packs/heroes/sets.js +51 -0
- package/dist/packs/heroes/sets.js.map +1 -0
- package/dist/packs/heroes/spells.d.ts +16 -0
- package/dist/packs/heroes/spells.js +269 -0
- package/dist/packs/heroes/spells.js.map +1 -0
- package/dist/packs/items/defaults.d.ts +43 -0
- package/dist/packs/items/defaults.js +1504 -0
- package/dist/packs/items/defaults.js.map +1 -0
- package/dist/packs/items/index.d.ts +27 -0
- package/dist/packs/items/index.js +214 -0
- package/dist/packs/items/index.js.map +1 -0
- package/dist/packs/moba/index.d.ts +3 -3
- package/dist/packs/moba/index.js +174 -0
- package/dist/packs/moba/index.js.map +1 -0
- package/dist/packs/pack.d.ts +15 -15
- package/dist/packs/pack.js +14 -0
- package/dist/packs/pack.js.map +1 -0
- package/dist/packs.d.ts +15 -7
- package/dist/packs.js +222 -0
- package/dist/packs.js.map +1 -0
- package/dist/paths.d.ts +2 -0
- package/dist/paths.js +109 -0
- package/dist/paths.js.map +1 -0
- package/dist/plain.js +57 -0
- package/dist/plain.js.map +1 -0
- package/dist/player.d.ts +33 -10
- package/dist/player.js +159 -0
- package/dist/player.js.map +1 -0
- package/dist/portals.d.ts +1 -1
- package/dist/portals.js +194 -0
- package/dist/portals.js.map +1 -0
- package/dist/prefabs.d.ts +25 -2
- package/dist/prefabs.js +239 -0
- package/dist/prefabs.js.map +1 -0
- package/dist/presetBuildings.js +58 -0
- package/dist/presetBuildings.js.map +1 -0
- package/dist/presetFoliage.d.ts +27 -0
- package/dist/presetFoliage.js +98 -0
- package/dist/presetFoliage.js.map +1 -0
- package/dist/presetGround.js +65 -0
- package/dist/presetGround.js.map +1 -0
- package/dist/proxies.d.ts +12 -0
- package/dist/proxies.js +79 -0
- package/dist/proxies.js.map +1 -0
- package/dist/query.d.ts +56 -0
- package/dist/query.js +88 -0
- package/dist/query.js.map +1 -0
- package/dist/races.d.ts +15 -14
- package/dist/races.js +172 -0
- package/dist/races.js.map +1 -0
- package/dist/randomGroups.js +91 -0
- package/dist/randomGroups.js.map +1 -0
- package/dist/registry.d.ts +117 -53
- package/dist/registry.js +323 -0
- package/dist/registry.js.map +1 -0
- package/dist/remains.d.ts +11 -9
- package/dist/remains.js +188 -0
- package/dist/remains.js.map +1 -0
- package/dist/replication.d.ts +12 -7
- package/dist/replication.js +100 -0
- package/dist/replication.js.map +1 -0
- package/dist/rng.d.ts +2 -0
- package/dist/rng.js +40 -0
- package/dist/rng.js.map +1 -0
- package/dist/rules.d.ts +186 -99
- package/dist/rules.js +179 -0
- package/dist/rules.js.map +1 -0
- package/dist/rulesCheck.d.ts +5 -4
- package/dist/rulesCheck.js +693 -0
- package/dist/rulesCheck.js.map +1 -0
- package/dist/runes.d.ts +2 -2
- package/dist/runes.js +80 -0
- package/dist/runes.js.map +1 -0
- package/dist/save.d.ts +37 -12
- package/dist/save.js +532 -0
- package/dist/save.js.map +1 -0
- package/dist/scenario.d.ts +2 -2
- package/dist/scenario.js +99 -0
- package/dist/scenario.js.map +1 -0
- package/dist/scheduler.d.ts +3 -0
- package/dist/scheduler.js +156 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/score.d.ts +19 -19
- package/dist/score.js +709 -0
- package/dist/score.js.map +1 -0
- package/dist/sequences.d.ts +10 -6
- package/dist/sequences.js +206 -0
- package/dist/sequences.js.map +1 -0
- package/dist/server/doorman.js +154 -0
- package/dist/server/doorman.js.map +1 -0
- package/dist/server/gameServer.d.ts +16 -1
- package/dist/server/gameServer.js +643 -0
- package/dist/server/gameServer.js.map +1 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/lobby.js +199 -0
- package/dist/server/lobby.js.map +1 -0
- package/dist/server/log.js +18 -0
- package/dist/server/log.js.map +1 -0
- package/dist/server/match.js +267 -0
- package/dist/server/match.js.map +1 -0
- package/dist/server/mode.d.ts +18 -9
- package/dist/server/mode.js +220 -0
- package/dist/server/mode.js.map +1 -0
- package/dist/{navigation-worker.js → server/navigation-worker.js} +1 -1
- package/dist/server/navigation-worker.js.map +1 -0
- package/dist/server/navigation.js +39 -0
- package/dist/server/navigation.js.map +1 -0
- package/dist/server/ops.d.ts +4 -0
- package/dist/server/ops.js +137 -0
- package/dist/server/ops.js.map +1 -0
- package/dist/server/packs.d.ts +3 -3
- package/dist/server/packs.js +32 -0
- package/dist/server/packs.js.map +1 -0
- package/dist/server/ratings.d.ts +5 -0
- package/dist/server/ratings.js +104 -0
- package/dist/server/ratings.js.map +1 -0
- package/dist/server/relay.d.ts +12 -2
- package/dist/server/relay.js +144 -0
- package/dist/server/relay.js.map +1 -0
- package/dist/server/rooms.d.ts +9 -2
- package/dist/server/rooms.js +442 -0
- package/dist/server/rooms.js.map +1 -0
- package/dist/server/seat.js +116 -0
- package/dist/server/seat.js.map +1 -0
- package/dist/server/seatSettings.d.ts +3 -3
- package/dist/server/seatSettings.js +63 -0
- package/dist/server/seatSettings.js.map +1 -0
- package/dist/server/secret.js +13 -0
- package/dist/server/secret.js.map +1 -0
- package/dist/server/start.d.ts +13 -6
- package/dist/server/start.js +76 -0
- package/dist/server/start.js.map +1 -0
- package/dist/server/websocket.d.ts +9 -1
- package/dist/server/websocket.js +306 -0
- package/dist/server/websocket.js.map +1 -0
- package/dist/server.js +15 -2861
- package/dist/session/can.js +26 -0
- package/dist/session/can.js.map +1 -0
- package/dist/session/commandReplay.d.ts +8 -2
- package/dist/session/commandReplay.js +293 -0
- package/dist/session/commandReplay.js.map +1 -0
- package/dist/session/debug.js +151 -0
- package/dist/session/debug.js.map +1 -0
- package/dist/session/delay.js +62 -0
- package/dist/session/delay.js.map +1 -0
- package/dist/session/delta.d.ts +14 -1
- package/dist/session/delta.js +407 -0
- package/dist/session/delta.js.map +1 -0
- package/dist/session/entityState.js +415 -0
- package/dist/session/entityState.js.map +1 -0
- package/dist/session/local.d.ts +47 -5
- package/dist/session/local.js +670 -0
- package/dist/session/local.js.map +1 -0
- package/dist/session/memory.d.ts +20 -2
- package/dist/session/memory.js +131 -0
- package/dist/session/memory.js.map +1 -0
- package/dist/session/protocol.d.ts +325 -31
- package/dist/session/protocol.js +55 -0
- package/dist/session/protocol.js.map +1 -0
- package/dist/session/remote.d.ts +74 -12
- package/dist/session/remote.js +1394 -0
- package/dist/session/remote.js.map +1 -0
- package/dist/session/replay.d.ts +11 -2
- package/dist/session/replay.js +160 -0
- package/dist/session/replay.js.map +1 -0
- package/dist/session/seed.js +12 -0
- package/dist/session/seed.js.map +1 -0
- package/dist/session/share.d.ts +5 -1
- package/dist/session/share.js +94 -0
- package/dist/session/share.js.map +1 -0
- package/dist/session/socket.d.ts +1 -1
- package/dist/session/socket.js +29 -0
- package/dist/session/socket.js.map +1 -0
- package/dist/session/wire.d.ts +5 -0
- package/dist/session/wire.js +84 -0
- package/dist/session/wire.js.map +1 -0
- package/dist/session/worker.d.ts +77 -12
- package/dist/session/worker.js +499 -0
- package/dist/session/worker.js.map +1 -0
- package/dist/shared.d.ts +31 -5
- package/dist/shared.js +166 -0
- package/dist/shared.js.map +1 -0
- package/dist/sides.d.ts +9 -3
- package/dist/sides.js +149 -0
- package/dist/sides.js.map +1 -0
- package/dist/sight.js +85 -0
- package/dist/sight.js.map +1 -0
- package/dist/simulate-worker.js +1 -1
- package/dist/simulate.d.ts +12 -8
- package/dist/{simulate-oXBiw1Ff.js → simulate.js} +10 -11
- package/dist/simulate.js.map +1 -0
- package/dist/smart.js +77 -0
- package/dist/smart.js.map +1 -0
- package/dist/spatial.d.ts +32 -16
- package/dist/spatial.js +234 -0
- package/dist/spatial.js.map +1 -0
- package/dist/spawning.d.ts +1 -0
- package/dist/spawning.js +224 -0
- package/dist/spawning.js.map +1 -0
- package/dist/stances.d.ts +6 -3
- package/dist/stances.js +169 -0
- package/dist/stances.js.map +1 -0
- package/dist/start.d.ts +10 -10
- package/dist/start.js +75 -0
- package/dist/start.js.map +1 -0
- package/dist/stats.d.ts +42 -16
- package/dist/stats.js +290 -0
- package/dist/stats.js.map +1 -0
- package/dist/summoned.d.ts +52 -0
- package/dist/summoned.js +38 -0
- package/dist/summoned.js.map +1 -0
- package/dist/summons.d.ts +10 -13
- package/dist/summons.js +271 -0
- package/dist/summons.js.map +1 -0
- package/dist/systems/abilities.js +224 -0
- package/dist/systems/abilities.js.map +1 -0
- package/dist/systems/combat.d.ts +35 -1
- package/dist/systems/combat.js +677 -0
- package/dist/systems/combat.js.map +1 -0
- package/dist/systems/combatTold.d.ts +3 -1
- package/dist/systems/combatTold.js +85 -0
- package/dist/systems/combatTold.js.map +1 -0
- package/dist/systems/construction.js +80 -0
- package/dist/systems/construction.js.map +1 -0
- package/dist/systems/economy.d.ts +0 -6
- package/dist/systems/economy.js +128 -0
- package/dist/systems/economy.js.map +1 -0
- package/dist/systems/fog.d.ts +1 -1
- package/dist/systems/fog.js +120 -0
- package/dist/systems/fog.js.map +1 -0
- package/dist/systems/life.js +32 -0
- package/dist/systems/life.js.map +1 -0
- package/dist/systems/movement.d.ts +24 -12
- package/dist/systems/movement.js +1247 -0
- package/dist/systems/movement.js.map +1 -0
- package/dist/systems/orders.js +64 -0
- package/dist/systems/orders.js.map +1 -0
- package/dist/systems/production.js +322 -0
- package/dist/systems/production.js.map +1 -0
- package/dist/systems/productionQueue.js +120 -0
- package/dist/systems/productionQueue.js.map +1 -0
- package/dist/systems/victory.d.ts +1 -1
- package/dist/systems/victory.js +56 -0
- package/dist/systems/victory.js.map +1 -0
- package/dist/talk.d.ts +6 -6
- package/dist/talk.js +153 -0
- package/dist/talk.js.map +1 -0
- package/dist/targeting.d.ts +142 -0
- package/dist/targeting.js +49 -0
- package/dist/targeting.js.map +1 -0
- package/dist/tech.d.ts +20 -3
- package/dist/tech.js +239 -0
- package/dist/tech.js.map +1 -0
- package/dist/techTree.d.ts +7 -0
- package/dist/techTree.js +90 -0
- package/dist/techTree.js.map +1 -0
- package/dist/terrain.d.ts +59 -7
- package/dist/terrain.js +389 -0
- package/dist/terrain.js.map +1 -0
- package/dist/terrainSave.d.ts +6 -0
- package/dist/terrainSave.js +74 -0
- package/dist/terrainSave.js.map +1 -0
- package/dist/testing.d.ts +8 -7
- package/dist/testing.js +13 -739
- package/dist/testing.js.map +1 -1
- package/dist/tiles.d.ts +1 -1
- package/dist/tiles.js +43 -0
- package/dist/tiles.js.map +1 -0
- package/dist/timers.d.ts +29 -4
- package/dist/timers.js +242 -0
- package/dist/timers.js.map +1 -0
- package/dist/tomes.d.ts +4 -4
- package/dist/tomes.js +94 -0
- package/dist/tomes.js.map +1 -0
- package/dist/trade.js +103 -0
- package/dist/trade.js.map +1 -0
- package/dist/transport.d.ts +6 -1
- package/dist/transport.js +281 -0
- package/dist/transport.js.map +1 -0
- package/dist/tunables.d.ts +10 -3
- package/dist/tunables.js +56 -0
- package/dist/tunables.js.map +1 -0
- package/dist/unitResources.d.ts +67 -0
- package/dist/unitResources.js +266 -0
- package/dist/unitResources.js.map +1 -0
- package/dist/upkeep.d.ts +6 -1
- package/dist/upkeep.js +26 -0
- package/dist/upkeep.js.map +1 -0
- package/dist/veterancy.d.ts +8 -3
- package/dist/veterancy.js +131 -0
- package/dist/veterancy.js.map +1 -0
- package/dist/vision.d.ts +36 -0
- package/dist/vision.js +133 -0
- package/dist/vision.js.map +1 -0
- package/dist/walls.d.ts +1 -1
- package/dist/walls.js +278 -0
- package/dist/walls.js.map +1 -0
- package/dist/world.d.ts +606 -88
- package/dist/world.js +1263 -0
- package/dist/world.js.map +1 -0
- package/package.json +2 -2
- package/dist/ai.js.map +0 -1
- package/dist/attributes.d.ts +0 -66
- package/dist/brain-BvVdUhX8.js +0 -7659
- package/dist/brain-BvVdUhX8.js.map +0 -1
- package/dist/builds-C6LfgvEU.js +0 -460
- package/dist/builds-C6LfgvEU.js.map +0 -1
- package/dist/coreComponents-syuh2fPG.js +0 -5149
- package/dist/coreComponents-syuh2fPG.js.map +0 -1
- package/dist/debugCommands-CzjrSm66.js +0 -14739
- package/dist/debugCommands-CzjrSm66.js.map +0 -1
- package/dist/determinism-BCymQwiE.js +0 -518
- package/dist/determinism-BCymQwiE.js.map +0 -1
- package/dist/game-DiJEN-Ks.js +0 -5800
- package/dist/game-DiJEN-Ks.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/inspect-D9dWHmZ0.js.map +0 -1
- package/dist/local-Dkovq42k.js +0 -1379
- package/dist/local-Dkovq42k.js.map +0 -1
- package/dist/missionRules-C-bGxm0Q.js.map +0 -1
- package/dist/navigation-worker.js.map +0 -1
- package/dist/packs-g5thvmGn.js +0 -3199
- package/dist/packs-g5thvmGn.js.map +0 -1
- package/dist/profiles-B3NS9jwk.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/simulate-oXBiw1Ff.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"packs-g5thvmGn.js","names":[],"sources":["../src/session/wire.ts","../src/session/remote.ts","../src/session/delay.ts","../src/session/seed.ts","../src/noise.ts","../src/mapCheck/rules/players.ts","../src/mapCheck/rules/objects.ts","../src/mapCheck/rules/random.ts","../src/mapCheck/rules/names.ts","../src/mapCheck/rules/regions.ts","../src/mapCheck/rules/paths.ts","../src/mapCheck/cells.ts","../src/mapCheck/rules/walking.ts","../src/mapCheck/rules/races.ts","../src/mapCheck/rules/targets.ts","../src/mapCheck.ts","../src/generate.ts","../src/packs.ts"],"sourcesContent":["/**\n * What goes over the wire between a host and a player, both layers of it in one place (design review E11): the game's\n * (`GameHostMessage`, `GameCommandMessage`: a `SessionHost` and a `RemoteSession`) and a server's lobby beside it\n * (`LobbyServerMessage`, `LobbyPlayerMessage`: a `GameServer`). One union each way (`HostToPlayer`, `PlayerToHost`),\n * discriminated by `type` (no type is both a game's and a lobby's), read with a shape check (`readHostMessage`,\n * `readPlayerMessage`), and `PROTOCOL_VERSION` is of all of it\n */\nimport type { GameData } from '#engine/gameData'\nimport type { Inspection, InspectTarget, LoggedEvent, WorldListing } from '#engine/inspect'\nimport type { PlayerId } from '#engine/entity'\nimport type { GameResult, ServerHooks, ServerSeat } from '#engine/game'\nimport type { SavedGround } from '#engine/ground'\nimport type { MapCamera, MapDoodad, MapEnvironment, MapPath, MapRegion } from '#engine/map'\nimport type { Delta } from './delta'\nimport type { PlayerCommand } from './protocol'\nimport type { RelayNotice, RelayRequest } from './share'\n\n/**\n * What the host sends a player\n *\n * @beta\n */\nexport type GameHostMessage =\n\t| {\n\t\t\ttype: 'welcome'\n\t\t\t/** The version of the wire the host speaks (`PROTOCOL_VERSION`): a player of another refuses the game */\n\t\t\tprotocol: number\n\t\t\tplayer: PlayerId\n\t\t\ttickRate: number\n\t\t\t/** The game module the world runs, by id, and the version of its data (`Registry.dataHash`): the player's has to be the same */\n\t\t\tgame: string\n\t\t\thash: string\n\t\t\t/**\n\t\t\t * The ground: all of it, or the map of the game it started as and what changed of it since (S36). A player\n\t\t\t * without that map asks for it (`ground`), and is sent it in parts\n\t\t\t */\n\t\t\tterrain: SavedGround\n\t\t\t/** What the map looks like beyond its ground, for the screen */\n\t\t\tenvironment?: MapEnvironment\n\t\t\t/** Its scenery, for the screen */\n\t\t\tdoodads?: MapDoodad[]\n\t\t\t/** Its regions, for the screen: what mist in places lies over by name */\n\t\t\tregions?: MapRegion[]\n\t\t\t/** Its views saved under names */\n\t\t\tcameras?: MapCamera[]\n\t\t\t/** Its paths, for a cinematic's camera on a rail */\n\t\t\tpaths?: MapPath[]\n\t\t\t/** What its definitions were changed to while it ran (`world.redefine`), copies and all: put in the player's registry */\n\t\t\tredefinitions?: GameData\n\t\t\t/** Everything the player knows, as a delta without a base */\n\t\t\tfirst: Delta\n\t\t\t/** The player only watches, and sees everything */\n\t\t\tobserver?: boolean\n\t\t\t/** The player may use the debug tools (`world.debugPlayers`): the host follows the world for them (`debug`) */\n\t\t\tdebug?: true\n\t }\n\t| { type: 'pong'; at: number }\n\t/** A part of the ground a world started as, for a player who does not have its map: `text` of `parts`, joined, is a `TerrainSave` */\n\t| { type: 'ground'; part: number; parts: number; text: string }\n\t/** The game ended on an error in its rules (`World.failure`): what the players are told of it */\n\t| { type: 'failed'; message: string }\n\t| ({ type: 'delta' } & Delta)\n\t/** The debug tools' view of the world (`SessionDebug`), for a player who may use them and follows something: every tenth of a second */\n\t| { type: 'debug'; inspection: Inspection | null; world: WorldListing | null; log: readonly LoggedEvent[] }\n\n/**\n * What a player sends the host: commands, and which ticks it has got (what the next deltas are made against)\n *\n * @internal\n */\nexport type GameCommandMessage =\n\t| { type: 'command'; seq: number; command: PlayerCommand }\n\t| { type: 'ack'; tick: number; events?: number }\n\t/** To measure the time there and back: answered at once with a `pong` of the same `at` */\n\t| { type: 'ping'; at: number }\n\t/** A part of the ground the world started as, for a player who does not have its map (`ground` answers it) */\n\t| { type: 'ground'; part: number }\n\t/** What the debug tools follow, change and list (`SessionDebug`), from a player who may use them: `debug` answers it */\n\t| ({ type: 'debug' } & DebugAsk)\n\n/**\n * What the debug tools of a screen ask of a world elsewhere (`SessionDebug`), as said over the wire or to a worker\n *\n * @beta\n */\nexport interface DebugAsk {\n\tinspect?: InspectTarget | null\n\tset?: { path: (string | number)[]; value: number | boolean }\n\tlisting?: boolean\n\tlogging?: boolean\n\tclearLog?: true\n}\n\n/**\n * What a player says to the server, besides what goes to the game\n *\n * @internal\n */\nexport type LobbyPlayerMessage =\n\t| {\n\t\t\ttype: 'join'\n\t\t\tname?: string\n\t\t\ttoken?: string\n\t\t\tticket?: string\n\t\t\twatch?: boolean\n\t\t\tkey?: string\n\t\t\tback?: boolean\n\t\t\twho?: string\n\t\t\t/**\n\t\t\t * The version of the wire the player speaks (`PROTOCOL_VERSION`): one of another is refused with why. Left\n\t\t\t * out, the player's own check of the welcome is what tells them\n\t\t\t */\n\t\t\tprotocol?: number\n\t }\n\t| { type: 'start' }\n\t/** In the lobby: another seat, free, for who is seated */\n\t| { type: 'sit'; player: PlayerId }\n\t/** In the lobby: ready, or not. Once every player seated is, the game starts */\n\t| { type: 'ready'; ready: boolean }\n\t/** In the lobby: the name one is shown by */\n\t| { type: 'name'; name: string }\n\t/** In a game a player paused (`pause` command): it goes on, for everyone */\n\t| { type: 'resume' }\n\t| { type: 'setting'; name: string; value: string }\n\t/** In the lobby: a setting of a seat (`ServerHooks.seatSettings`): one's own, or one no other player holds */\n\t| { type: 'seatSetting'; player: PlayerId; name: string; value: string }\n\t| { type: 'admin'; key: string; action: 'pause' | 'resume' | 'stop' }\n\t/** In the lobby: a line said to everyone there, before the game */\n\t| { type: 'lobbyChat'; text: string }\n\t/** In the lobby: a vote to let another seated player go. Once most of the others vote so, they are let go */\n\t| { type: 'kick'; player: PlayerId }\n\n/**\n * What the server tells everyone connected, as it changes\n *\n * @beta\n */\nexport type LobbyServerMessage =\n\t| {\n\t\t\ttype: 'lobby'\n\t\t\tmode: string\n\t\t\tgame: string\n\t\t\tphase: 'lobby' | 'game' | 'ended'\n\t\t\tseats: ServerSeat[]\n\t\t\tsettings: Record<string, string>\n\t\t\t/** What the game offers to set (`ServerHooks.settings`) */\n\t\t\toffered: NonNullable<ServerHooks['settings']>\n\t\t\t/** What the game offers to set for each seat (`ServerHooks.seatSettings`, and a race: `seatSettingsOf`) */\n\t\t\tseatOffered: NonNullable<ServerHooks['seatSettings']>\n\t }\n\t| { type: 'seated'; player: PlayerId; token: string }\n\t/** A line said in the lobby (`lobbyChat`): by whom, their seat where they have one */\n\t| { type: 'lobbyChat'; player?: PlayerId; name: string; text: string }\n\t| { type: 'watching'; player: PlayerId }\n\t| { type: 'full' }\n\t| { type: 'refused'; reason: string }\n\t/** The game paused, or going on: by a player (`player`, for `seconds` at most) or by an admin (no player) */\n\t| { type: 'paused'; paused: boolean; player?: PlayerId; seconds?: number }\n\t| { type: 'result'; result: GameResult }\n\n/**\n * What a player is told besides the game: a server's lobby, a pause, the result, or, watching through a relay, that\n * nothing is shared yet or that the game watched ended\n *\n * @beta\n */\nexport type ServerToPlayer = LobbyServerMessage | Extract<RelayNotice, { type: 'waiting' | 'ended' }>\n\n/**\n * Everything a host, a server or a relay sends a player\n *\n * @beta\n */\nexport type HostToPlayer = GameHostMessage | ServerToPlayer\n\n/**\n * Everything a player sends a host or a server, or a relay to watch through\n *\n * @internal\n */\nexport type PlayerToHost = GameCommandMessage | LobbyPlayerMessage | Extract<RelayRequest, { type: 'watch' }>\n\n/** The game's own messages to a player: the rest are a server's or a relay's (`ServerToPlayer`) */\nconst GAME_TYPES = new Set<string>(['welcome', 'pong', 'ground', 'failed', 'delta', 'debug'] satisfies GameHostMessage['type'][])\n\n/**\n * Whether a message to a player is a server's or a relay's, not the game's\n *\n * @internal\n */\nexport const isServerMessage = (message: HostToPlayer): message is ServerToPlayer => !GAME_TYPES.has(message.type)\n\n/** Every type a player is sent, each said once: what is not one of them is not read */\nconst HOST_TYPES: Record<HostToPlayer['type'], true> = {\n\twelcome: true,\n\tpong: true,\n\tground: true,\n\tfailed: true,\n\tdelta: true,\n\tdebug: true,\n\tlobby: true,\n\tseated: true,\n\twatching: true,\n\tfull: true,\n\trefused: true,\n\tlobbyChat: true,\n\tpaused: true,\n\tresult: true,\n\twaiting: true,\n\tended: true\n}\n\n/** Every type a host or a server is sent */\nconst PLAYER_TYPES: Record<PlayerToHost['type'], true> = {\n\tcommand: true,\n\tack: true,\n\tping: true,\n\tground: true,\n\tdebug: true,\n\tjoin: true,\n\tstart: true,\n\tsit: true,\n\tready: true,\n\tname: true,\n\tresume: true,\n\tsetting: true,\n\tseatSetting: true,\n\tadmin: true,\n\tlobbyChat: true,\n\tkick: true,\n\twatch: true\n}\n\n/** A message as text, an object of a known type, or nothing: not JSON, not an object, a type that is not one of `types` */\nfunction read<M extends { type: string }>(text: string, types: Record<string, true>): M | undefined {\n\tlet message: unknown\n\ttry {\n\t\tmessage = JSON.parse(text)\n\t} catch {\n\t\treturn undefined\n\t}\n\tif (typeof message !== 'object' || message === null || Array.isArray(message)) return undefined\n\tconst { type } = message as { type?: unknown }\n\treturn typeof type === 'string' && Object.hasOwn(types, type) ? (message as M) : undefined\n}\n\n/**\n * What a host or a server sent, as text: one of its messages, or nothing for what is not (not JSON, not an object of a\n * type a player is sent). Its fields are its receiver's to check\n *\n * @internal\n */\nexport const readHostMessage = (text: string): HostToPlayer | undefined => read(text, HOST_TYPES)\n\n/**\n * What a player sent, as text: one of its messages, or nothing for what is not\n *\n * @internal\n */\nexport const readPlayerMessage = (text: string): PlayerToHost | undefined => read(text, PLAYER_TYPES)\n","import { worldFailed } from '#engine/engineEvents'\nimport { groundSpeedOn, hasGroundSpeeds } from '#engine/groundSpeed'\nimport { type DataKind, type DataValues, type GameData, mergeValues, redefineIn, redefinitions, restoreRedefinitions } from '#engine/gameData'\nimport { type GameCommandMessage, type GameHostMessage, type HostToPlayer, isServerMessage, readHostMessage, type ServerToPlayer } from './wire'\nimport { errorFields } from '#engine/log'\nimport type { GameMap, MapCamera, MapDoodad, MapEnvironment, MapPath, MapRegion } from '#engine/map'\nimport { footprintOf } from '#engine/defs'\nimport type { PlayerId } from '#engine/entity'\nimport type { GameModule } from '#engine/game'\nimport { createRegistry } from '#engine/game'\nimport { BuildGrid } from '#engine/grid'\nimport type { Vec2 } from '#engine/math'\nimport { AirNavigation } from '#engine/navigation/air'\nimport type { Navigation } from '#engine/navigation/navigation'\nimport { RecastNavigation, type RecastNavigationOptions } from '#engine/navigation/recast'\nimport { placementCells, siteOf } from '#engine/orders/build'\nimport type { Registry } from '#engine/registry'\nimport { loadTerrain, saveTerrain, type TerrainSave } from '#engine/terrainSave'\nimport {\n\tapplyTerrainPatch,\n\tgroundOf,\n\tisGroundChanges,\n\tMissingGround,\n\tsavedGround,\n\ttype SavedGround,\n\tterrainPatchProblem,\n\twithChanges\n} from '#engine/ground'\nimport type { Terrain } from '#engine/terrain'\nimport { groundKnownTo } from '#engine/cellLayers'\nimport type { World } from '#engine/world'\nimport { type MessageRef, toMessage } from '#engine/messages'\nimport { LocalSession, endSharedCaptures, shareCaptures } from './local'\nimport { askDebug, DEBUG_EVERY, LocalDebug, RemoteDebug } from './debug'\nimport { apply, bytesByKey, type Delta, diff, type FogMessage, type Frame, quantize } from './delta'\nimport {\n\ttype CampInfo,\n\ttype EntityState,\n\ttype FogState,\n\ttype GameSession,\n\tisFiniteNumber,\n\ttype PlayerCommand,\n\tPROTOCOL_VERSION,\n\tprotocolMismatch,\n\treadMessage,\n\ttype SessionEvent,\n\ttype Snapshot,\n\ttype SessionCan,\n\ttype SessionDebug\n} from './protocol'\n\n/*\n * A session over a wire. The simulation runs on one side (`SessionHost`, a server or a page standing in for one), each\n * player's screen on the other (`RemoteSession`). Between them only text goes, as it would over a WebSocket: what the\n * host sends a player is what that player's `LocalSession` seat would give, as JSON, and what a player sends is their\n * commands. Everything the screen asks besides (the fog, whether it can build somewhere, the way a unit would walk) is\n * answered on its own side, from what it has been told\n */\n\n/**\n * One end of a connection: text in, text out, in order\n *\n * @beta\n */\nexport interface Transport {\n\tsend(message: string): void\n\t/** What comes in from the other end. One handler: a later one takes the place of the one before */\n\tonMessage(handler: (message: string) => void): void\n\t/** Told when the other end closes */\n\tonClose(handler: () => void): void\n\tclose(): void\n}\n\n/**\n * An end of a `loopback`, which counts what it sends: for a budget of bandwidth\n *\n * @beta\n */\nexport interface LoopbackEnd extends Transport {\n\t/** Characters sent, a byte each as the JSON goes over a WebSocket of mostly ASCII */\n\treadonly bytesSent: number\n\treadonly messagesSent: number\n}\n\n/**\n * A connection inside the page, standing in for a network (`loopback`)\n *\n * @beta\n */\nexport interface LoopbackOptions {\n\t/** Milliseconds each message takes, one way */\n\tlatency?: number\n\t/** Milliseconds a message may take on top of that, at random: never out of order, the way a WebSocket keeps it */\n\tjitter?: number\n\t/**\n\t * The share of the snapshots that never arrive, 0..1, for what a lossy connection does to the screen. Only from the\n\t * host: the welcome and the player's commands always do. The events of a snapshot lost are lost with it\n\t */\n\tloss?: number\n\t/** Random numbers for jitter and loss: `Math.random` when left out (the simulation does not use it) */\n\trandom?: () => number\n}\n\n/**\n * Two ends of a connection in the page, `[client, host]`: everything sent is text, delivered after the latency the\n * options give. The whole networked way, in one page and in tests\n *\n * @beta\n */\nexport function loopback(options: LoopbackOptions = {}): [LoopbackEnd, LoopbackEnd] {\n\tconst { latency = 0, jitter = 0, loss = 0, random = Math.random } = options\n\n\t/** One end: what it is handed to deliver, and the transport its side holds */\n\tclass End implements LoopbackEnd {\n\t\tpeer!: End\n\t\tbytesSent = 0\n\t\tmessagesSent = 0\n\t\tprivate handler: (message: string) => void = () => {}\n\t\tprivate closed: () => void = () => {}\n\t\tprivate open = true\n\t\t/** When the last message sent is due: none overtakes the one before */\n\t\tprivate last = 0\n\n\t\tconstructor(private readonly lossy: boolean) {}\n\n\t\tsend(message: string): void {\n\t\t\tif (!this.open) return\n\t\t\tthis.bytesSent += message.length\n\t\t\tthis.messagesSent++\n\t\t\t// snapshots only: the welcome comes first, and commands go the other way\n\t\t\tif (this.lossy && loss > 0 && message.startsWith('{\"type\":\"delta\"') && random() < loss) return\n\t\t\tconst due = Math.max(performance.now() + latency + random() * jitter, this.last)\n\t\t\tthis.last = due\n\t\t\tconst { peer } = this\n\t\t\tsetTimeout(() => peer.deliver(message), Math.max(due - performance.now(), 0))\n\t\t}\n\n\t\tdeliver(message: string): void {\n\t\t\tif (this.open) this.handler(message)\n\t\t}\n\n\t\tonMessage(handler: (message: string) => void): void {\n\t\t\tthis.handler = handler\n\t\t}\n\n\t\tonClose(handler: () => void): void {\n\t\t\tthis.closed = handler\n\t\t}\n\n\t\tclose(): void {\n\t\t\tthis.shut()\n\t\t\t// the other end hears of it once what was on its way has arrived\n\t\t\tconst { peer } = this\n\t\t\tsetTimeout(() => peer.shut(), Math.max(this.last - performance.now(), latency, 0))\n\t\t}\n\n\t\tshut(): void {\n\t\t\tif (!this.open) return\n\t\t\tthis.open = false\n\t\t\tthis.closed()\n\t\t}\n\t}\n\n\tconst client = new End(false)\n\tconst host = new End(true)\n\tclient.peer = host\n\thost.peer = client\n\treturn [client, host]\n}\n\n// ---- what goes over the wire: `wire.ts`\n\n/** Whether what a player sent as a command is one to look at: an object with a type. Its fields are its definition's to check */\nconst isCommand = (value: unknown): value is PlayerCommand =>\n\ttypeof value === 'object' && value !== null && !Array.isArray(value) && typeof (value as { type?: unknown }).type === 'string'\n\n/**\n * Runs of equal values: how many 0s, then how many 1s, and so on\n *\n * @internal\n */\nexport function toRuns(cells: Uint8Array): number[] {\n\tconst runs: number[] = []\n\tlet value = 0\n\tlet count = 0\n\tfor (let i = 0; i < cells.length; i++) {\n\t\tconst cell = cells[i] ? 1 : 0\n\t\tif (cell === value) count++\n\t\telse {\n\t\t\truns.push(count)\n\t\t\tvalue = cell\n\t\t\tcount = 1\n\t\t}\n\t}\n\truns.push(count)\n\treturn runs\n}\n\n/**\n * Cells back from `toRuns`, into `out`\n *\n * @internal\n */\nexport function fromRuns(runs: readonly number[], out: Uint8Array): Uint8Array {\n\tlet at = 0\n\tlet value = 0\n\tfor (const run of runs) {\n\t\tout.fill(value, at, Math.min(at + run, out.length))\n\t\tat += run\n\t\tvalue ^= 1\n\t}\n\treturn out\n}\n\n/** The fog for the wire: nothing of its cells when the whole map is lit, which they say nothing about then */\nconst fogMessage = (fog: FogState): FogMessage =>\n\tfog.revealed ? { revealed: true, visible: [], explored: [] } : { revealed: false, visible: toRuns(fog.visible), explored: toRuns(fog.explored) }\n\n/** The runs of a team's fog, by its cells, as they were at a version of the fog: the seats of a team share them */\nconst fogRuns = new WeakMap<Uint8Array, { version: number; message: FogMessage }>()\nconst revealedFog: FogMessage = { revealed: true, visible: [], explored: [] }\n\n/** The fog for the wire, its runs made once for every seat of a team while it stays as it is */\nfunction fogMessageOf(fog: FogState): FogMessage {\n\tif (fog.revealed) return revealedFog\n\tconst known = fogRuns.get(fog.visible)\n\tif (known && known.version === fog.version) return known.message\n\tconst message = fogMessage(fog)\n\tfogRuns.set(fog.visible, { version: fog.version, message })\n\treturn message\n}\n\n/**\n * The entities of a frame as the wire has them (`quantize`), one list between the seats of a round told the very same\n * (the seats of a side, the observers: what they are told of an entity is one object between them, `LocalSession`), so\n * that it is rounded once and a diff of the same two lists is worked out once (`diff`). `made` is this round's so far\n */\nfunction quantizedList(entities: readonly EntityState[], made: { told: readonly EntityState[]; sent: EntityState[] }[]): EntityState[] {\n\tfor (const { told, sent } of made) {\n\t\tif (told.length !== entities.length) continue\n\t\tlet alike = true\n\t\tfor (let i = 0; i < told.length; i++) {\n\t\t\tif (told[i] !== entities[i]) {\n\t\t\t\talike = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (alike) return sent\n\t}\n\tconst sent = entities.map(quantize)\n\tmade.push({ told: entities, sent })\n\treturn sent\n}\n\n/** Milliseconds between two pings, to measure the time to the host and back */\nconst PING_EVERY = 2000\n\n/** Seconds of jitter the interpolation buffer makes room for, at most */\nexport const MAX_JITTER = 0.2\n\n/**\n * What a player's side keeps and how often it asks, set by `ConnectOptions`: each the number it has always been when\n * left out\n *\n * @beta\n */\nexport interface PlayerLimits {\n\t/** Milliseconds between two pings, to measure the time to the host and back. 2000 when left out */\n\tpingEvery?: number\n\t/** Seconds of jitter the interpolation buffer makes room for, at most: a spike of lateness is not waited out for good. 0.2 when left out */\n\tmaxJitter?: number\n\t/** Snapshots waiting for the screen, at most: past that the oldest is folded into the next. 64 when left out */\n\tkeptSnapshots?: number\n\t/** Events the folded snapshots carry together, at most: the newest kept. 2000 when left out */\n\tkeptScreenEvents?: number\n}\n\n/**\n * Where a host's time went over a while: see `SessionHost.takeTiming`\n *\n * @beta\n */\nexport interface HostTiming {\n\t/** When the counting started, `performance.now()` */\n\tsince: number\n\tticks: number\n\t/** Milliseconds the ticks took, added up, and the longest */\n\ttickTime: number\n\ttickMax: number\n\t/** Rounds of sending everyone what changed */\n\tsends: number\n\tsendTime: number\n\tsendMax: number\n\t/**\n\t * Where the sending's milliseconds went, added up over the seats: what each player may know taken from the world\n\t * (`capture`), its positions rounded (`quantize`), the fog made runs (`fog`), what changed since the frame they\n\t * have (`diff`), made text (`stringify`)\n\t *\n\t * @beta\n\t */\n\tparts: { capture: number; quantize: number; fog: number; diff: number; stringify: number }\n\t/**\n\t * Characters of the rounds' text, to every seat, before any compression of the wire\n\t *\n\t * @beta\n\t */\n\tbytes: number\n\t/**\n\t * Those characters by what they carry, when the host counts them (`SessionHostOptions.bytesByKey`): each field of\n\t * the entities added and changed (`entity.hp`, `entity.own.abilities`), the other parts (`rest.players`, `rest.fog`),\n\t * `events`, `removed`, and the rest (ids, brackets) as `other`. They add up to `bytes`\n\t *\n\t * @beta\n\t */\n\tkeys?: Record<string, number>\n}\n\nconst emptyTiming = (since: number, byKey = false): HostTiming => ({\n\tsince,\n\tticks: 0,\n\ttickTime: 0,\n\ttickMax: 0,\n\tsends: 0,\n\tsendTime: 0,\n\tsendMax: 0,\n\tparts: { capture: 0, quantize: 0, fog: 0, diff: 0, stringify: 0 },\n\tbytes: 0,\n\t...(byKey && { keys: {} })\n})\n\n/** Frames kept on either side, at most: more than a second and a half of ticks a player has not said it got */\nconst KEPT_FRAMES = 64\n\n/**\n * Bytes of the frames kept for one player, at most (`SessionHostOptions.keptBytes`): 8 MB, some thirty frames of a\n * thousand units (a frame of them is about 250 KB). A player who has said nothing for longer is sent everything again\n */\nconst KEPT_BYTES = 8 * 1024 * 1024\n\n/** What each list of entities a frame keeps takes as the wire writes it: one list between the seats of a side (`quantizedList`) */\nconst listBytes = new WeakMap<object, number>()\n\n/** Entities of a list written out to tell what the list takes: the rest are taken to be as big */\nconst SAMPLED = 8\n\n/**\n * What a frame kept for a player takes, about: its entities as the wire writes them (some of them written out, the rest\n * taken to be as big: writing out all of a thousand units' at every send costs more than the send itself), its fog,\n * its players\n */\nfunction frameBytes(frame: Frame): number {\n\tconst { entities, players } = frame.snapshot\n\tlet bytes = listBytes.get(entities)\n\tif (bytes === undefined) {\n\t\tconst sampled = Math.min(entities.length, SAMPLED)\n\t\tlet written = 0\n\t\tfor (let i = 0; i < sampled; i++) written += JSON.stringify(entities[Math.floor((i * entities.length) / sampled)]).length\n\t\tlistBytes.set(entities, (bytes = sampled ? Math.round((written / sampled) * entities.length) : 0))\n\t}\n\tlet fog = listBytes.get(frame.fog)\n\tif (fog === undefined) listBytes.set(frame.fog, (fog = JSON.stringify(frame.fog).length))\n\tlet told = listBytes.get(players)\n\tif (told === undefined) listBytes.set(players, (told = JSON.stringify(players).length))\n\treturn bytes + fog + told\n}\n\n/**\n * Snapshots waiting for the screen, at most (`RemoteSession.update`): three seconds of them at 20 a second. A page\n * whose screen stops asking (a tab in the background) folds the oldest into the next, their events kept, rather than\n * keeping every one for as long as it is away\n */\nconst KEPT_SNAPSHOTS = 64\n\n/** Events the folded snapshots carry together, at most: the newest kept. What is the screen's only (the state is in the snapshot) */\nconst KEPT_SCREEN_EVENTS = 2000\n\n// ---- the host\n\n/** A player connected to a host */\ninterface Seat {\n\ttransport: Transport\n\tsession: LocalSession\n\t/** The debug tools' view of the world, for a player who may use them and asked (`debug`), and when it last went */\n\tdebug?: { view: LocalDebug; sentAt: number }\n\t/** What was sent at each tick, until the player has said it got a later one */\n\tframes: Map<number, Frame>\n\t/** What each of those frames takes (`frameBytes`), and all of them together */\n\tframeSizes: Map<number, number>\n\tkeptBytes: number\n\t/** The last tick the player said it got whose frame was still kept: deltas are made against it. None yet before the first */\n\tacked: number\n\t/** The last tick the player said it got at all, kept or not: what it has heard up to */\n\theardUpTo: number\n\t/**\n\t * The whole frame (a delta against nothing) last sent and not yet said to be had, and when it went: no other whole\n\t * one goes until it is, or its answer is overdue (RV11)\n\t */\n\twhole?: { tick: number; at: number }\n\t/**\n\t * Events the player has not said it got: each batch by its own number (`n`, as talk goes out between ticks too, RV14),\n\t * the tick it went out with, and when it last was sent\n\t */\n\tevents: { tick: number; n: number; events: SessionEvent[]; sentAt?: number }[]\n\t/** The number of the last batch of events made for the player */\n\teventsMade: number\n\t/** When the frame of each tick went out, for the time an answer takes */\n\tsentAt: Map<number, number>\n\t/** Milliseconds from sending a frame to hearing it got there, evened out */\n\troundTrip: number\n\t/** The tick of the world when the player last said it got something, or connected */\n\theard: number\n\t/** What the host answers of its own, with the next snapshot: commands the limit let go, refused (`allow`) */\n\tanswers: SessionEvent[]\n\t/** The parts of the ground sent: each goes once */\n\tgroundSent: Set<number>\n}\n\n/** @beta */\nexport interface SessionHostOptions {\n\t/** Snapshots a second sent to each player, at most: the simulation runs at its tick rate all the same. 20 when left out */\n\tsendRate?: number\n\t/**\n\t * Ticks one update catches up at most. A host that fell further behind (a stall, a machine too slow for the game)\n\t * lets the rest go, and the game runs slower for a moment, rather than spiralling. 8 when left out\n\t */\n\tmaxTicksPerUpdate?: number\n\t/** Told of a tick that took longer than a tick lasts, with how many milliseconds: the watchdog */\n\tonSlowTick?: (milliseconds: number, tick: number) => void\n\t/**\n\t * Told when stepping the world threw, running by the clock (`start`): the host has stopped by then, and what\n\t * becomes of the game is whoever runs it's to say. Said in the world's log, and nothing more, when left out. An\n\t * error is never a reason for the process to go\n\t */\n\tonError?: (error: unknown) => void\n\t/**\n\t * The world is the host's, and goes with it (`dispose`): for a server's game, or a game run in the page behind a\n\t * wire. Not for a world the page plays itself and only lets others watch (`recordGame`, `shareGame`). No when left out\n\t */\n\townsWorld?: boolean\n\t/**\n\t * Seconds of the game a player may go without saying it got what it was sent, before its seat is closed: what is\n\t * kept for it to send again (the events it has not said it got) would grow for as long as it says nothing. 15 when\n\t * left out; `Infinity` never closes one\n\t */\n\tdropSilentAfter?: number\n\t/**\n\t * Ticks of events kept for a player who has not said they got them, at most: past that the oldest that already went\n\t * are let go, not sent again. They are there already over a transport that loses nothing (a worker, a WebSocket),\n\t * so this bounds only a player who goes on hearing but has stopped answering (a page frozen in the background). 600\n\t * when left out\n\t *\n\t * @beta\n\t */\n\tkeptEvents?: number\n\t/**\n\t * Frames kept for each player to make a delta against, at most: a player who says nothing for longer is sent\n\t * everything again, once, and nothing more until it answers (or its answer is overdue); an answer to a frame let go\n\t * still says the player is there. 64 when left out (more than a second and a half of ticks)\n\t *\n\t * @beta\n\t */\n\tkeptFrames?: number\n\t/**\n\t * Bytes of the frames kept for each player, at most, summed (what each takes as the wire writes it): a player who\n\t * says nothing while a thousand units fight is sent everything again sooner than `keptFrames` would. 8 MB when left\n\t * out\n\t *\n\t * @beta\n\t */\n\tkeptBytes?: number\n\t/**\n\t * Characters of the ground in one message, for a player who does not have the map and asks for it a part at a\n\t * time: well under what a connection holds. 262144 when left out\n\t *\n\t * @beta\n\t */\n\tgroundPart?: number\n\t/**\n\t * Whether `takeTiming` says what the characters sent were spent on, field by field (`HostTiming.keys`): what a\n\t * measure of the wire asks for (`net.bench.ts`), at the cost of writing each field again. No when left out\n\t *\n\t * @beta\n\t */\n\tbytesByKey?: boolean\n}\n\n/**\n * Runs a world for players connected to it over transports: the server's job, done anywhere. It steps the world by\n * the clock (`start`) or by hand (`update`), and at most `sendRate` times a second sends every player what changed in\n * what they may know (`Delta`), as their `LocalSession` seat sees it: against the last tick they said they got, with\n * the events they have not. Their commands come in as they arrive, and go in at the next tick\n *\n * @beta\n */\nexport class SessionHost {\n\tprivate readonly seats = new Set<Seat>()\n\tprivate accumulator = 0\n\tprivate sinceSent = Infinity\n\tprivate timer?: ReturnType<typeof setInterval>\n\tprivate last = 0\n\tprivate readonly sendEvery: number\n\t/** Simulation speed multiplier, 0 pauses */\n\tspeed = 1\n\n\tconstructor(\n\t\treadonly world: World,\n\t\toptions: SessionHostOptions = {}\n\t) {\n\t\tthis.sendEvery = 1 / (options.sendRate ?? 20)\n\t\tthis.maxTicks = options.maxTicksPerUpdate ?? 8\n\t\tthis.onSlowTick = options.onSlowTick\n\t\tthis.ownsWorld = options.ownsWorld ?? false\n\t\tthis.dropSilentAfter = options.dropSilentAfter ?? 15\n\t\tthis.keptEvents = options.keptEvents ?? 600\n\t\tthis.keptFrames = Math.max(2, options.keptFrames ?? KEPT_FRAMES)\n\t\tthis.keptBytes = Math.max(1, options.keptBytes ?? KEPT_BYTES)\n\t\tthis.groundPart = Math.max(1, options.groundPart ?? GROUND_PART)\n\t\tthis.byKey = options.bytesByKey ?? false\n\t\tthis.timing = emptyTiming(performance.now(), this.byKey)\n\t\tthis.onError = options.onError\n\t\t// a game that ends on an error says so to everyone at it, once\n\t\tthis.stopFailed = world.events.on(worldFailed, (failure) => {\n\t\t\tfor (const seat of this.seats) this.post(seat, { type: 'failed', message: failure.message })\n\t\t})\n\t}\n\n\tprivate readonly onError?: (error: unknown) => void\n\tprivate readonly stopFailed: () => void\n\n\tprivate readonly dropSilentAfter: number\n\tprivate readonly keptFrames: number\n\tprivate readonly keptBytes: number\n\tprivate readonly groundPart: number\n\tprivate readonly keptEvents: number\n\t/** Whether the characters sent are counted by what they carry (`bytesByKey`) */\n\tprivate readonly byKey: boolean\n\n\tprivate readonly ownsWorld: boolean\n\n\tprivate readonly maxTicks: number\n\tprivate readonly onSlowTick?: (milliseconds: number, tick: number) => void\n\n\t/**\n\t * Seats a player at the world, on the host's end of a transport. The welcome goes out at once: everything the player\n\t * may know, also to one who comes back. `readOnly` for who only watches: their commands go nowhere but their lines\n\t * of chat and their pings, which go to who watches alone (`observers`, said by `name`); and with `observer` they see\n\t * everything, from `player`'s side. `allow` decides on each command before it goes in: a limit of how many, a game\n\t * paused. One it lets go is answered, refused (the `command` event of its `seq`): with what it gives for why, or\n\t * `cannotDoThat` for `false`\n\t */\n\tconnect(\n\t\tplayer: PlayerId,\n\t\ttransport: Transport,\n\t\toptions: { readOnly?: boolean; observer?: boolean; allow?: () => boolean | MessageRef; name?: string } = {}\n\t): void {\n\t\tconst session = new LocalSession(this.world, player, { observer: options.observer })\n\t\tconst seat: Seat = {\n\t\t\ttransport,\n\t\t\tsession,\n\t\t\tframes: new Map(),\n\t\t\tframeSizes: new Map(),\n\t\t\tkeptBytes: 0,\n\t\t\tacked: -1,\n\t\t\theardUpTo: -1,\n\t\t\tevents: [],\n\t\t\teventsMade: 0,\n\t\t\tsentAt: new Map(),\n\t\t\troundTrip: 100,\n\t\t\theard: this.world.tick,\n\t\t\tanswers: [],\n\t\t\tgroundSent: new Set()\n\t\t}\n\t\tthis.seats.add(seat)\n\t\ttransport.onMessage((text) => {\n\t\t\t// the player's word, of any shape: what is not as it should be is dropped (a command's fields are checked\n\t\t\t// further on, by its definition)\n\t\t\tconst message = readMessage(text)\n\t\t\tif (!message) return\n\t\t\tif (message.type === 'ack') {\n\t\t\t\tif (isFiniteNumber(message.tick)) this.acknowledge(seat, message.tick, isFiniteNumber(message.events) ? message.events : undefined)\n\t\t\t} else if (message.type === 'ping') {\n\t\t\t\tif (isFiniteNumber(message.at)) this.post(seat, { type: 'pong', at: message.at })\n\t\t\t} else if (message.type === 'ground') {\n\t\t\t\t// a part of the ground the world started as, one at a time as asked: never more than a part waits to go\n\t\t\t\t// (each part once: a screen asks for each once, and the ground is many times what asks for it, RV37)\n\t\t\t\tconst parts = this.groundParts()\n\t\t\t\tconst { part } = message\n\t\t\t\tif (parts && Number.isInteger(part) && (part as number) >= 0 && (part as number) < parts.length && !seat.groundSent.has(part as number)) {\n\t\t\t\t\tseat.groundSent.add(part as number)\n\t\t\t\t\tthis.post(seat, { type: 'ground', part: part as number, parts: parts.length, text: parts[part as number] })\n\t\t\t\t}\n\t\t\t} else if (message.type === 'debug') {\n\t\t\t\t// only a player the world lets use the debug tools (`world.debugPlayers`): anyone can send anything\n\t\t\t\tif (!this.world.debugPlayers.has(player)) return\n\t\t\t\tseat.debug ??= { view: new LocalDebug(this.world), sentAt: -Infinity }\n\t\t\t\taskDebug(seat.debug.view, message)\n\t\t\t\tseat.debug.sentAt = -Infinity\n\t\t\t} else if (message.type === 'command' && options.readOnly) {\n\t\t\t\t// who watches says a line or marks a spot, for who watches alone: nothing else of theirs goes in\n\t\t\t\tconst { command } = message\n\t\t\t\tif (!isCommand(command) || (command.type !== 'chat' && command.type !== 'ping')) return\n\t\t\t\tsession.send({ ...command, to: 'observers', by: options.name ?? 'A watcher' } as PlayerCommand)\n\t\t\t\tthis.heardOutside = true\n\t\t\t} else if (message.type === 'command') {\n\t\t\t\t// every command counts against the limit, one of no shape as well (RV37)\n\t\t\t\tconst allowed = options.allow?.() ?? true\n\t\t\t\tconst seq = isFiniteNumber(message.seq) ? message.seq : undefined\n\t\t\t\tif (!isCommand(message.command)) return\n\t\t\t\t// what who watches says is theirs: a player's line to them would tell them what the side knows\n\t\t\t\tif ((message.command.type === 'chat' || message.command.type === 'ping') && (message.command as { to?: unknown }).to === 'observers') return\n\t\t\t\tif (allowed === true) {\n\t\t\t\t\tsession.send(message.command, seq)\n\t\t\t\t\t// talk, carried out at once: told now, a paused game's too (RV14)\n\t\t\t\t\tif (this.world.registry.command(message.command.type)?.outsideTick) this.heardOutside = true\n\t\t\t\t}\n\t\t\t\t// one let go is answered, refused: a screen waits on its number otherwise (RV14)\n\t\t\t\telse if (seq !== undefined) seat.answers.push({ type: 'command', seq, refusal: allowed ? toMessage(allowed) : { key: 'cannotDoThat' } })\n\t\t\t}\n\t\t})\n\t\ttransport.onClose(() => this.leave(seat))\n\t\tconst { registry } = this.world\n\t\tthis.post(seat, {\n\t\t\ttype: 'welcome',\n\t\t\tprotocol: PROTOCOL_VERSION,\n\t\t\tplayer,\n\t\t\ttickRate: this.world.tickRate,\n\t\t\tgame: registry.game,\n\t\t\thash: registry.dataHash,\n\t\t\t// the cells changed out of the player's sight as their team last saw them (RV7)\n\t\t\tterrain: savedGround(\n\t\t\t\tgroundKnownTo(this.world, options.observer ? undefined : this.world.player(player).team),\n\t\t\t\tthis.world.ground,\n\t\t\t\tthis.world.registry.module?.maps,\n\t\t\t\tthis.world.registry.module ?? {}\n\t\t\t),\n\t\t\t...(this.world.map.environment && { environment: this.world.map.environment }),\n\t\t\t...(this.world.map.doodads.length > 0 && { doodads: [...this.world.map.doodads] }),\n\t\t\t...(this.world.map.regions.length > 0 && { regions: [...this.world.map.regions] }),\n\t\t\t...(this.world.map.cameras.length > 0 && { cameras: [...this.world.map.cameras] }),\n\t\t\t...(this.world.map.paths.length > 0 && { paths: [...this.world.map.paths] }),\n\t\t\t// (looked at, not made: a world nothing was changed of has none, nor its save)\n\t\t\t...(this.world.states.has(redefinitions) && { redefinitions: structuredClone(this.world.state(redefinitions)) }),\n\t\t\tfirst: this.deltaFor(seat),\n\t\t\t...(options.observer ? { observer: true } : {}),\n\t\t\t...(this.world.debugPlayers.has(player) && { debug: true })\n\t\t})\n\t}\n\n\t/** The ground the world started as, whole, in parts small enough to go one at a time: made the first time one is asked for */\n\tprivate groundParts(): string[] | undefined {\n\t\tconst base = this.world.ground\n\t\tif (!base) return undefined\n\t\tif (!this.ground) {\n\t\t\tconst text = JSON.stringify(saveTerrain(base.terrain))\n\t\t\tthis.ground = []\n\t\t\tfor (let i = 0; i < text.length; i += this.groundPart) this.ground.push(text.slice(i, i + this.groundPart))\n\t\t}\n\t\treturn this.ground\n\t}\n\n\tprivate ground?: string[]\n\n\t/** The player has the frame of `tick`: what comes next is made against it, and what it has is not sent again */\n\tprivate acknowledge(seat: Seat, tick: number, events?: number): void {\n\t\t// the batches of events it says it got, the talk between two ticks too\n\t\tif (events !== undefined) seat.events = seat.events.filter((sent) => sent.n > events)\n\t\t// (never a tick not there yet: what is said to be had is let go)\n\t\tif (tick <= seat.heardUpTo || tick > this.world.tick) return\n\t\t// heard, whether the frame it got is still kept or was let go: a player whose answers take longer than the frames\n\t\t// kept last still answers, and is not let go as silent (RV11)\n\t\tseat.heardUpTo = tick\n\t\tseat.heard = this.world.tick\n\t\tconst sent = seat.sentAt.get(tick) ?? (seat.whole?.tick === tick ? seat.whole.at : undefined)\n\t\tif (sent !== undefined) seat.roundTrip += (performance.now() - sent - seat.roundTrip) * 0.2\n\t\tif (seat.whole && tick >= seat.whole.tick) seat.whole = undefined\n\t\tfor (const kept of seat.sentAt.keys()) if (kept <= tick) seat.sentAt.delete(kept)\n\t\tseat.events = seat.events.filter((sent) => sent.tick > tick)\n\t\t// a base for the deltas from now on, where its frame is still kept\n\t\tif (!seat.frames.has(tick)) return\n\t\tseat.acked = tick\n\t\tfor (const kept of [...seat.frames.keys()]) if (kept < tick) this.forget(seat, kept)\n\t}\n\n\t/**\n\t * Whether a player is sent nothing this round: it has no frame kept to make a delta against, and the whole one it\n\t * was sent last is on its way still. Another would be as big, and come no sooner than the answer to the first\n\t */\n\tprivate holding(seat: Seat, now: number): boolean {\n\t\treturn !!seat.whole && !seat.frames.has(seat.acked) && now - seat.whole.at <= seat.roundTrip * 1.5 + this.sendEvery * 1000\n\t}\n\n\tprivate leave(seat: Seat): void {\n\t\tif (!this.seats.delete(seat)) return\n\t\tseat.session.dispose()\n\t\tseat.debug?.view.dispose()\n\t\t// running by the clock for nobody: stops, until someone connects and it is started again\n\t\tif (this.seats.size === 0) this.stop()\n\t}\n\n\t/** How many players are connected */\n\tget players(): number {\n\t\treturn this.seats.size\n\t}\n\n\t/**\n\t * How much the host keeps for each connected player, for a test of its limits (`keptFrames`, `keptEvents`): the\n\t * frames it may make a delta against, when each was sent, and the events not yet said to be had\n\t *\n\t * @internal\n\t */\n\tkept(): { frames: number; bytes: number; sentAt: number; events: number }[] {\n\t\treturn [...this.seats].map((seat) => ({ frames: seat.frames.size, bytes: seat.keptBytes, sentAt: seat.sentAt.size, events: seat.events.length }))\n\t}\n\n\tprivate post(seat: Seat, message: GameHostMessage): void {\n\t\tseat.transport.send(JSON.stringify(message))\n\t}\n\n\t/** Lets `dt` seconds pass: the ticks that fit into it, then what changed to everyone, when it is time to send */\n\tupdate(dt: number): void {\n\t\tconst { world } = this\n\t\tlet stepped = false\n\t\tthis.accumulator += dt * this.speed * world.cheats.speed\n\t\tthis.sinceSent += dt\n\t\tlet ticks = 0\n\t\twhile (this.accumulator >= world.dt) {\n\t\t\tif (ticks++ >= this.maxTicks) {\n\t\t\t\t// too far behind to catch up: the rest is let go\n\t\t\t\tthis.accumulator = 0\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tconst began = performance.now()\n\t\t\tworld.step()\n\t\t\tconst took = performance.now() - began\n\t\t\tconst { timing, totals } = this\n\t\t\ttiming.ticks++\n\t\t\ttiming.tickTime += took\n\t\t\ttiming.tickMax = Math.max(timing.tickMax, took)\n\t\t\ttotals.ticks++\n\t\t\ttotals.tickTime += took\n\t\t\ttotals.lastTick = took\n\t\t\tif (took > world.dt * 1000) this.onSlowTick?.(took, world.tick)\n\t\t\tthis.accumulator -= world.dt\n\t\t\tstepped = true\n\t\t}\n\t\t// talk heard between ticks goes out with no tick to wait for: a paused game's too (RV14)\n\t\tif (stepped || this.heardOutside) this.sendDue()\n\t}\n\n\t/** What the debug tools of a seat follow, as the world stands: when they follow, list or log anything */\n\tprivate sendDebug(seat: Seat, debug: NonNullable<Seat['debug']>, now: number): void {\n\t\tdebug.sentAt = now\n\t\tconst { view } = debug\n\t\tview.refresh()\n\t\tif (!view.inspection && !view.world && !view.logging) return\n\t\tthis.post(seat, { type: 'debug', inspection: view.inspection, world: view.world, log: view.logging ? [...view.log()] : [] })\n\t}\n\n\t/** Moves the game on by `ticks` at the next update, however fast it goes: a step of a held game (`speed` 0) */\n\tadvance(ticks = 1): void {\n\t\tthis.accumulator += this.world.dt * Math.max(0, Math.floor(ticks))\n\t}\n\n\t/**\n\t * Sends everyone what changed, when it is time to, for a world something else steps: the page's own game, shared with\n\t * those who watch it (`shareGame`). `dt` is the seconds since the last call. Nothing goes while the world stands still\n\t */\n\tpublish(dt: number): void {\n\t\tthis.sinceSent += dt\n\t\tif (this.world.tick !== this.sentTick || this.heardOutside) this.sendDue()\n\t}\n\n\t/** The tick what changed went out at last */\n\tprivate sentTick = -1\n\t/** Talk was carried out since what changed went out last: it goes out with no tick to wait for (RV14) */\n\tprivate heardOutside = false\n\n\t/** What changed to everyone, when the rate allows */\n\tprivate sendDue(): void {\n\t\tif (this.sinceSent < this.sendEvery) return\n\t\tthis.sentTick = this.world.tick\n\t\tthis.heardOutside = false\n\t\t// what was over carries on to the next: updates a tick apart still send at the rate asked, on average\n\t\tthis.sinceSent = Math.min(this.sinceSent - this.sendEvery, this.sendEvery)\n\t\tconst began = performance.now()\n\t\tconst silent = this.dropSilentAfter * this.world.tickRate\n\t\t// every seat is captured from the same world: what everyone is told of an entity is described once between them\n\t\tshareCaptures(this.world)\n\t\tthis.roundEntities = []\n\t\ttry {\n\t\t\tfor (const seat of [...this.seats]) {\n\t\t\t\t// one who has said nothing for long is let go: everything it was not sent again would pile up for it\n\t\t\t\tif (this.world.tick - seat.heard > silent) {\n\t\t\t\t\tseat.transport.close()\n\t\t\t\t\tthis.leave(seat)\n\t\t\t\t} else if (!this.holding(seat, began)) {\n\t\t\t\t\tconst delta = this.deltaFor(seat)\n\t\t\t\t\tconst made = performance.now()\n\t\t\t\t\tconst text = JSON.stringify({ type: 'delta', ...delta } satisfies GameHostMessage)\n\t\t\t\t\tthis.timing.parts.stringify += performance.now() - made\n\t\t\t\t\tthis.timing.bytes += text.length\n\t\t\t\t\tif (this.timing.keys) bytesByKey(delta, text, this.timing.keys)\n\t\t\t\t\tseat.transport.send(text)\n\t\t\t\t}\n\t\t\t\tif (seat.debug && began - seat.debug.sentAt >= DEBUG_EVERY) this.sendDebug(seat, seat.debug, began)\n\t\t\t}\n\t\t} finally {\n\t\t\tendSharedCaptures(this.world)\n\t\t\tthis.roundEntities = []\n\t\t}\n\t\tconst took = performance.now() - began\n\t\tconst { timing, totals } = this\n\t\ttiming.sends++\n\t\ttiming.sendTime += took\n\t\ttiming.sendMax = Math.max(timing.sendMax, took)\n\t\ttotals.sends++\n\t\ttotals.sendTime += took\n\t}\n\n\t/**\n\t * Where the host's time went since it was last asked (`takeTiming`): ticks of the simulation, and rounds of sending\n\t * everyone what changed (the snapshots, the diffs, the JSON), each in milliseconds, added up and at most\n\t */\n\tprivate timing: HostTiming\n\n\t/**\n\t * Where the host's time went since it started, never counted anew: ticks and rounds of sending, with the\n\t * milliseconds they took, and how long the last tick took. What a server's numbers are made of (`/metrics`)\n\t */\n\treadonly totals = { ticks: 0, tickTime: 0, lastTick: 0, sends: 0, sendTime: 0 }\n\n\t/** Where the time went since the last call, and starts counting anew: for a server to print */\n\ttakeTiming(): HostTiming & { seconds: number } {\n\t\tconst now = performance.now()\n\t\tconst timing = { ...this.timing, seconds: (now - this.timing.since) / 1000 }\n\t\tthis.timing = emptyTiming(now, this.byKey)\n\t\treturn timing\n\t}\n\n\t/** The lists of entities told this round so far, and what each was sent as, for the seats told the same to share one (`quantizedList`) */\n\tprivate roundEntities: { told: readonly EntityState[]; sent: EntityState[] }[] = []\n\n\t/** What the player knows now, as what changed since the tick they last said they got */\n\tprivate deltaFor(seat: Seat): Delta {\n\t\tconst { session } = seat\n\t\tconst { parts } = this.timing\n\t\tconst began = performance.now()\n\t\tconst snapshot = session.snapshot()\n\t\tconst captured = performance.now()\n\t\tconst told = seat.answers.length ? [...snapshot.events, ...seat.answers.splice(0)] : snapshot.events\n\t\tif (told.length) seat.events.push({ tick: snapshot.tick, n: ++seat.eventsMade, events: told })\n\t\t// a player who hears but does not answer: the oldest that went already are let go\n\t\tlet over = seat.events.length - this.keptEvents\n\t\twhile (over-- > 0 && seat.events[0].sentAt !== undefined) seat.events.shift()\n\t\tconst entities = quantizedList(snapshot.entities, this.roundEntities)\n\t\tconst quantized = performance.now()\n\t\tconst fog = fogMessageOf(session.fog())\n\t\tconst fogged = performance.now()\n\t\tconst frame: Frame = {\n\t\t\tsnapshot: { ...snapshot, entities, events: [] },\n\t\t\tfog,\n\t\t\tcamps: session.camps().map((camp) => ({ ...camp })),\n\t\t\tteam: session.team\n\t\t}\n\t\t// events go once, and again only when the answer that they got there is overdue: lost on the way\n\t\tconst now = performance.now()\n\t\tconst overdue = seat.roundTrip * 1.5 + this.sendEvery * 1000\n\t\tconst events = seat.events.filter((sent) => sent.sentAt === undefined || now - sent.sentAt > overdue)\n\t\tfor (const sent of events) sent.sentAt = now\n\t\tconst base = seat.frames.get(seat.acked)\n\t\tconst delta: Delta = {\n\t\t\t...diff(base, frame, this.world.registry),\n\t\t\tevents: events.map(({ tick, n, events }) => ({ tick, n, events }))\n\t\t}\n\t\tif (!base) seat.whole = { tick: frame.snapshot.tick, at: now }\n\t\tparts.capture += captured - began\n\t\tparts.quantize += quantized - captured\n\t\tparts.fog += fogged - quantized\n\t\tparts.diff += performance.now() - fogged\n\t\tthis.keep(seat, frame)\n\t\tseat.sentAt.set(frame.snapshot.tick, now)\n\t\tif (seat.sentAt.size > this.keptFrames) seat.sentAt.delete(seat.sentAt.keys().next().value!)\n\t\treturn delta\n\t}\n\n\t/**\n\t * Keeps the frame a player was sent, to make the next delta against: the oldest let go past `keptFrames` of them or\n\t * `keptBytes` together, the newest kept whatever it takes. A player who says nothing for long is sent everything\n\t * again, once its base is no longer kept\n\t */\n\tprivate keep(seat: Seat, frame: Frame): void {\n\t\tconst { tick } = frame.snapshot\n\t\tconst bytes = frameBytes(frame)\n\t\tseat.frames.set(tick, frame)\n\t\tseat.frameSizes.set(tick, bytes)\n\t\tseat.keptBytes += bytes\n\t\twhile (seat.frames.size > 1 && (seat.frames.size > this.keptFrames || seat.keptBytes > this.keptBytes))\n\t\t\tthis.forget(seat, seat.frames.keys().next().value!)\n\t}\n\n\t/** Lets go of a frame kept for a player */\n\tprivate forget(seat: Seat, tick: number): void {\n\t\tif (!seat.frames.delete(tick)) return\n\t\tseat.keptBytes -= seat.frameSizes.get(tick) ?? 0\n\t\tseat.frameSizes.delete(tick)\n\t}\n\n\t/** Runs the world by the clock, `rate` updates a second, until `stop` or `dispose` */\n\tstart(rate = this.world.tickRate): void {\n\t\tthis.stop()\n\t\tthis.last = performance.now()\n\t\tthis.timer = setInterval(() => {\n\t\t\tconst now = performance.now()\n\t\t\t// a tab in the background is held back: it catches up a little at a time, not all at once\n\t\t\tconst dt = Math.min((now - this.last) / 1000, 0.25)\n\t\t\tthis.last = now\n\t\t\ttry {\n\t\t\t\tthis.update(dt)\n\t\t\t} catch (error) {\n\t\t\t\t// thrown out of a timer, it would end the process, and every other game with it: the host stops here\n\t\t\t\tthis.stop()\n\t\t\t\tif (this.onError) this.onError(error)\n\t\t\t\telse this.world.log.error('server', 'stepping the game threw: it is stopped', { error: errorFields(error) })\n\t\t\t}\n\t\t}, 1000 / rate)\n\t}\n\n\tstop(): void {\n\t\tif (this.timer !== undefined) clearInterval(this.timer)\n\t\tthis.timer = undefined\n\t}\n\n\t/** Whether it runs by the clock */\n\tget running(): boolean {\n\t\treturn this.timer !== undefined\n\t}\n\n\t/** Stops, and closes every connection. The world goes too, when it is the host's (`ownsWorld`) */\n\t/**\n\t * Stops, and lets every player go: their connections closed, unless `closeTransports` is false (a server that keeps\n\t * them for its lobby, after the game)\n\t */\n\tdispose(options: { closeTransports?: boolean } = {}): void {\n\t\tthis.stop()\n\t\tthis.stopFailed()\n\t\tfor (const seat of [...this.seats]) {\n\t\t\tif (options.closeTransports !== false) seat.transport.close()\n\t\t\tthis.leave(seat)\n\t\t}\n\t\tif (this.ownsWorld) this.world.dispose()\n\t}\n}\n\n// ---- the player's side\n\n/** A structure the player knows of, as it stands on their copy of the map */\ninterface Known {\n\tcellX: number\n\tcellZ: number\n\tw: number\n\td: number\n\t/** The kind of resource it is, for a resource: what a building that goes up on one looks for (`builtOn`) */\n\tresource?: string\n}\n\n/**\n * What the player's side keeps of the map, to answer the screen without asking the host: a placement grid and the\n * ways to walk of the map as it was made, with the structures the player has seen on them. What they have not seen\n * is not there: a path preview never goes around a building in the dark, and gives it away\n */\nexport class ClientWorld {\n\treadonly grid: BuildGrid\n\tprivate readonly known = new Map<number, Known>()\n\tprivate readonly seen = new Set<number>()\n\n\tconstructor(\n\t\treadonly terrain: Terrain,\n\t\tprivate readonly registry: Registry,\n\t\treadonly nav: Navigation,\n\t\treadonly air: Navigation\n\t) {\n\t\tthis.grid = new BuildGrid(terrain)\n\t}\n\n\t/** Whether a resource of a kind that it knows of covers just this ground, with nothing it knows of standing on it */\n\tresourceAt(kind: string, cellX: number, cellZ: number, w: number, d: number): boolean {\n\t\tlet found = false\n\t\tfor (const structure of this.known.values()) {\n\t\t\tif (structure.cellX !== cellX || structure.cellZ !== cellZ || structure.w !== w || structure.d !== d) continue\n\t\t\tif (structure.resource !== kind) return false\n\t\t\tfound = true\n\t\t}\n\t\treturn found\n\t}\n\n\t/** Brings the structures up to date with a snapshot: those in it stand, those no longer in it are gone */\n\tsync(snapshot: Snapshot): void {\n\t\tconst { seen, known, grid, nav } = this\n\t\tseen.clear()\n\t\tlet changed = false\n\t\tfor (const entity of snapshot.entities) {\n\t\t\tif (!this.registry.units.has(entity.type)) continue\n\t\t\tconst def = this.registry.unit(entity.type)\n\t\t\tif (!def.footprint) continue\n\t\t\tseen.add(entity.id)\n\t\t\tif (known.has(entity.id)) continue\n\t\t\tconst site = siteOf(def, entity)\n\t\t\tconst { w, d } = footprintOf(def)\n\t\t\tknown.set(entity.id, { cellX: site.cellX, cellZ: site.cellZ, w, d, ...(def.resource && { resource: def.resource.kind }) })\n\t\t\tgrid.occupy(site.cellX, site.cellZ, w, d, entity.id)\n\t\t\t// what blocks the way is what the host treats as an obstacle: every structure, trees and mines too\n\t\t\tnav.addObstacle(entity.id, site)\n\t\t\tchanged = true\n\t\t}\n\t\tlet released = false\n\t\tfor (const [id, structure] of known) {\n\t\t\tif (seen.has(id)) continue\n\t\t\tknown.delete(id)\n\t\t\tgrid.release(structure.cellX, structure.cellZ, structure.w, structure.d, id)\n\t\t\tnav.removeObstacle(id)\n\t\t\tchanged = released = true\n\t\t}\n\t\t// what stood on another (a cursed mine on a gold mine) gave it its ground back\n\t\tif (released) for (const [id, structure] of known) grid.occupy(structure.cellX, structure.cellZ, structure.w, structure.d, id)\n\t\t// the navmesh takes in what changed as it updates\n\t\tif (changed) nav.update(0)\n\t}\n}\n\n/**\n * The host said no, with why: to come back to a game that is over, or a player let go. Trying again does not help\n *\n * @beta\n */\nexport class SessionRefused extends Error {\n\tconstructor(readonly reason: string) {\n\t\tsuper(reason)\n\t\tthis.name = 'SessionRefused'\n\t}\n}\n\n/**\n * A player's seat at a world that runs elsewhere, over a transport (see `connect`). It rebuilds what the host sends\n * as changes (`Delta`) into whole snapshots, keeping the objects of what did not change, says which ticks it got, and\n * answers the screen's questions from those and its own copy of the map (`ClientWorld`). No debug access, and no\n * checkpoints: those belong to a simulation in the page\n *\n * @beta\n */\nexport class RemoteSession implements GameSession {\n\t/**\n\t * A seat over a wire can none of what a game in this page can (`SessionCan`), but the debug tools' view of the world\n\t * for a player the host lets use them (`inspect`, said over the wire)\n\t */\n\treadonly can: SessionCan\n\t/** The debug tools' view of the world, for a player the host lets use them (the welcome's `debug`) */\n\tprotected get debugView(): SessionDebug | undefined {\n\t\treturn this.remoteDebug\n\t}\n\tprivate readonly remoteDebug?: RemoteDebug\n\treadonly playerId: PlayerId\n\tteam: number\n\treadonly terrain: Terrain\n\treadonly environment?: MapEnvironment\n\treadonly doodads: readonly MapDoodad[]\n\treadonly regions: readonly MapRegion[]\n\treadonly cameras: readonly MapCamera[]\n\treadonly paths: readonly MapPath[]\n\treadonly registry: Registry\n\treadonly tickRate: number\n\talpha = 1\n\n\t/** What the player knows by tick, for the deltas to come: from the base of the last one on */\n\tprivate readonly frames = new Map<number, Frame>()\n\tprivate latest: Frame\n\tprivate readonly incoming: Snapshot[] = []\n\t/** What the host's definitions were changed to while it ran (`world.redefine`), as this screen heard it */\n\tprivate readonly redefined: GameData = {}\n\n\t/** The number of the last batch of events that went to the screen (`Delta.events`): those sent again are not applied twice */\n\tprivate eventsUpTo = -1\n\tprivate readonly fogState: FogState\n\tprivate closed = false\n\n\t/*\n\t * The interpolation buffer. The screen is shown a little behind the newest snapshot (`delay` ticks), always between\n\t * two it has, so that what moves goes on moving smoothly however unevenly the snapshots arrive. Its own clock\n\t * (`renderTick`) follows the host's: a little faster when it falls behind, a little slower when it gets ahead, and\n\t * a jump when it is far off\n\t */\n\t/** The tick the screen shows, between the last two snapshots given out */\n\tprivate renderTick?: number\n\t/** The tick of the snapshot given out last, and of the one before it */\n\tprivate shownTick: number\n\tprivate shownBefore: number\n\t/** Ticks between two snapshots, evened out */\n\tprotected interval = 1\n\t/** How far off the time snapshots arrive at is from the ticks between them, in seconds, evened out */\n\tprotected jitter = 0\n\t/** When the last snapshot arrived, and its tick */\n\tprivate arrival?: { at: number; tick: number }\n\n\tconstructor(\n\t\tprivate transport: Transport,\n\t\twelcome: Extract<GameHostMessage, { type: 'welcome' }>,\n\t\tregistry: Registry,\n\t\tprivate readonly map: ClientWorld,\n\t\t/** How much it keeps and how often it asks (`ConnectOptions`) */\n\t\tprotected readonly limits: PlayerLimits = {}\n\t) {\n\t\tthis.playerId = welcome.player\n\t\tthis.tickRate = welcome.tickRate\n\t\tthis.observer = welcome.observer ?? false\n\t\tthis.remoteDebug = welcome.debug ? new RemoteDebug((ask) => this.tell({ type: 'debug', ...ask })) : undefined\n\t\tthis.can = this.remoteDebug ? { inspect: this.remoteDebug } : {}\n\t\tthis.registry = registry\n\t\tthis.terrain = map.terrain\n\t\tthis.environment = welcome.environment\n\t\tthis.doodads = welcome.doodads ?? []\n\t\tthis.regions = welcome.regions ?? []\n\t\tthis.cameras = welcome.cameras ?? []\n\t\tthis.paths = welcome.paths ?? []\n\t\t// what the definitions were changed to before this player came, before anything is made of them\n\t\trestoreRedefinitions(registry, welcome.redefinitions)\n\t\tthis.heardRedefined(welcome.redefinitions)\n\t\tconst cells = this.terrain.width * this.terrain.depth\n\t\tthis.fogState = {\n\t\t\twidth: this.terrain.width,\n\t\t\tdepth: this.terrain.depth,\n\t\t\tversion: 0,\n\t\t\trevealed: false,\n\t\t\tvisible: new Uint8Array(cells),\n\t\t\texplored: new Uint8Array(cells)\n\t\t}\n\t\tconst first = this.take(welcome.first)!\n\t\tthis.latest = first\n\t\tthis.team = first.team\n\t\t// the events that came with it are in the first snapshot the screen asks for\n\t\tthis.incoming.length = 0\n\t\tthis.shownTick = this.shownBefore = first.snapshot.tick\n\t\tthis.attach(transport)\n\t}\n\n\t/** Talks through a transport from now on: what comes in is taken, and its closing is a drop */\n\tprivate attach(transport: Transport): void {\n\t\tthis.transport = transport\n\t\tthis.closed = false\n\t\tthis.leaving = false\n\t\ttransport.onMessage((text) => {\n\t\t\tconst message = readHostMessage(text)\n\t\t\tif (message) this.receive(message)\n\t\t})\n\t\ttransport.onClose(() => {\n\t\t\t// one closed before it is not this one's to say\n\t\t\tif (this.transport !== transport) return\n\t\t\tthis.closed = true\n\t\t\tclearInterval(this.pinger)\n\t\t\tif (!this.leaving) this.onDisconnect?.()\n\t\t})\n\t\tthis.sendPing()\n\t\tclearInterval(this.pinger)\n\t\tthis.pinger = setInterval(() => this.sendPing(), this.limits.pingEvery ?? PING_EVERY)\n\t}\n\n\t/** Whether the host has gone */\n\tget disconnected(): boolean {\n\t\treturn this.closed\n\t}\n\n\t/**\n\t * Told when the connection drops, not by this side's leaving (`dispose`): to try again (`resume`), or to say the\n\t * game is lost\n\t */\n\tonDisconnect?: () => void\n\t/** This side closed it: not a drop */\n\tprivate leaving = false\n\n\t/**\n\t * Goes on with the same game over a new connection, once the host has welcomed it there again (a server does, to who\n\t * comes back with their seat's token): everything known sent again, and the screen catches up. What the host says\n\t * besides the game before the welcome goes to `onServer`; a `refused` fails it with the reason, as does a connection\n\t * that closes first, or a host that runs another game\n\t */\n\tasync resume(transport: Transport): Promise<void> {\n\t\tconst welcome = await new Promise<Extract<GameHostMessage, { type: 'welcome' }>>((resolve, reject) => {\n\t\t\ttransport.onClose(() => reject(new Error('The host closed the connection before it took the player back')))\n\t\t\ttransport.onMessage((text) => {\n\t\t\t\tconst message = readHostMessage(text)\n\t\t\t\tif (!message) return\n\t\t\t\tif (message.type === 'welcome') resolve(message)\n\t\t\t\telse if (message.type === 'refused') reject(new SessionRefused(String(message.reason ?? 'refused')))\n\t\t\t\telse if (isServerMessage(message)) this.onServer?.(message)\n\t\t\t})\n\t\t})\n\t\tconst problem = welcomeProblem(welcome as unknown as Record<string, unknown>)\n\t\tif (problem) {\n\t\t\ttransport.close()\n\t\t\tthrow new Error(problem)\n\t\t}\n\t\tif (welcome.game !== this.registry.game || welcome.hash !== this.registry.dataHash || welcome.player !== this.playerId) {\n\t\t\ttransport.close()\n\t\t\tthrow new Error('The host took the player back to another game')\n\t\t}\n\t\t// what the definitions were changed to while this side was away\n\t\trestoreRedefinitions(this.registry, welcome.redefinitions)\n\t\tthis.heardRedefined(welcome.redefinitions)\n\t\t// a seat of its own on the host: its batches of events are numbered from the first again\n\t\tthis.eventsUpTo = -1\n\t\t// talked through first, so that the host hears this side got the welcome\n\t\tthis.attach(transport)\n\t\t// everything again, from nothing: the frames before are no base for what comes\n\t\tthis.frames.clear()\n\t\tthis.incoming.length = 0\n\t\t// and the arrival clock with them: the first snapshot after the outage is not one tick after the last before it\n\t\tthis.arrival = undefined\n\t\tthis.interval = 1\n\t\tthis.jitter = 0\n\t\t// taken back to before what was shown (a replay gone back to its start): shown from there, and its events heard\n\t\t// again, or nothing older than what was shown would come out (`update`) and every event up to it would be skipped\n\t\tif (welcome.first.tick < this.shownTick) {\n\t\t\tthis.shownTick = this.shownBefore = welcome.first.tick\n\t\t\tthis.renderTick = undefined\n\t\t\tthis.eventsUpTo = welcome.first.tick - 1\n\t\t}\n\t\tthis.take(welcome.first)\n\t\t// the debug tools follow on the host it is served from now\n\t\tthis.remoteDebug?.askAgain()\n\t}\n\n\t/** Keeps what the host's definitions were changed to, over what was kept before */\n\tprivate heardRedefined(data: GameData | undefined): void {\n\t\tfor (const [kind, byId] of Object.entries(data ?? {}) as [DataKind, Record<string, DataValues>][])\n\t\t\tfor (const [id, values] of Object.entries(byId)) {\n\t\t\t\tconst kept = (this.redefined[kind] ??= {})\n\t\t\t\tkept[id] = mergeValues(kept[id] ?? {}, values)\n\t\t\t}\n\t}\n\n\t/**\n\t * Takes a new version of the game into this screen's registry (hot reload, a game in a worker): its definitions as\n\t * the new version has them, what the host changed of them while it ran over them again\n\t */\n\ttakeGame(game: GameModule): void {\n\t\tthis.registry.takeFrom(createRegistry(game))\n\t\trestoreRedefinitions(this.registry, this.redefined)\n\t}\n\n\t/** Takes in a message of the host's: what the transport hands it, and what came in while the session was made */\n\treceive(message: HostToPlayer): void {\n\t\tif (message.type === 'delta') this.take(message)\n\t\telse if (message.type === 'debug') this.remoteDebug?.take(message)\n\t\telse if (message.type === 'pong') {\n\t\t\tconst took = performance.now() - message.at\n\t\t\t// evened out, from the first answer on\n\t\t\tthis.ping = this.ping === undefined ? took : this.ping + (took - this.ping) * 0.3\n\t\t} else if (message.type === 'failed') {\n\t\t\tif (typeof message.message === 'string') this.failure = { message: message.message }\n\t\t} else if (isServerMessage(message)) {\n\t\t\t// a server's pause: who asked for it, and until when at most\n\t\t\tif (message.type === 'paused') {\n\t\t\t\tthis.pause =\n\t\t\t\t\tmessage.paused === true\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...(typeof message.player === 'number' && { player: message.player }),\n\t\t\t\t\t\t\t\t...(typeof message.seconds === 'number' && { until: Date.now() + message.seconds * 1000 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: null\n\t\t\t\tthis.onPause?.(this.pause)\n\t\t\t}\n\t\t\tthis.onServer?.(message)\n\t\t}\n\t}\n\n\t/**\n\t * The game paused by the server, for everyone: by a player (`player`, until a time at most, in `Date.now()`'s\n\t * milliseconds) or an admin (neither). Null while it goes on\n\t */\n\tpause: { player?: PlayerId; until?: number } | null = null\n\t/** Told each time the server pauses the game or lets it go on */\n\tonPause?: (pause: { player?: PlayerId; until?: number } | null) => void\n\n\t/** Says something to the server beside the game: a lobby's message (`{ type: 'resume' }`) */\n\ttell(message: { type: string } & Record<string, unknown>): void {\n\t\tif (!this.closed) this.transport.send(JSON.stringify(message))\n\t}\n\n\t/** Why the game ended on an error in its rules, once the host said so */\n\tfailure: { message: string } | null = null\n\n\t/** Milliseconds a message takes to the host and back, evened out: measured every couple of seconds */\n\tping?: number\n\t/** Whether the player only watches, and sees everything */\n\treadonly observer: boolean\n\tprivate pinger?: ReturnType<typeof setInterval>\n\n\t/** Asks the host to answer at once, to measure the time there and back */\n\tprivate sendPing(): void {\n\t\tif (!this.closed) this.transport.send(JSON.stringify({ type: 'ping', at: performance.now() } satisfies GameCommandMessage))\n\t}\n\n\t/** Told of what the host says besides the game: a server's messages (see `ConnectOptions.onServer`) */\n\tonServer?: ConnectOptions['onServer']\n\n\t/** Rebuilds the frame a delta makes, says it got it, and has its snapshot wait for the screen */\n\tprivate take(delta: Delta): Frame | undefined {\n\t\tconst base = delta.base === null ? undefined : this.frames.get(delta.base)\n\t\t// made against a frame this side no longer has: wait for one against what it said it got\n\t\tif (delta.base !== null && !base) return undefined\n\t\t// what did not change keeps the objects of the frame before, which the screen tells changes by\n\t\tconst frame = apply(base, delta, this.latest)\n\t\tconst { snapshot } = frame\n\t\tthis.frames.set(snapshot.tick, frame)\n\t\t// the host makes nothing against anything older than this base from now on\n\t\tfor (const tick of this.frames.keys()) if (delta.base !== null && tick < delta.base) this.frames.delete(tick)\n\t\tif (delta.rest.fog) this.takeFog(delta.rest.fog)\n\t\tif (delta.rest.team !== undefined) this.team = delta.rest.team\n\t\t// each batch of events once, however often it was sent: by its number, as talk goes between ticks too (RV14)\n\t\tconst events: SessionEvent[] = []\n\t\tfor (const sent of delta.events) {\n\t\t\tif (sent.n <= this.eventsUpTo) continue\n\t\t\tevents.push(...sent.events)\n\t\t\tthis.eventsUpTo = sent.n\n\t\t\t// what the ground says it is now: the cells of the game's layers set as the game runs; and the definitions\n\t\t\tfor (const event of sent.events) {\n\t\t\t\tif (event.type === 'redefined') {\n\t\t\t\t\tredefineIn(this.registry, event.kind, event.definition, event.values)\n\t\t\t\t\tthis.heardRedefined({ [event.kind]: { [event.definition]: event.values } })\n\t\t\t\t}\n\t\t\t\tif (event.type === 'ground' && !terrainPatchProblem(this.terrain, event.patch)) applyTerrainPatch(this.terrain, event.patch)\n\t\t\t\tif (event.type !== 'cells') continue\n\t\t\t\tconst layer = this.terrain.cellLayer(event.layer)\n\t\t\t\tfor (const c of event.at) if (c >= 0 && c < layer.length) layer[c] = event.value\n\t\t\t}\n\t\t}\n\t\tthis.incoming.push({ ...snapshot, events })\n\t\tif (this.incoming.length > (this.limits.keptSnapshots ?? KEPT_SNAPSHOTS)) this.fold()\n\t\tthis.arrived(snapshot.tick)\n\t\tthis.map.sync(snapshot)\n\t\tthis.latest = frame\n\t\tif (!this.closed) this.transport.send(JSON.stringify({ type: 'ack', tick: snapshot.tick, events: this.eventsUpTo } satisfies GameCommandMessage))\n\t\treturn frame\n\t}\n\n\t/**\n\t * The oldest snapshot waiting let go, its events put before the next one's: the screen, when it asks again, jumps\n\t * to the newest anyway. The state is in every snapshot; the events (deaths, sounds, lines said) are what would be lost\n\t */\n\tprivate fold(): void {\n\t\tconst oldest = this.incoming.shift()!\n\t\tif (!oldest.events.length) return\n\t\tconst next = this.incoming[0]\n\t\tconst events = oldest.events.concat(next.events)\n\t\tconst mostEvents = this.limits.keptScreenEvents ?? KEPT_SCREEN_EVENTS\n\t\tthis.incoming[0] = { ...next, events: events.length > mostEvents ? events.slice(-mostEvents) : events }\n\t}\n\n\t/**\n\t * Snapshots come in and not yet given to the screen (`update`): a few normally, never more than a few seconds of\n\t * them, however long the screen does not ask\n\t *\n\t * @beta\n\t */\n\tget waiting(): number {\n\t\treturn this.incoming.length\n\t}\n\n\tprivate takeFog(message: FogMessage): void {\n\t\tconst fog = this.fogState\n\t\tfog.revealed = message.revealed\n\t\tfromRuns(message.visible, fog.visible)\n\t\tfromRuns(message.explored, fog.explored)\n\t\tfog.version++\n\t}\n\n\tsnapshot(): Snapshot {\n\t\treturn this.latest.snapshot\n\t}\n\n\t/** The tick the screen is shown at, between two snapshots: behind the newest by `delay` */\n\tget shownAt(): number {\n\t\treturn this.renderTick ?? this.shownTick\n\t}\n\n\t/**\n\t * The ticks between two snapshots, and the jitter the interpolation makes room for, as it has them evened out. A\n\t * test may set the jitter, as a late line would have\n\t *\n\t * @internal\n\t */\n\tget pacing(): { interval: number; jitter: number } {\n\t\treturn { interval: this.interval, jitter: this.jitter }\n\t}\n\n\t/** @internal */\n\tset pacing(pacing: { jitter: number }) {\n\t\tthis.jitter = pacing.jitter\n\t}\n\n\t/** How far behind the newest snapshot the screen is shown, in ticks: about two snapshots, and room for the jitter */\n\tget delay(): number {\n\t\t// a spike of lateness (a tab in the background, a line that stalled) is not waited out for good: a fifth of a second at most\n\t\treturn this.interval * 2 + Math.min(this.jitter, this.limits.maxJitter ?? MAX_JITTER) * this.tickRate * 2\n\t}\n\n\t/** Takes note of when a snapshot arrived, for how far apart they come and how unevenly */\n\tprivate arrived(tick: number): void {\n\t\tconst now = performance.now()\n\t\tconst last = this.arrival\n\t\tthis.arrival = { at: now, tick }\n\t\tif (!last || tick <= last.tick) return\n\t\tconst ticks = tick - last.tick\n\t\tthis.interval += (ticks - this.interval) * 0.1\n\t\tconst off = Math.abs((now - last.at) / 1000 - ticks / this.tickRate)\n\t\tthis.jitter += (off - this.jitter) * 0.1\n\t}\n\n\t/**\n\t * Lets the screen's clock go on by `dt`, and gives out the snapshots it has come to, oldest first: the screen draws\n\t * between the last two (`alpha`). The time is the host's: the clock follows the snapshots, not the other way around\n\t */\n\tupdate(dt: number): Snapshot[] {\n\t\tconst newest = this.incoming.length ? this.incoming[this.incoming.length - 1].tick : this.shownTick\n\t\tconst target = newest - this.delay\n\t\tif (this.renderTick === undefined || Math.abs(target - this.renderTick) > this.tickRate) this.renderTick = target\n\t\telse {\n\t\t\t// a tenth faster or slower at most: nobody sees a clock catch up that way\n\t\t\tconst rate = 1 + Math.max(-0.1, Math.min((target - this.renderTick) * 0.05, 0.1))\n\t\t\tthis.renderTick += dt * this.tickRate * rate\n\t\t}\n\t\t// never past what has come in\n\t\tthis.renderTick = Math.min(this.renderTick, newest)\n\t\tconst out: Snapshot[] = []\n\t\t// the next one goes out once the screen has come to the one before it: it is drawn towards from there\n\t\twhile (this.incoming.length && this.renderTick >= this.shownTick) {\n\t\t\tconst next = this.incoming.shift()!\n\t\t\tthis.shownBefore = this.shownTick\n\t\t\tthis.shownTick = next.tick\n\t\t\tout.push(next)\n\t\t}\n\t\tconst span = this.shownTick - this.shownBefore\n\t\tthis.alpha = span > 0 ? Math.max(0, Math.min((this.renderTick - this.shownBefore) / span, 1)) : 1\n\t\treturn out\n\t}\n\n\tsend(command: PlayerCommand): number {\n\t\tconst seq = ++this.lastSeq\n\t\tif (!this.closed) this.transport.send(JSON.stringify({ type: 'command', seq, command } satisfies GameCommandMessage))\n\t\treturn seq\n\t}\n\n\t/** The number of the last command sent */\n\tprivate lastSeq = 0\n\n\tfog(): FogState {\n\t\treturn this.fogState\n\t}\n\n\tcamps(): readonly CampInfo[] {\n\t\treturn this.latest.camps\n\t}\n\n\t/**\n\t * Whether the player could build this here, as far as they can tell: on their copy of the map, with the structures\n\t * they know, on ground they have explored. The game's own say (the `canPlace` hook) is the host's: it may still refuse\n\t */\n\tcanPlace(unitType: string, point: Vec2): boolean {\n\t\tif (!this.registry.units.has(unitType)) return false\n\t\tconst def = this.registry.unit(unitType)\n\t\tconst site = siteOf(def, point)\n\t\tconst { w, d } = footprintOf(def)\n\t\t// on a resource of its kind that it knows of, with nothing on it yet; anywhere else, on free ground\n\t\tif (\n\t\t\tdef.builtOn !== undefined\n\t\t\t\t? !this.map.resourceAt(def.builtOn, site.cellX, site.cellZ, w, d)\n\t\t\t\t: !this.map.grid.canPlace(site.cellX, site.cellZ, w, d)\n\t\t)\n\t\t\treturn false\n\t\tconst fog = this.fogState\n\t\tif (fog.revealed) return true\n\t\tconst explored = (x: number, z: number) => fog.explored[Math.floor(z) * fog.width + Math.floor(x)] === 1\n\t\treturn (\n\t\t\texplored(site.x - site.hw + 0.5, site.z - site.hd + 0.5) &&\n\t\t\texplored(site.x + site.hw - 0.5, site.z - site.hd + 0.5) &&\n\t\t\texplored(site.x - site.hw + 0.5, site.z + site.hd - 0.5) &&\n\t\t\texplored(site.x + site.hw - 0.5, site.z + site.hd - 0.5)\n\t\t)\n\t}\n\n\t/** Which cells of a building's ground are in the way, as `canPlace` sees them: on the player's copy of the map, explored */\n\tplaceCells(unitType: string, point: Vec2): readonly boolean[] | undefined {\n\t\tif (!this.registry.units.has(unitType)) return undefined\n\t\tconst fog = this.fogState\n\t\treturn placementCells(\n\t\t\tthis.registry.unit(unitType),\n\t\t\tpoint,\n\t\t\t(x, z) => this.map.grid.canPlace(x, z, 1, 1),\n\t\t\tfog.revealed ? undefined : (x, z) => fog.explored[z * fog.width + x] === 1\n\t\t)\n\t}\n\n\t/** The way a unit would walk, on the player's copy of the map: around the structures they know, and no others */\n\tfindPath(from: Vec2, to: Vec2, flying = false): Vec2[] | null {\n\t\treturn (flying ? this.map.air : this.map.nav).findPath(from, to)\n\t}\n\n\tdispose(): void {\n\t\tclearInterval(this.pinger)\n\t\tthis.leaving = true\n\t\tif (!this.closed) this.transport.close()\n\t\tthis.closed = true\n\t\tthis.map.nav.dispose()\n\t\tthis.map.air.dispose()\n\t}\n}\n\n/** @beta */\nexport interface ConnectOptions {\n\t/**\n\t * The game module the host runs: the player's side needs its data, and checks it is the very same version. Or the\n\t * games the player has, by id, for a host that says which it runs\n\t */\n\tgame: GameModule | Record<string, GameModule>\n\tnavigation?: RecastNavigationOptions\n\t/** The maps the welcome's ground may be one of (S36): the game's own (`GameModule.maps`) when left out */\n\tmaps?: readonly GameMap[]\n\t/**\n\t * What the player's side keeps and how often it asks: `pingEvery`, `maxJitter`, `keptSnapshots`,\n\t * `keptScreenEvents` (`PlayerLimits`)\n\t *\n\t * @beta\n\t */\n\tlimits?: PlayerLimits\n\t/** What else the host says, before the game and during it: a server's lobby, a pause, the result */\n\tonServer?: (message: ServerToPlayer) => void\n}\n\n/** How much of the ground goes in one message, for a player who does not have its map: well under what a connection holds */\nconst GROUND_PART = 256 * 1024\n\n/**\n * The ground of a welcome: all of it, or the map it started as among the player's (S36), the changes put on it. A\n * player without that map asks the host for it, a part at a time, and puts the changes on what it is sent\n */\nasync function groundOfWelcome(\n\ttransport: Transport,\n\tground: SavedGround,\n\tmaps: readonly GameMap[] | undefined,\n\tgame: GameModule,\n\tearly: string[],\n\t/** Told of a close while the ground is sent, as the caller's own handler is put aside meanwhile */\n\tdropped: () => void\n): Promise<Terrain> {\n\ttry {\n\t\treturn groundOf(ground, maps, game).terrain\n\t} catch (error) {\n\t\tif (!(error instanceof MissingGround) || !isGroundChanges(ground)) throw error\n\t}\n\tconst whole = await new Promise<TerrainSave>((resolve, reject) => {\n\t\tconst parts: string[] = []\n\t\ttransport.onClose(() => {\n\t\t\tdropped()\n\t\t\treject(new Error('The host closed the connection while the ground was sent'))\n\t\t})\n\t\ttransport.onMessage((text) => {\n\t\t\tconst message = readHostMessage(text)\n\t\t\tif (message?.type !== 'ground') {\n\t\t\t\tearly.push(text)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tparts[message.part] = message.text\n\t\t\tif (message.part + 1 < message.parts) transport.send(JSON.stringify({ type: 'ground', part: message.part + 1 }))\n\t\t\telse {\n\t\t\t\ttransport.onMessage((later) => early.push(later))\n\t\t\t\tresolve(JSON.parse(parts.join('')) as TerrainSave)\n\t\t\t}\n\t\t})\n\t\ttransport.send(JSON.stringify({ type: 'ground', part: 0 }))\n\t})\n\treturn withChanges(loadTerrain(whole), ground)\n}\n\n/**\n * What is wrong with a welcome, before anything of it is used: another version of the wire (`PROTOCOL_VERSION`), or a\n * shape that is not one. What comes after it is the host's word, trusted as the welcome said it would be\n */\nfunction welcomeProblem(welcome: Record<string, unknown>): string | undefined {\n\tif (welcome.protocol !== PROTOCOL_VERSION) return protocolMismatch(welcome.protocol)\n\tconst good =\n\t\tNumber.isInteger(welcome.player) &&\n\t\tisFiniteNumber(welcome.tickRate) &&\n\t\t(welcome.tickRate as number) > 0 &&\n\t\ttypeof welcome.game === 'string' &&\n\t\ttypeof welcome.hash === 'string' &&\n\t\ttypeof welcome.terrain === 'object' &&\n\t\twelcome.terrain !== null &&\n\t\ttypeof welcome.first === 'object' &&\n\t\twelcome.first !== null\n\treturn good ? undefined : 'The host sent a welcome this player cannot read'\n}\n\n/**\n * Connects to a host over a transport (the player's end of it), and waits for the welcome: what the session is\n * made of. Fails when the host runs another version of the game, or of the engine's wire (`PROTOCOL_VERSION`), and\n * when the connection closes before the session is made: while the map is made from the welcome too\n *\n * @beta\n */\nexport function connect(transport: Transport, options: ConnectOptions): Promise<RemoteSession> {\n\treturn connectAs(transport, options, (...made) => new RemoteSession(...made))\n}\n\n/** `connect`, for a session of a kind of its own: `make` is given what a `RemoteSession` is made of */\nexport async function connectAs<S extends RemoteSession>(\n\ttransport: Transport,\n\toptions: ConnectOptions,\n\tmake: (...made: ConstructorParameters<typeof RemoteSession>) => S\n): Promise<S> {\n\t// a drop after the welcome, until the session is made, is heard here: the session's own handler is not on yet, and a\n\t// transport says it once (RV9)\n\tlet dropped = false\n\tconst drop = () => {\n\t\tdropped = true\n\t}\n\tconst welcome = await new Promise<Extract<GameHostMessage, { type: 'welcome' }>>((resolve, reject) => {\n\t\ttransport.onClose(() => {\n\t\t\tdrop()\n\t\t\treject(new Error('The host closed the connection before the game started'))\n\t\t})\n\t\ttransport.onMessage((text) => {\n\t\t\tconst message = readHostMessage(text)\n\t\t\tif (!message) return\n\t\t\tif (message.type === 'welcome') resolve(message)\n\t\t\telse if (isServerMessage(message)) options.onServer?.(message)\n\t\t})\n\t})\n\tconst problem = welcomeProblem(welcome as unknown as Record<string, unknown>)\n\tif (problem) {\n\t\ttransport.close()\n\t\tthrow new Error(problem)\n\t}\n\tconst game =\n\t\t'id' in options.game && typeof options.game.id === 'string'\n\t\t\t? (options.game as GameModule)\n\t\t\t: (options.game as Record<string, GameModule>)[welcome.game]\n\t// a game of the same base with other packs of content (or mods): which, said (campaign plan RC6)\n\tconst own = 'id' in options.game && typeof options.game.id === 'string' ? (options.game as GameModule).id : undefined\n\tconst others = otherPacks(welcome.game, game?.id ?? own)\n\tif (!game) {\n\t\ttransport.close()\n\t\tthrow new Error(others ?? `The host runs ${welcome.game}, which this player does not have`)\n\t}\n\tconst registry = createRegistry(game)\n\tif (welcome.game !== registry.game || welcome.hash !== registry.dataHash) {\n\t\ttransport.close()\n\t\tthrow new Error(others ?? `The host runs ${welcome.game} (${welcome.hash}), this is ${registry.game} (${registry.dataHash}): not the same game`)\n\t}\n\t// what comes in while the map is made waits for the session\n\tconst early: string[] = []\n\ttransport.onMessage((text) => early.push(text))\n\ttransport.onClose(drop)\n\tconst lost = 'The host closed the connection while the map was made'\n\t// (its ground asked for of a host already gone would never come)\n\tif (dropped) throw new Error(lost)\n\tconst terrain = await groundOfWelcome(transport, welcome.terrain, options.maps ?? game.maps, game, early, drop)\n\ttransport.onClose(drop)\n\t// weighing slow ground as the host's does (EN2): the ways it shows are the ones its units take\n\tconst speedAt = hasGroundSpeeds(registry) ? (x: number, z: number) => groundSpeedOn(registry, terrain, x, z) : undefined\n\tconst nav = await RecastNavigation.create(terrain, { agentRadius: 0.5, ...(speedAt && { speedAt }), ...options.navigation })\n\tif (dropped) {\n\t\tnav.dispose()\n\t\tthrow new Error(lost)\n\t}\n\tconst map = new ClientWorld(terrain, registry, nav, new AirNavigation(terrain.width, terrain.depth))\n\tconst session = make(transport, welcome, registry, map, options.limits)\n\tsession.onServer = options.onServer\n\tfor (const text of early) {\n\t\tconst message = readHostMessage(text)\n\t\tif (message) session.receive(message)\n\t}\n\treturn session\n}\n\n/**\n * What a player is told who joins a game of the same base as theirs with other packs of content or mods\n * (`melee+gnomes` against `melee`): the host's and theirs. Nothing for games of other bases, or the same\n */\nfunction otherPacks(host: string, own: string | undefined): string | undefined {\n\tif (own === undefined || own === host) return undefined\n\tconst [hostBase, ...hostPacks] = host.split('+')\n\tconst [ownBase, ...ownPacks] = own.split('+')\n\tif (hostBase !== ownBase) return undefined\n\tconst list = (packs: string[]) => (packs.length ? packs.join(', ') : 'none')\n\treturn `The host plays ${hostBase} with the packs ${list(hostPacks)}, this player with ${list(ownPacks)}: the host's are the game's`\n}\n","/**\n * A watcher shown the game some seconds behind it (RV86): what the host sends goes on after the delay, so that who\n * watches a game being played cannot tell a side where the other is now. The host is answered at once on the\n * watcher's behalf (`ack`), as one who missed nothing: it goes on making each frame against the one before, and keeps\n * nothing more for the delay; the watcher's own answers are not passed on, as they come late. The rest of what the\n * watcher says (a line, a ping) goes as it is said\n */\nimport type { Transport } from './remote'\n\n/** The tick a message to a player says it brings: of a delta from the head of its text, of the welcome from the frame it carries */\nconst tickOf = (message: string): number | undefined => {\n\tconst found =\n\t\t/^\\{\"type\":\"delta\",\"tick\":(\\d+)/.exec(message) ?? (message.startsWith('{\"type\":\"welcome\"') ? /\"first\":\\{\"tick\":(\\d+)/.exec(message) : null)\n\treturn found ? Number(found[1]) : undefined\n}\n\n/** How often what is held is looked at, to send on what is due: a second's tenth is near enough for a delay of seconds */\nconst LOOK_EVERY = 100\n\n/**\n * The host's end of a watcher's transport, with what goes to the watcher held for `seconds` (see the top of this\n * file). Closing it closes the watcher's, and what is held goes with it\n *\n * @beta\n */\nexport function delayed(transport: Transport, seconds: number): Transport {\n\tconst held: { at: number; text: string }[] = []\n\tlet hostHears: (text: string) => void = () => {}\n\tlet hostClosed: () => void = () => {}\n\tconst timer = setInterval(() => {\n\t\tconst now = performance.now()\n\t\tlet due = 0\n\t\twhile (due < held.length && held[due].at <= now) due++\n\t\tfor (const { text } of held.splice(0, due)) transport.send(text)\n\t}, LOOK_EVERY)\n\ttransport.onMessage((text) => {\n\t\t// the watcher's own answers come late: the host had them at once\n\t\tif (text.startsWith('{\"type\":\"ack\"')) return\n\t\thostHears(text)\n\t})\n\t// one handler on the watcher's end (a server's keeps one): told on to the host's\n\ttransport.onClose(() => {\n\t\tclearInterval(timer)\n\t\theld.length = 0\n\t\thostClosed()\n\t})\n\treturn {\n\t\tsend(text) {\n\t\t\theld.push({ at: performance.now() + seconds * 1000, text })\n\t\t\tconst tick = tickOf(text)\n\t\t\t// answered as one who missed nothing, once what the host does now is done\n\t\t\tif (tick !== undefined) queueMicrotask(() => hostHears(JSON.stringify({ type: 'ack', tick })))\n\t\t},\n\t\tonMessage(handler) {\n\t\t\thostHears = handler\n\t\t},\n\t\tonClose(handler) {\n\t\t\thostClosed = handler\n\t\t},\n\t\tclose() {\n\t\t\tclearInterval(timer)\n\t\t\theld.length = 0\n\t\t\ttransport.close()\n\t\t}\n\t}\n}\n","/**\n * A seed of the moment, for a game no other was (the clock: a session's, never the rules'): where every new world made without a seed of its own gets its seed\n * (a map played in a page, on a server, in a worker). The same seed, the same game\n *\n * @beta\n */\nexport const randomSeed = (): number => Date.now() % 100000\n","/**\n * Noise that repeats: a lattice of random values that wraps around, read smoothly between them, so that whatever is\n * made of it tiles. Seeded (`Rng`), so the same seed makes the same noise everywhere. What the map generator shapes\n * its ground with; the client makes the ground's textures with the same (`packages/client`, its own copy, so that a\n * worker of the page's loads nothing of the engine)\n */\nimport { Rng } from './rng'\n\n/**\n * Noise between 0 and 1 at a point, `u` and `v` 0..1 across the picture it repeats over\n *\n * @beta\n */\nexport type Noise2 = (u: number, v: number) => number\n\n/**\n * A value noise that repeats every `period` cells of its lattice: between 0 and 1, smooth\n *\n * @internal\n */\nexport function tilingNoise(period: number, seed: number): Noise2 {\n\tconst size = Math.max(1, Math.round(period))\n\tconst rng = new Rng(seed)\n\tconst values = Float32Array.from({ length: size * size }, () => rng.next())\n\t// written out, with no call in it: read a few hundred thousand times for a map\n\treturn (u, v) => {\n\t\tconst x = u * size\n\t\tconst z = v * size\n\t\tlet x0 = Math.floor(x)\n\t\tlet z0 = Math.floor(z)\n\t\tconst fx = x - x0\n\t\tconst fz = z - z0\n\t\tx0 = ((x0 % size) + size) % size\n\t\tz0 = ((z0 % size) + size) % size\n\t\tconst x1 = x0 + 1 === size ? 0 : x0 + 1\n\t\tconst z1 = z0 + 1 === size ? 0 : z0 + 1\n\t\tconst sx = fx * fx * (3 - 2 * fx)\n\t\tconst sz = fz * fz * (3 - 2 * fz)\n\t\tconst r0 = z0 * size\n\t\tconst r1 = z1 * size\n\t\tconst top = values[r0 + x0] + (values[r0 + x1] - values[r0 + x0]) * sx\n\t\tconst bottom = values[r1 + x0] + (values[r1 + x1] - values[r1 + x0]) * sx\n\t\treturn top + (bottom - top) * sz\n\t}\n}\n\n/**\n * Several noises, each finer and fainter than the one before: what looks like ground and not like a pattern. 0..1\n *\n * @beta\n */\nexport function layeredNoise(seed: number, periods: readonly number[]): Noise2 {\n\tconst noises = periods.map((period, i) => tilingNoise(period, seed + i * 101))\n\tconst weights = periods.map((_, i) => 1 / (1 << i))\n\tconst total = weights.reduce((sum, weight) => sum + weight, 0)\n\tif (noises.length === 1) {\n\t\tconst [only] = noises\n\t\treturn (u, v) => only(u, v)\n\t}\n\treturn (u, v) => {\n\t\tlet sum = 0\n\t\tfor (let i = 0; i < noises.length; i++) sum += noises[i](u, v) * weights[i]\n\t\treturn sum / total\n\t}\n}\n","import { maxPlayersOf } from '../../game'\nimport { MAP_CREEPS, MAP_NEUTRAL, MAX_MAP_PLAYERS } from '../../map'\nimport type { MapRule } from '../rule'\n\n/** How many players the map has, against what the game allows */\nexport const playerRules: MapRule = {\n\tid: 'players',\n\tcheck(map, registry, say, _context) {\n\t\tconst players = map.players.filter((player) => player.id !== MAP_CREEPS && player.id !== MAP_NEUTRAL).length\n\t\tconst most = registry.module ? maxPlayersOf(registry.module) : MAX_MAP_PLAYERS\n\t\tif (players > most) say({ message: `The map has ${players} players, and the game allows ${most}`, error: true, rule: 'too-many-players' })\n\t}\n}\n","import { WATER_DEEP } from '../../terrain'\nimport type { MapRule } from '../rule'\n\n/** What is placed and the camps: of types the game has, on the map, out of deep water */\nexport const objectRules: MapRule = {\n\tid: 'objects',\n\tcheck(map, registry, say, { terrain, onMap }) {\n\t\tfor (const object of map.objects) {\n\t\t\tif (!registry.units.has(object.type)) {\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `\"${object.type}\" is no unit type of the game: it is left out`,\n\t\t\t\t\tat: object,\n\t\t\t\t\trule: 'unknown-type',\n\t\t\t\t\tabout: { object: object.id }\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!onMap(object)) {\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `${registry.unit(object.type).name} stands off the map`,\n\t\t\t\t\terror: true,\n\t\t\t\t\tat: object,\n\t\t\t\t\trule: 'off-map',\n\t\t\t\t\tabout: { object: object.id }\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst def = registry.unit(object.type)\n\t\t\tif (!def.flying && terrain.waterAt(object.x, object.z) === WATER_DEEP)\n\t\t\t\tsay({ message: `${def.name} stands in deep water`, at: object, rule: 'deep-water', about: { object: object.id } })\n\t\t}\n\t\tfor (const camp of map.camps) {\n\t\t\tconst strangers = camp.units.filter((type) => !type.startsWith('@') && !registry.units.has(type))\n\t\t\tif (strangers.length)\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `A camp has creeps the game does not have: ${strangers.join(', ')}`,\n\t\t\t\t\tat: camp,\n\t\t\t\t\trule: 'unknown-creeps',\n\t\t\t\t\tabout: { camp: camp.id }\n\t\t\t\t})\n\t\t\tif (!onMap(camp)) say({ message: 'A camp stands off the map', error: true, at: camp, rule: 'off-map', about: { camp: camp.id } })\n\t\t}\n\t}\n}\n","import { groupChoices, tableItems } from '../../randomGroups'\nimport type { MapRule } from '../rule'\n\n/** Random groups and item tables: something to draw from, and by names there are */\nexport const randomRules: MapRule = {\n\tid: 'random',\n\tcheck(map, registry, say, _context) {\n\t\t// random groups and item tables, by the names that are given and that there are\n\t\tconst groups = new Map((map.randomGroups ?? []).map((group) => [group.name, group]))\n\t\tconst tables = new Set((map.itemTables ?? []).map((table) => table.name))\n\t\tfor (const group of groups.values()) {\n\t\t\tif (!groupChoices(group, registry).length)\n\t\t\t\tsay({ message: `The random group ${group.name} has nothing of the game to draw from`, error: true, rule: 'empty-random-group' })\n\t\t}\n\t\tfor (const table of map.itemTables ?? []) {\n\t\t\tif (!tableItems(table, registry).length)\n\t\t\t\tsay({ message: `The item table ${table.name} has nothing of the game to draw from`, error: true, rule: 'empty-item-table' })\n\t\t}\n\t\tfor (const object of map.objects) {\n\t\t\tif (object.random && !groups.has(object.random))\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `It is drawn from \"${object.random}\", which is no random group of the map`,\n\t\t\t\t\terror: true,\n\t\t\t\t\tat: object,\n\t\t\t\t\trule: 'unknown-random-group',\n\t\t\t\t\tabout: { object: object.id }\n\t\t\t\t})\n\t\t\tif (object.drops && !tables.has(object.drops))\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `It drops from \"${object.drops}\", which is no item table of the map`,\n\t\t\t\t\terror: true,\n\t\t\t\t\tat: object,\n\t\t\t\t\trule: 'unknown-item-table',\n\t\t\t\t\tabout: { object: object.id }\n\t\t\t\t})\n\t\t}\n\t\tfor (const camp of map.camps) {\n\t\t\tfor (const unit of camp.units) {\n\t\t\t\tif (unit.startsWith('@') && !groups.has(unit.slice(1)))\n\t\t\t\t\tsay({\n\t\t\t\t\t\tmessage: `A camp has \"${unit}\", which is no random group of the map`,\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\tat: camp,\n\t\t\t\t\t\trule: 'unknown-random-group',\n\t\t\t\t\t\tabout: { camp: camp.id }\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { MapTarget } from '../../mapFields'\nimport type { Vec2 } from '../../math'\nimport type { MapRule } from '../rule'\n\n/** One thing a name, and the cameras players start looking from */\nexport const nameRules: MapRule = {\n\tid: 'names',\n\tcheck(map, _registry, say, _context) {\n\t\t// the rules find things by name: one thing a name\n\t\tconst named = new Map<string, { at: Vec2; about: MapTarget }[]>()\n\t\tconst name = (value: string | undefined, at: Vec2, about: MapTarget) => {\n\t\t\tif (value) named.set(value, [...(named.get(value) ?? []), { at, about }])\n\t\t}\n\t\tfor (const object of map.objects) name(object.name, object, { object: object.id })\n\t\tfor (const camp of map.camps) name(camp.name, camp, { camp: camp.id })\n\t\tfor (const region of map.regions) name(region.name, region.shape, { region: region.id })\n\t\tfor (const point of map.points) name(point.name, point, { point: point.id })\n\t\tfor (const path of map.paths) name(path.name, path.points[0] ?? { x: 0, z: 0 }, { path: path.id })\n\t\tfor (const [value, places] of named) {\n\t\t\tif (places.length > 1)\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `\"${value}\" is the name of ${places.length} things: the rules find only one`,\n\t\t\t\t\terror: true,\n\t\t\t\t\tat: places[1].at,\n\t\t\t\t\trule: 'name-twice',\n\t\t\t\t\tabout: places[1].about\n\t\t\t\t})\n\t\t}\n\t\tfor (const player of map.players) {\n\t\t\tif (player.camera && !map.cameras.some((camera) => camera.name === player.camera)) {\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `${player.name} starts looking from \"${player.camera}\", which is no camera of the map`,\n\t\t\t\t\tat: player.start,\n\t\t\t\t\trule: 'unknown-camera',\n\t\t\t\t\tabout: { player: player.id }\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n}\n","import { shapeBounds } from '#engine/areas'\nimport type { MapRule } from '../rule'\n\n/** Regions on the map */\nexport const regionRules: MapRule = {\n\tid: 'regions',\n\tcheck(map, _registry, say, _context) {\n\t\tconst { width, depth } = map\n\t\tfor (const region of map.regions) {\n\t\t\tconst { shape } = region\n\t\t\tconst reach = shapeBounds(shape)\n\t\t\tif (reach.x1 <= 0 || reach.z1 <= 0 || reach.x0 >= width || reach.z0 >= depth)\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `The region ${region.name} is outside the map`,\n\t\t\t\t\terror: true,\n\t\t\t\t\tat: shape,\n\t\t\t\t\trule: 'region-off-map',\n\t\t\t\t\tabout: { region: region.id }\n\t\t\t\t})\n\t\t\telse if (reach.x0 < 0 || reach.z0 < 0 || reach.x1 > width || reach.z1 > depth)\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `The region ${region.name} goes past the edge of the map`,\n\t\t\t\t\tat: shape,\n\t\t\t\t\trule: 'region-past-edge',\n\t\t\t\t\tabout: { region: region.id }\n\t\t\t\t})\n\t\t}\n\t}\n}\n","import type { MapRule } from '../rule'\n\n/** Paths on the map: on it, and what they paint and carve there to be had */\nexport const pathRules: MapRule = {\n\tid: 'paths',\n\tcheck(map, registry, say, { onMap }) {\n\t\tfor (const path of map.paths) {\n\t\t\tconst about = { path: path.id }\n\t\t\tif (path.points.some((point) => !onMap(point)))\n\t\t\t\tsay({ message: `The path ${path.name} goes off the map`, at: path.points[0], rule: 'path-off-map', about })\n\t\t\t// a tile neither the map's tileset nor the game has is painted nowhere\n\t\t\tfor (const tile of [path.paint, path.profile?.ground])\n\t\t\t\tif (tile !== undefined && !map.tileset.includes(tile) && !registry.tiles.some((def) => def.id === tile))\n\t\t\t\t\tsay({\n\t\t\t\t\t\tmessage: `The path ${path.name} paints with ${tile}, which neither the map's tiles nor the game's are`,\n\t\t\t\t\t\tat: path.points[0],\n\t\t\t\t\t\trule: 'path-tile-missing',\n\t\t\t\t\t\tabout\n\t\t\t\t\t})\n\t\t\tif (path.profile && path.points.length < 2)\n\t\t\t\tsay({\n\t\t\t\t\tmessage: `The path ${path.name} carves its bed with one point: it carves nothing until it has two`,\n\t\t\t\t\tat: path.points[0],\n\t\t\t\t\trule: 'path-profile-short',\n\t\t\t\t\tabout\n\t\t\t\t})\n\t\t}\n\t}\n}\n","/*\n * Where something on foot can stand on a map, and which of it can get to which: what the checks of walking go by, and\n * what the editor shows (design review E8b)\n */\nimport { footprintOf } from '../defs'\nimport { footprintCell } from '../grid'\nimport { BLOCKS_WALK, BRIDGE, type GameMap, mapTerrain } from '../map'\nimport type { Vec2 } from '../math'\nimport type { Registry } from '../registry'\nimport { type Terrain, WATER_DEEP } from '../terrain'\n\n/** The steepest ground something on foot walks, in radians: as the navigation mesh has it */\nconst WALKABLE_SLOPE = (38 * Math.PI) / 180\n\n/**\n * Which cells of a map something on foot can stand on (1) and which have a building or a mine on them (`built`): for\n * the checks, and for what the editor shows of where one can walk and build. `steep` counts slopes too steep to walk\n *\n * @beta\n */\nexport function mapCells(\n\tmap: GameMap,\n\tregistry: Registry,\n\tterrain: Terrain = mapTerrain(map),\n\tsteep = false\n): { open: Uint8Array; built: Uint8Array } {\n\tconst { width, depth } = map\n\tconst open = new Uint8Array(width * depth)\n\tconst built = new Uint8Array(width * depth)\n\tfor (let c = 0; c < open.length; c++) {\n\t\tconst x = c % width\n\t\tconst z = (c - x) / width\n\t\topen[c] =\n\t\t\t(terrain.water[c] !== WATER_DEEP || terrain.blocked[c] === BRIDGE) &&\n\t\t\tterrain.blocked[c] !== BLOCKS_WALK &&\n\t\t\tterrain.inPlay(x, z) &&\n\t\t\t(!steep || terrain.slopeAt(x + 0.5, z + 0.5) <= WALKABLE_SLOPE)\n\t\t\t\t? 1\n\t\t\t\t: 0\n\t}\n\t// what is built stands in the way\n\tfor (const object of map.objects) {\n\t\tif (!registry.units.has(object.type)) continue\n\t\tconst def = registry.unit(object.type)\n\t\tif (def.kind === 'unit') continue\n\t\tconst { w, d } = footprintOf(def)\n\t\tconst corner = footprintCell(object.x, object.z, w, d)\n\t\tfor (let z = corner.z; z < corner.z + d; z++) {\n\t\t\tfor (let x = corner.x; x < corner.x + w; x++) {\n\t\t\t\tif (x < 0 || z < 0 || x >= width || z >= depth) continue\n\t\t\t\topen[z * width + x] = 0\n\t\t\t\tbuilt[z * width + x] = 1\n\t\t\t}\n\t\t}\n\t}\n\treturn { open, built }\n}\n\n/** Cells something on foot can stand on, and which of them it can get to from which: a number per cell, 0 for none */\nexport function walkingAreas(map: GameMap, registry: Registry): { area: Int32Array; at: (point: Vec2) => number } {\n\tconst { width, depth, levels, ramps } = map\n\tconst { open } = mapCells(map, registry)\n\t// a step between two levels is a cliff, unless one side is a ramp\n\tconst passable = (a: number, b: number) => levels[a] === levels[b] || ramps[a] > 0 || ramps[b] > 0\n\tconst area = new Int32Array(width * depth)\n\tlet next = 0\n\tconst queue = new Int32Array(width * depth)\n\tfor (let start = 0; start < area.length; start++) {\n\t\tif (!open[start] || area[start]) continue\n\t\tnext++\n\t\tlet head = 0\n\t\tlet tail = 0\n\t\tqueue[tail++] = start\n\t\tarea[start] = next\n\t\twhile (head < tail) {\n\t\t\tconst c = queue[head++]\n\t\t\tconst x = c % width\n\t\t\tconst z = (c - x) / width\n\t\t\tfor (const [nx, nz] of [\n\t\t\t\t[x - 1, z],\n\t\t\t\t[x + 1, z],\n\t\t\t\t[x, z - 1],\n\t\t\t\t[x, z + 1]\n\t\t\t]) {\n\t\t\t\tif (nx < 0 || nz < 0 || nx >= width || nz >= depth) continue\n\t\t\t\tconst n = nz * width + nx\n\t\t\t\tif (!open[n] || area[n] || !passable(c, n)) continue\n\t\t\t\tarea[n] = next\n\t\t\t\tqueue[tail++] = n\n\t\t\t}\n\t\t}\n\t}\n\t/** The area a point is in, or the one next to it, for what stands on cells nothing walks on: a mine, a town hall */\n\tconst at = (point: Vec2) => {\n\t\tconst cx = Math.floor(point.x)\n\t\tconst cz = Math.floor(point.z)\n\t\tfor (let r = 0; r <= 4; r++) {\n\t\t\tfor (let z = cz - r; z <= cz + r; z++) {\n\t\t\t\tfor (let x = cx - r; x <= cx + r; x++) {\n\t\t\t\t\tif (x < 0 || z < 0 || x >= width || z >= depth) continue\n\t\t\t\t\tif (Math.max(Math.abs(x - cx), Math.abs(z - cz)) !== r) continue\n\t\t\t\t\tconst found = area[z * width + x]\n\t\t\t\t\tif (found) return found\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn 0\n\t}\n\treturn { area, at }\n}\n","import { reachedByDefault } from '../../mapFields'\nimport { walkingAreas } from '../cells'\nimport type { MapRule } from '../rule'\n\n/** Who can walk to whom: starts cut off from each other, mines nobody can walk to */\nexport const walkingRules: MapRule = {\n\tid: 'walking',\n\tcheck(map, registry, say, _context) {\n\t\t// who can walk to whom: starts that are cut off from each other, mines nobody can walk to\n\t\tconst starts = map.players.filter((player) => player.start)\n\t\tif (starts.length) {\n\t\t\tconst { at } = walkingAreas(map, registry)\n\t\t\tconst areas = starts.map((player) => at(player.start!))\n\t\t\tstarts.forEach((player, i) => {\n\t\t\t\tif (!areas[i])\n\t\t\t\t\tsay({\n\t\t\t\t\t\tmessage: `${player.name} starts where nothing can walk`,\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\tat: player.start,\n\t\t\t\t\t\trule: 'start-blocked',\n\t\t\t\t\t\tabout: { player: player.id }\n\t\t\t\t\t})\n\t\t\t\telse if (areas.some((other, j) => j !== i && other && other !== areas[i])) {\n\t\t\t\t\tsay({\n\t\t\t\t\t\tmessage: `${player.name} cannot walk to every other start: a cliff, water or what is built is in the way`,\n\t\t\t\t\t\tat: player.start,\n\t\t\t\t\t\trule: 'starts-apart',\n\t\t\t\t\t\tabout: { player: player.id }\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t\tconst reached = new Set(areas.filter(Boolean))\n\t\t\tfor (const object of map.objects) {\n\t\t\t\tif (!registry.units.has(object.type)) continue\n\t\t\t\tconst def = registry.unit(object.type)\n\t\t\t\t// what is mined, not what is cut, unless the game says: trees stand where they stand\n\t\t\t\tif (!(registry.module?.editor?.reach ?? reachedByDefault)(def)) continue\n\t\t\t\tif (!reached.has(at(object)))\n\t\t\t\t\tsay({ message: `Nobody can walk to the ${def.name} here`, at: object, rule: 'unreachable', about: { object: object.id } })\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { GameMap } from '../../map'\nimport type { MapProblem } from '../../mapFields'\nimport { RANDOM_RACE } from '../../races'\nimport type { Registry } from '../../registry'\nimport { availableTo } from '../../shared'\nimport type { MapRule } from '../rule'\n\n/**\n * What is wrong with the races of a map: a player fixed to a race the game has not got, or the map offering one, are\n * errors (a world is not made from it); what is placed for a player that their race may not have is a warning. What\n * the map offers is for the players it fixes no race for: one fixed to another is as the map means it\n */\nfunction raceProblems(map: GameMap, registry: Registry): MapProblem[] {\n\tconst problems: MapProblem[] = []\n\tconst known = (race: string) => race === RANDOM_RACE || registry.races.has(race)\n\tconst none = registry.races.size === 0\n\tfor (const race of map.races ?? []) {\n\t\tif (race === RANDOM_RACE || registry.races.has(race)) continue\n\t\tproblems.push({\n\t\t\tmessage: `The map offers the race \"${race}\", which ${none ? 'the game does not have: it has no races' : 'is no race of the game'}`,\n\t\t\terror: true,\n\t\t\trule: 'unknown-race'\n\t\t})\n\t}\n\tfor (const player of map.players) {\n\t\tif (player.race === undefined) continue\n\t\tif (!known(player.race)) {\n\t\t\tproblems.push({\n\t\t\t\tmessage: `${player.name} plays the race \"${player.race}\", which ${none ? 'the game does not have: it has no races' : 'is no race of the game'}`,\n\t\t\t\terror: true,\n\t\t\t\tat: player.start,\n\t\t\t\trule: 'unknown-race',\n\t\t\t\tabout: { player: player.id }\n\t\t\t})\n\t\t}\n\t}\n\t// what a player whose race is fixed may not have: they could not make it, and it is theirs all the same\n\tconst fixed = new Map(\n\t\tmap.players.filter((player) => player.race && player.race !== RANDOM_RACE && registry.races.has(player.race)).map((player) => [player.id, player])\n\t)\n\tfor (const object of map.objects) {\n\t\tconst owner = fixed.get(object.owner)\n\t\tif (!owner || !registry.units.has(object.type)) continue\n\t\tconst def = registry.unit(object.type)\n\t\tif (availableTo(def, owner.race)) continue\n\t\tproblems.push({\n\t\t\tmessage: `${def.name} is ${registry.race(def.race!).name}, and ${owner.name} plays ${registry.race(owner.race!).name}`,\n\t\t\tat: object,\n\t\t\trule: 'other-race',\n\t\t\tabout: { object: object.id }\n\t\t})\n\t}\n\treturn problems\n}\n\n/** The races of the map, its players and what is placed for them */\nexport const raceRules: MapRule = {\n\tid: 'races',\n\tcheck(map, registry, say) {\n\t\tfor (const problem of raceProblems(map, registry)) say(problem)\n\t}\n}\n","import {\n\tcampFields,\n\ttype MapFieldDef,\n\tmapFields,\n\ttype MapTarget,\n\tobjectFields,\n\tplayerFields,\n\tregionFields,\n\tTARGET_FIELDS,\n\ttargetName\n} from '../../mapFields'\nimport type { Vec2 } from '../../math'\nimport type { MapRule } from '../rule'\n\n/** A field that names a region, a point or a path the map has not (any more) */\nexport const targetRules: MapRule = {\n\tid: 'targets',\n\tcheck(map, registry, say, _context) {\n\t\t// a field that names a region, a point or a path the map has not (any more): taken away, or never there\n\t\tconst naming = (fields: readonly MapFieldDef[], data: Record<string, unknown> | undefined, about: MapTarget | undefined, at?: Vec2) => {\n\t\t\tfor (const field of fields) {\n\t\t\t\tconst kind = field.kind as (typeof TARGET_FIELDS)[number]\n\t\t\t\tconst id = data?.[field.id]\n\t\t\t\tif (!(TARGET_FIELDS as readonly string[]).includes(field.kind) || typeof id !== 'number') continue\n\t\t\t\tif (targetName(map, kind, id) === undefined)\n\t\t\t\t\tsay({\n\t\t\t\t\t\tmessage: `${field.name} names a ${kind} the map does not have`,\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\trule: 'missing-target',\n\t\t\t\t\t\t...(at && { at }),\n\t\t\t\t\t\t...(about && { about })\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tfor (const object of map.objects) naming(objectFields(registry, object.type), object.data, { object: object.id }, object)\n\t\tfor (const camp of map.camps) naming(campFields(registry), camp.data, { camp: camp.id }, camp)\n\t\tfor (const region of map.regions) naming(regionFields(registry), region.data, { region: region.id })\n\t\tfor (const player of map.players) naming(playerFields(registry), player.data, { player: player.id }, player.start)\n\t\tnaming(mapFields(registry), map.data, undefined)\n\t}\n}\n","/*\n * The checks of a map before it is played (design review E8b): the engine's (`MAP_RULES`, one file each in\n * `mapCheck/rules`), those given beside them (the client's of a map's looks, a game's view's own), then the game's own\n * (`MapEditorDef.check`), less what the map and the game silence\n */\nimport { type GameMap, mapTerrain } from './map'\nimport type { MapProblem } from './mapFields'\nimport type { Vec2 } from './math'\nimport type { Registry } from './registry'\nimport type { Terrain } from './terrain'\nimport type { MapCheckContext, MapRule } from './mapCheck/rule'\nimport { playerRules } from './mapCheck/rules/players'\nimport { objectRules } from './mapCheck/rules/objects'\nimport { randomRules } from './mapCheck/rules/random'\nimport { nameRules } from './mapCheck/rules/names'\nimport { regionRules } from './mapCheck/rules/regions'\nimport { pathRules } from './mapCheck/rules/paths'\nimport { walkingRules } from './mapCheck/rules/walking'\nimport { raceRules } from './mapCheck/rules/races'\nimport { targetRules } from './mapCheck/rules/targets'\n\nexport { mapCells } from './mapCheck/cells'\nexport type { MapCheckContext, MapRule } from './mapCheck/rule'\n\n/**\n * The engine's checks of a map, in the order they run: players, what is placed, random groups, names, regions, paths,\n * walking, races, the fields that name things\n *\n * @beta\n */\nexport const MAP_RULES: readonly MapRule[] = [\n\tplayerRules,\n\tobjectRules,\n\trandomRules,\n\tnameRules,\n\tregionRules,\n\tpathRules,\n\twalkingRules,\n\traceRules,\n\ttargetRules\n]\n\n/**\n * What is wrong with a map, before it is played: what the game does not have, names used twice or named and not\n * there, what stands off the map or in deep water, starts that cannot reach each other on foot, mines nobody can walk\n * to, regions outside the map (`MAP_RULES`); then the checks given (`more`: the client's of what the map looks like,\n * a game view's own, as the editor runs them); then the game's own (`MapEditorDef.check`). Errors keep it from being\n * played; the rest are warnings. Runs without the editor, for a test that goes over every map of a project\n *\n * @beta\n */\nexport function checkMap(map: GameMap, registry: Registry, more: readonly MapRule[] = []): MapProblem[] {\n\tconst problems: MapProblem[] = []\n\tconst { width, depth } = map\n\tlet terrain: Terrain | undefined\n\tconst context: MapCheckContext = {\n\t\tget terrain() {\n\t\t\treturn (terrain ??= mapTerrain(map))\n\t\t},\n\t\tonMap: (p: Vec2) => p.x >= 0 && p.z >= 0 && p.x <= width && p.z <= depth\n\t}\n\tconst say = (problem: MapProblem) => void problems.push(problem)\n\tfor (const rule of [...MAP_RULES, ...more]) rule.check(map, registry, say, context)\n\t// the game's own, each said to be the game's where it names no rule of its own; then what the map and the game silence\n\tconst own = (registry.assembly?.check?.(map, registry) ?? []).map((problem) => ({ rule: 'game', ...problem }))\n\tconst silenced = new Set([...(registry.module?.editor?.silence ?? []), ...(map.silence ?? [])])\n\treturn [...problems, ...own].filter((problem) => !problem.rule || !silenced.has(problem.rule))\n}\n","/**\n * Maps made by a generator (world plan G1): a map from a seed and a few sliders, made of passes a game adds to,\n * replaces or leaves out, each a function of a context that holds the map, the seed's numbers, noise that repeats\n * across the map, the symmetry and what the passes before put down. Deterministic: the engine's `Rng`, nothing of\n * the clock. The engine's own passes shape the ground (`terrainPass`), paint it (`tilesPass`), seat the players\n * (`startsPass`), scatter things over it (`scatterPass`: trees now, rocks and houses the same way later), put\n * resources near the starts (`resourcesPass`) and lay roads (`roadsPass`); `generateMap` runs them and checks the map\n * (`checkMap`), trying the next seed where a start is cut off or blocked. A game declares its generator\n * (`GameModule.generator`), for the editor and the page to find; `presetGenerator` is the engine's to take whole\n */\nimport { checkMap } from './mapCheck'\nimport { Rng } from './rng'\nimport { layeredNoise, type Noise2 } from './noise'\nimport {\n\tcreateMap,\n\ttype GameMap,\n\tMAP_CREEPS,\n\tMAP_NEUTRAL,\n\ttype MapCamp,\n\ttype MapDoodad,\n\ttype MapObject,\n\ttype MapPlayer,\n\ttype MapRegion,\n\tmapTerrain\n} from './map'\nimport type { MapProblem } from './mapFields'\nimport type { Vec2 } from './math'\nimport type { AreaShape } from './areas'\nimport type { PlayerId } from './entity'\nimport type { Registry } from './registry'\nimport { WATER_DEEP, WATER_NONE, WATER_SHALLOW } from './terrain'\nimport { atan, atan2, cos, hypot, sin } from './exactMath'\n\n/**\n * How a map is mirrored, so that it is fair: not at all, across x, across z, both ways, a half turn about the middle,\n * or quarter turns (a square map, its sides even). As the editor's symmetry says it\n *\n * @beta\n */\nexport type MapSymmetry = 'none' | 'x' | 'z' | 'both' | 'half' | 'quarter'\n\n/**\n * What a map is made with (`generateMap`): the seed, the size, the players, the symmetry, and the game's own\n * parameters (`MapGenerator.params`), each at its default where not said\n *\n * @beta\n */\nexport interface GeneratorOptions {\n\tseed: number\n\twidth: number\n\tdepth: number\n\tplayers: number\n\tsymmetry?: MapSymmetry\n\t/** The map's name: \"Generated <seed>\" when left out */\n\tname?: string\n\t/** The game's own parameters, by id, as the dialog's sliders and switches set them */\n\tparams?: Record<string, number | string | boolean>\n}\n\n/**\n * A parameter of a generator (`MapGenerator.params`): a slider, a switch or a choice in the editor's dialog and the\n * page's form, and a value in code (`GeneratorOptions.params`)\n *\n * @beta\n */\nexport interface GeneratorParamDef {\n\tid: string\n\tname: string\n\tdescription?: string\n\t/** A number on a slider (the default), a switch, or one of `choices` */\n\tkind?: 'number' | 'boolean' | 'choice'\n\tdefault: number | string | boolean\n\tmin?: number\n\tmax?: number\n\tstep?: number\n\tchoices?: { value: string; label: string }[]\n}\n\n/**\n * What was put down by a pass, for the passes after to avoid or use (`GeneratorContext.placed`)\n *\n * @beta\n */\nexport interface GeneratorMark {\n\tkind: string\n\tx: number\n\tz: number\n\tradius: number\n}\n\n/**\n * What a pass works with (`GeneratorPass.run`): the map as the passes before left it, the seed's numbers, noise that\n * repeats across the map, the symmetry, and what to put down with\n *\n * @beta\n */\nexport interface GeneratorContext {\n\tmap: GameMap\n\t/** The seed's numbers: every draw of a pass is one of these, so the same seed makes the same map */\n\trng: Rng\n\toptions: GeneratorOptions\n\tregistry: Registry\n\t/** A parameter as it is: what the options say, or its default (`MapGenerator.params`), or `fallback` where neither says */\n\tparam<T extends number | string | boolean>(id: string, fallback: T): T\n\t/**\n\t * A place, and the places the symmetry mirrors or turns it to (the first is the place itself): what is put down at\n\t * one is put down at the others, so the map is fair\n\t */\n\tsymmetric(x: number, z: number): Vec2[]\n\t/** Whether a cell is the first of its mirrored set: what is done once a set is done at this one, and mirrored from it */\n\tcanonical(cx: number, cz: number): boolean\n\t/**\n\t * What `draw` makes, made once for a place and the places the symmetry mirrors it to: the first call of a set draws\n\t * (and spends the seed's numbers), the calls for its mirrors get the same. For a choice put down at every mirror\n\t * (a camp's creeps), so the map stays fair\n\t */\n\tonce<T>(x: number, z: number, draw: () => T): T\n\t/**\n\t * Noise that repeats across the map, by a name (the same name is the same noise), 0..1 at a point of the map in\n\t * cells; `cells` are the sizes of its features, coarsest first (`[32, 16, 8]` for hills). Mirrored as the map is\n\t */\n\tnoise(name: string, cells?: readonly number[]): (x: number, z: number) => number\n\t/** What the passes before put down, by kind */\n\tplaced: GeneratorMark[]\n\t/** Puts a mark down for the passes after: nothing on the map, only in `placed` */\n\tmark(kind: string, x: number, z: number, radius: number): void\n\t/** Whether nothing marked is within `radius` of a place (of `kinds` alone, when said) */\n\tfree(x: number, z: number, radius: number, kinds?: readonly string[]): boolean\n\t/** The level of the ground at a point: its cell's cliff level */\n\tlevelAt(x: number, z: number): number\n\t/** Whether a point is on the map and on ground something walks: no deep water, not off the map */\n\twalkable(x: number, z: number): boolean\n\t/** Scenery put down, with an id of its own: the model by its path in `models/`, as big as it says, turned as it says */\n\taddDoodad(doodad: Omit<MapDoodad, 'id' | 'scale' | 'yaw'> & { scale?: number | [number, number, number]; yaw?: number }): MapDoodad\n\t/** A unit or a building of a type put down, with an id of its own, for a player (`MAP_NEUTRAL`, `MAP_CREEPS`, or one of the map's) */\n\taddObject(type: string, owner: PlayerId, x: number, z: number, more?: Partial<Omit<MapObject, 'id' | 'type' | 'owner' | 'x' | 'z'>>): MapObject\n\t/** Creeps that guard a spot, with an id of their own */\n\taddCamp(x: number, z: number, units: string[], more?: Partial<Omit<MapCamp, 'id' | 'x' | 'z' | 'units'>>): MapCamp\n\t/** A region the rules watch by name, with an id of its own */\n\taddRegion(name: string, shape: AreaShape, more?: Partial<Omit<MapRegion, 'id' | 'name' | 'shape'>>): MapRegion\n}\n\n/**\n * A pass of a generator: one thing done to the map, in its turn (`MapGenerator.passes`)\n *\n * @beta\n */\nexport interface GeneratorPass {\n\tid: string\n\tname: string\n\trun(ctx: GeneratorContext): void\n}\n\n/**\n * A game's generator (`GameModule.generator`): its parameters, as the dialog and the page show them, and its passes\n * in order. `generateMap` runs it\n *\n * @beta\n */\nexport interface MapGenerator {\n\tparams: GeneratorParamDef[]\n\tpasses: GeneratorPass[]\n\t/**\n\t * How many seeds are tried where the map comes out with a problem that keeps it from being played (an error, a start\n\t * cut off from the others or blocked): 4 when left out\n\t */\n\ttries?: number\n}\n\n/**\n * How a map was made, kept with it (`GameMap.generated`): the same again from the same\n *\n * @beta\n */\nexport interface GeneratedWith {\n\tseed: number\n\toptions: GeneratorOptions\n}\n\n/**\n * The map a generator makes of options: its passes run in order on a map of the size and players asked, with the\n * game's tiles; then checked (`checkMap`). A map with a problem that keeps it from being played (a start cut off from\n * the others, or where nothing walks) is thrown away and the next seed tried, `tries` times; the last is given with\n * its problems. The map says how it was made (`GameMap.generated`)\n *\n * @beta\n */\nexport function generateMap(\n\tgenerator: MapGenerator,\n\toptions: GeneratorOptions,\n\tregistry: Registry\n): { map: GameMap; problems: MapProblem[]; seed: number } {\n\tconst tries = Math.max(1, generator.tries ?? 4)\n\tlet last: { map: GameMap; problems: MapProblem[]; seed: number } | undefined\n\tfor (let attempt = 0; attempt < tries; attempt++) {\n\t\tconst seed = options.seed + attempt\n\t\tconst map = createMap({\n\t\t\tname: options.name ?? `Generated ${seed}`,\n\t\t\twidth: options.width,\n\t\t\tdepth: options.depth,\n\t\t\tplayers: options.players,\n\t\t\tgame: registry.module?.id,\n\t\t\ttileset: registry.tileIds\n\t\t})\n\t\tconst ctx: GeneratorContext = createContext(map, { ...options, seed }, registry, generator)\n\t\tfor (const pass of generator.passes) pass.run(ctx)\n\t\tmap.generated = { seed, options: { ...options, seed } }\n\t\tconst problems = checkMap(map, registry)\n\t\tlast = { map, problems, seed }\n\t\tif (!problems.some(unplayable)) return last\n\t}\n\treturn last!\n}\n\n/** What keeps a map from being played, so that the next seed is tried: an error, or a start cut off from the others or blocked */\nconst unplayable = (problem: MapProblem) => problem.error || problem.rule === 'starts-apart' || problem.rule === 'start-blocked'\n\n// ---- the context\n\nconst SYMMETRIES: MapSymmetry[] = ['none', 'x', 'z', 'both', 'half', 'quarter']\n\n/**\n * The places a point is mirrored or turned to, the point first (as the editor's `mirrors`)\n *\n * @beta\n */\nexport function symmetricPlaces(symmetry: MapSymmetry, width: number, depth: number, x: number, z: number): Vec2[] {\n\tconst out: Vec2[] = [{ x, z }]\n\tconst add = (px: number, pz: number) => {\n\t\tif (!out.some((other) => Math.abs(other.x - px) < 1e-6 && Math.abs(other.z - pz) < 1e-6)) out.push({ x: px, z: pz })\n\t}\n\tswitch (symmetry) {\n\t\tcase 'x':\n\t\t\tadd(width - x, z)\n\t\t\tbreak\n\t\tcase 'z':\n\t\t\tadd(x, depth - z)\n\t\t\tbreak\n\t\tcase 'both':\n\t\t\tadd(width - x, z)\n\t\t\tadd(x, depth - z)\n\t\t\tadd(width - x, depth - z)\n\t\t\tbreak\n\t\tcase 'half':\n\t\t\tadd(width - x, depth - z)\n\t\t\tbreak\n\t\tcase 'quarter': {\n\t\t\tconst cx = width / 2\n\t\t\tconst cz = depth / 2\n\t\t\tfor (let k = 1; k < 4; k++) {\n\t\t\t\tlet px = x - cx\n\t\t\t\tlet pz = z - cz\n\t\t\t\tfor (let i = 0; i < k; i++) [px, pz] = [-pz, px]\n\t\t\t\tadd(cx + px, cz + pz)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\treturn out\n}\n\n/** How many places a mirrored set has at most: four, for quarter turns and both ways */\nconst MIRRORS = 4\n\n/** The first of a point's mirrored set, by row then column: where a noise is read, so the noise is mirrored as the map is */\nfunction firstPlace(symmetry: MapSymmetry, width: number, depth: number, x: number, z: number, out: { x: number; z: number }): void {\n\tout.x = x\n\tout.z = z\n\tconst take = (px: number, pz: number) => takeFirst(out, px, pz)\n\tswitch (symmetry) {\n\t\tcase 'x':\n\t\t\ttake(width - x, z)\n\t\t\tbreak\n\t\tcase 'z':\n\t\t\ttake(x, depth - z)\n\t\t\tbreak\n\t\tcase 'both':\n\t\t\ttake(width - x, z)\n\t\t\ttake(x, depth - z)\n\t\t\ttake(width - x, depth - z)\n\t\t\tbreak\n\t\tcase 'half':\n\t\t\ttake(width - x, depth - z)\n\t\t\tbreak\n\t\tcase 'quarter': {\n\t\t\tconst cx = width / 2\n\t\t\tconst cz = depth / 2\n\t\t\tlet px = x - cx\n\t\t\tlet pz = z - cz\n\t\t\tfor (let k = 1; k < 4; k++) {\n\t\t\t\t;[px, pz] = [-pz, px]\n\t\t\t\ttake(cx + px, cz + pz)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n/** The earlier of a place and another, by row then column, kept in `out` */\nfunction takeFirst(out: { x: number; z: number }, px: number, pz: number): void {\n\tif (pz < out.z - 1e-6 || (Math.abs(pz - out.z) < 1e-6 && px < out.x)) {\n\t\tout.x = px\n\t\tout.z = pz\n\t}\n}\n\n/** What the engine's passes use of a context beyond what a game's see: the mirror table */\ninterface GeneratorInternals {\n\t/** A cell's mirrored set, as cells, itself among them */\n\tmirrorsOf(c: number): number[]\n\t/** Sets a value in a cell and its mirrors */\n\tsetCell(array: Uint8Array, c: number, value: number): void\n}\n\nfunction createContext(map: GameMap, options: GeneratorOptions, registry: Registry, generator: MapGenerator): GeneratorContext & GeneratorInternals {\n\tconst { width, depth } = map\n\tconst symmetry = options.symmetry ?? 'none'\n\tif (!SYMMETRIES.includes(symmetry)) throw new Error(`generateMap: there is no symmetry \"${symmetry}\": ${SYMMETRIES.join(', ')}`)\n\tif (symmetry === 'quarter' && (width !== depth || width % 2)) throw new Error('generateMap: quarter turns need a square map with even sides')\n\tconst rng = new Rng(options.seed)\n\tconst defaults = Object.fromEntries(generator.params.map((param) => [param.id, param.default]))\n\tconst given = options.params ?? {}\n\tconst noises = new Map<string, Noise2>()\n\tconst placed: GeneratorMark[] = []\n\tlet nextId = 1\n\t// each cell's mirrored set, as cells (-1 past the end), and the first of it: where things are done once, and mirrored from\n\tconst mirrors = new Int32Array(width * depth * MIRRORS).fill(-1)\n\tconst canon = new Int32Array(width * depth)\n\tfor (let c = 0; c < canon.length; c++) {\n\t\tconst cx = c % width\n\t\tconst cz = (c - cx) / width\n\t\tlet first = c\n\t\tlet n = 0\n\t\tfor (const place of symmetricPlaces(symmetry, width, depth, cx + 0.5, cz + 0.5)) {\n\t\t\tconst mx = Math.floor(place.x)\n\t\t\tconst mz = Math.floor(place.z)\n\t\t\tif (mx < 0 || mz < 0 || mx >= width || mz >= depth) continue\n\t\t\tconst m = mz * width + mx\n\t\t\tmirrors[c * MIRRORS + n++] = m\n\t\t\tfirst = Math.min(first, m)\n\t\t}\n\t\tcanon[c] = first\n\t}\n\t// the marks in a grid of 8 cells, for what keeps off them to find the near ones alone\n\tconst GRID = 8\n\tconst cols = Math.ceil(width / GRID)\n\tconst rows = Math.ceil(depth / GRID)\n\tconst grid: number[][] = Array.from({ length: cols * rows }, () => [])\n\tlet widest = 0\n\tconst point = { x: 0, z: 0 }\n\tconst drawn = new Map<number, unknown>()\n\treturn {\n\t\tmap,\n\t\trng,\n\t\toptions,\n\t\tregistry,\n\t\tparam: <T extends number | string | boolean>(id: string, fallback: T): T => (given[id] ?? defaults[id] ?? fallback) as T,\n\t\tsymmetric: (x, z) => symmetricPlaces(symmetry, width, depth, x, z),\n\t\tcanonical: (cx, cz) => canon[cz * width + cx] === cz * width + cx,\n\t\tonce: <T>(x: number, z: number, draw: () => T): T => {\n\t\t\tconst cx = Math.min(Math.max(Math.floor(x), 0), width - 1)\n\t\t\tconst cz = Math.min(Math.max(Math.floor(z), 0), depth - 1)\n\t\t\tconst key = canon[cz * width + cx]\n\t\t\tif (drawn.has(key)) return drawn.get(key) as T\n\t\t\tconst value = draw()\n\t\t\tdrawn.set(key, value)\n\t\t\treturn value\n\t\t},\n\t\tmirrorsOf: (c) => {\n\t\t\tconst out: number[] = []\n\t\t\tfor (let i = 0; i < MIRRORS; i++) {\n\t\t\t\tconst m = mirrors[c * MIRRORS + i]\n\t\t\t\tif (m >= 0) out.push(m)\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\t\tsetCell: (array, c, value) => {\n\t\t\tfor (let i = 0; i < MIRRORS; i++) {\n\t\t\t\tconst m = mirrors[c * MIRRORS + i]\n\t\t\t\tif (m >= 0) array[m] = value\n\t\t\t}\n\t\t},\n\t\tnoise(name, cells = [32, 16, 8]) {\n\t\t\tlet known = noises.get(name)\n\t\t\tif (!known) {\n\t\t\t\t// a seed of the name's own, so another name is another noise, and the same name the same\n\t\t\t\tlet salt = 0\n\t\t\t\tfor (const letter of name) salt = (salt * 31 + letter.charCodeAt(0)) >>> 0\n\t\t\t\tconst size = Math.max(width, depth)\n\t\t\t\tconst noise = layeredNoise(\n\t\t\t\t\toptions.seed + salt,\n\t\t\t\t\tcells.map((each) => Math.max(1, Math.round(size / each)))\n\t\t\t\t)\n\t\t\t\t// mirrored as the map is: read at the first of a point's mirrored set\n\t\t\t\tknown =\n\t\t\t\t\tsymmetry === 'none'\n\t\t\t\t\t\t? (x, z) => noise(x / size, z / size)\n\t\t\t\t\t\t: (x, z) => {\n\t\t\t\t\t\t\t\tfirstPlace(symmetry, width, depth, x, z, point)\n\t\t\t\t\t\t\t\treturn noise(point.x / size, point.z / size)\n\t\t\t\t\t\t\t}\n\t\t\t\tnoises.set(name, known)\n\t\t\t}\n\t\t\treturn known\n\t\t},\n\t\tplaced,\n\t\tmark: (kind, x, z, radius) => {\n\t\t\tplaced.push({ kind, x, z, radius })\n\t\t\twidest = Math.max(widest, radius)\n\t\t\tconst gx = Math.min(Math.max(Math.floor(x / GRID), 0), cols - 1)\n\t\t\tconst gz = Math.min(Math.max(Math.floor(z / GRID), 0), rows - 1)\n\t\t\tgrid[gz * cols + gx].push(placed.length - 1)\n\t\t},\n\t\tfree: (x, z, radius, kinds) => {\n\t\t\tconst reach = Math.ceil((radius + widest) / GRID)\n\t\t\tconst gx = Math.floor(x / GRID)\n\t\t\tconst gz = Math.floor(z / GRID)\n\t\t\tfor (let dz = -reach; dz <= reach; dz++)\n\t\t\t\tfor (let dx = -reach; dx <= reach; dx++) {\n\t\t\t\t\tconst gxx = gx + dx\n\t\t\t\t\tconst gzz = gz + dz\n\t\t\t\t\tif (gxx < 0 || gzz < 0 || gxx >= cols || gzz >= rows) continue\n\t\t\t\t\tfor (const i of grid[gzz * cols + gxx]) {\n\t\t\t\t\t\tconst each = placed[i]\n\t\t\t\t\t\tif (kinds && !kinds.includes(each.kind)) continue\n\t\t\t\t\t\tif (hypot(each.x - x, each.z - z) < radius + each.radius) return false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\treturn true\n\t\t},\n\t\tlevelAt: (x, z) => {\n\t\t\tconst cx = Math.min(Math.max(Math.floor(x), 0), width - 1)\n\t\t\tconst cz = Math.min(Math.max(Math.floor(z), 0), depth - 1)\n\t\t\treturn map.levels[cz * width + cx]\n\t\t},\n\t\twalkable: (x, z) => {\n\t\t\tif (x < 0 || z < 0 || x >= width || z >= depth) return false\n\t\t\treturn map.water[Math.floor(z) * width + Math.floor(x)] !== WATER_DEEP\n\t\t},\n\t\taddDoodad(doodad) {\n\t\t\tconst { scale = 1, yaw = 0, ...rest } = doodad\n\t\t\tconst made: MapDoodad = { id: nextId++, yaw, scale: typeof scale === 'number' ? [scale, scale, scale] : scale, ...rest }\n\t\t\tmap.doodads.push(made)\n\t\t\treturn made\n\t\t},\n\t\taddObject(type, owner, x, z, more = {}) {\n\t\t\tconst made: MapObject = { id: nextId++, type, owner, x, z, facing: 0, scale: 1, ...more }\n\t\t\tmap.objects.push(made)\n\t\t\treturn made\n\t\t},\n\t\taddCamp(x, z, units, more = {}) {\n\t\t\tconst made: MapCamp = { id: nextId++, x, z, units, ...more }\n\t\t\tmap.camps.push(made)\n\t\t\treturn made\n\t\t},\n\t\taddRegion(name, shape, more = {}) {\n\t\t\tconst made: MapRegion = { id: nextId++, name, shape, ...more }\n\t\t\tmap.regions.push(made)\n\t\t\treturn made\n\t\t}\n\t}\n}\n\n// ---- the ground\n\n/**\n * What `terrainPass` takes: the parameters of the generator it reads where they are not given here\n *\n * @beta\n */\nexport interface TerrainPassOptions {\n\t/** How many cliff levels the ground rises through, 1 (flat) to 4: the parameter `levels`, or 2 */\n\tlevels?: number\n\t/** How much of the map is under water, 0..1: the parameter `water`, or 0.15 */\n\twater?: number\n\t/** How much the ground rolls within a level, 0..1: the parameter `roughness`, or 0.4 */\n\troughness?: number\n\t/** How many cells a hill is across, about: the parameter `hills`, or 24 */\n\thills?: number\n\t/** Whether ramps are cut so that every part of the ground can be walked to: yes when left out */\n\tramps?: boolean\n\t/** How wide a ramp is, in cells: 3 when left out */\n\trampWidth?: number\n\t/**\n\t * The lie of the land, where it is not the noise's alone: the ground's value at a point (high is high), made from the\n\t * point, the plateau noise there (0..1) and the map; the levels and the water are cut from the values as ever (the\n\t * lowest share water). A bay (`basinShape`: the corners high, a sea in the middle, an island in it), a valley, a\n\t * ridge: a shape of the game's own\n\t */\n\tshape?: (x: number, z: number, noise: number, map: GameMap) => number\n}\n\n/**\n * What `basinShape` takes\n *\n * @beta\n */\nexport interface BasinShapeOptions {\n\t/** How big the island in the middle is, 0..1 of the way to the corners: 0.14 when left out, 0 for no island */\n\tisland?: number\n\t/** How much the noise moves the shore and the island about, 0..1: 0.25 when left out */\n\troughness?: number\n\t/**\n\t * How high the island rises, in the shape's values (the corners are at 1, the middle of the sea at 0): 0.4 when\n\t * left out, which with `water` at 0.2 and three levels lands it on the lowest dry level, the beach's, so that fords\n\t * of shallow water reach it with no cliff between\n\t */\n\theight?: number\n}\n\n/**\n * The lie of a bay, for `terrainPass`'s `shape`: the corners high, the ground falling to a sea in the middle, an\n * island in it. With `water` at 0.25–0.35 the sea takes the middle and the shore runs round it; the starts in the\n * corners (`startsPass` with a spread of 0.4), the way between them along the shore\n *\n * @beta\n */\nexport function basinShape(options: BasinShapeOptions = {}): NonNullable<TerrainPassOptions['shape']> {\n\tconst island = Math.min(Math.max(options.island ?? 0.14, 0), 0.5)\n\tconst roughness = Math.min(Math.max(options.roughness ?? 0.25, 0), 1)\n\tconst height = Math.min(Math.max(options.height ?? 0.4, 0), 1)\n\treturn (x, z, noise, map) => {\n\t\t// how far from the middle, 0 there and 1 at a corner\n\t\tconst d = hypot((x / map.width - 0.5) * 2, (z / map.depth - 0.5) * 2) / Math.SQRT2\n\t\t// the island a plateau to its rim, not a peak: high until near its edge, then down into the sea\n\t\tconst r = island > 0 ? d / island : 1\n\t\tconst rise = r < 1 ? (1 - r * r * r * r) * height : 0\n\t\treturn d + rise + (noise - 0.5) * roughness\n\t}\n}\n\n/** Whether a cell is on the map */\nconst on = (map: GameMap, cx: number, cz: number) => cx >= 0 && cz >= 0 && cx < map.width && cz < map.depth\n\n/** The four cells next to one */\nconst NEIGHBOURS: readonly (readonly [number, number])[] = [\n\t[-1, 0],\n\t[1, 0],\n\t[0, -1],\n\t[0, 1]\n]\n\n/** How steep a cell is, in radians, from the heights at its corners: as `Terrain.slopeAt` has it, read straight off the terrain */\nfunction cellSlope(terrain: { heights: Float32Array; vertsX: number }, cx: number, cz: number): number {\n\tconst { heights, vertsX } = terrain\n\tconst v = cz * vertsX + cx\n\tconst dx = (heights[v + 1] + heights[v + vertsX + 1] - heights[v] - heights[v + vertsX]) / 2\n\tconst dz = (heights[v + vertsX] + heights[v + vertsX + 1] - heights[v] - heights[v + 1]) / 2\n\treturn atan(hypot(dx, dz))\n}\n\n/** The engine's passes reach the mirror table of the context they are given; a context of a game's own has none, and mirrors by `symmetric` */\nfunction internals(ctx: GeneratorContext): GeneratorInternals {\n\tconst own = ctx as Partial<GeneratorInternals>\n\tif (own.mirrorsOf && own.setCell) return own as GeneratorInternals\n\tconst { width } = ctx.map\n\tconst mirrorsOf = (c: number) => {\n\t\tconst cx = c % width\n\t\tconst cz = (c - cx) / width\n\t\treturn ctx.symmetric(cx + 0.5, cz + 0.5).flatMap((place) => {\n\t\t\tconst mx = Math.floor(place.x)\n\t\t\tconst mz = Math.floor(place.z)\n\t\t\treturn on(ctx.map, mx, mz) ? [mz * width + mx] : []\n\t\t})\n\t}\n\treturn { mirrorsOf, setCell: (array, c, value) => mirrorsOf(c).forEach((m) => (array[m] = value)) }\n}\n\n/**\n * The ground: a height field of noise, mirrored as the map is, quantised into cliff levels with the ground rolling\n * within each, water in the low ground, and ramps cut between the levels so that every part can be walked to\n *\n * @beta\n */\nexport function terrainPass(options: TerrainPassOptions = {}): GeneratorPass {\n\treturn {\n\t\tid: 'terrain',\n\t\tname: 'The ground',\n\t\trun(ctx) {\n\t\t\tconst { map } = ctx\n\t\t\tconst { width, depth } = map\n\t\t\tconst levels = Math.min(Math.max(Math.round(options.levels ?? ctx.param('levels', 2)), 1), 4)\n\t\t\tconst waterShare = Math.min(Math.max(options.water ?? ctx.param('water', 0.15), 0), 0.6)\n\t\t\tconst roughness = Math.min(Math.max(options.roughness ?? ctx.param('roughness', 0.4), 0), 1)\n\t\t\tconst hills = Math.max(4, options.hills ?? ctx.param('hills', 24))\n\t\t\tconst plateau = ctx.noise('plateau', [hills * 2, hills])\n\t\t\tconst roll = ctx.noise('roll', [hills / 2, hills / 4, hills / 8])\n\t\t\t// the levels: the plateau noise spread evenly, so each level has about its share of the map; the lowest share is water\n\t\t\tconst values = new Float32Array(width * depth)\n\t\t\tfor (let c = 0; c < values.length; c++) {\n\t\t\t\tconst x = (c % width) + 0.5\n\t\t\t\tconst z = Math.floor(c / width) + 0.5\n\t\t\t\tvalues[c] = options.shape ? options.shape(x, z, plateau(x, z), map) : plateau(x, z)\n\t\t\t}\n\t\t\t// where the levels and the water begin, from how the noise is spread: read off a sample of it, enough to be exact to a cell or so\n\t\t\tconst stride = Math.max(1, Math.floor(values.length / 16384))\n\t\t\tconst sorted = Float32Array.from({ length: Math.floor(values.length / stride) }, (_, i) => values[i * stride]).sort()\n\t\t\tconst quantile = (q: number) => sorted[Math.min(Math.max(Math.round(q * (sorted.length - 1)), 0), sorted.length - 1)]\n\t\t\tconst waterAt = quantile(waterShare)\n\t\t\tconst steps = Array.from({ length: levels - 1 }, (_, i) => quantile(waterShare + ((1 - waterShare) * (i + 1)) / levels))\n\t\t\tfor (let c = 0; c < values.length; c++) {\n\t\t\t\tlet level = 0\n\t\t\t\tfor (const step of steps) if (values[c] >= step) level++\n\t\t\t\tmap.levels[c] = level\n\t\t\t\tmap.water[c] = values[c] < waterAt ? WATER_DEEP : WATER_NONE\n\t\t\t}\n\t\t\t// no cells alone of their level: a cliff of one cell is a spike. Each cell takes the level most of its neighbours have, twice over\n\t\t\tconst { setCell } = internals(ctx)\n\t\t\tconst counts = new Int32Array(5)\n\t\t\tfor (let round = 0; round < 2; round++) {\n\t\t\t\tconst before = map.levels.slice()\n\t\t\t\tfor (let c = 0; c < before.length; c++) {\n\t\t\t\t\tconst cx = c % width\n\t\t\t\t\tconst cz = (c - cx) / width\n\t\t\t\t\tif (!ctx.canonical(cx, cz)) continue\n\t\t\t\t\tcounts.fill(0)\n\t\t\t\t\tfor (let dz = -1; dz <= 1; dz++)\n\t\t\t\t\t\tfor (let dx = -1; dx <= 1; dx++) if (on(map, cx + dx, cz + dz)) counts[before[(cz + dz) * width + cx + dx]]++\n\t\t\t\t\tlet best = before[c]\n\t\t\t\t\tlet most = counts[best]\n\t\t\t\t\tfor (let level = 0; level < counts.length; level++) if (counts[level] > most) [best, most] = [level, counts[level]]\n\t\t\t\t\tif (best !== before[c]) setCell(map.levels, c, best)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// water lies in the low ground alone, shallow at its rim\n\t\t\tfor (let c = 0; c < values.length; c++) if (map.levels[c] > 0) map.water[c] = WATER_NONE\n\t\t\tconst deep = map.water.slice()\n\t\t\tfor (let c = 0; c < deep.length; c++) {\n\t\t\t\tif (deep[c] !== WATER_DEEP) continue\n\t\t\t\tconst cx = c % width\n\t\t\t\tconst cz = (c - cx) / width\n\t\t\t\tlet rim = false\n\t\t\t\tfor (const [dx, dz] of NEIGHBOURS) if (on(map, cx + dx, cz + dz) && deep[(cz + dz) * width + cx + dx] !== WATER_DEEP) rim = true\n\t\t\t\tif (rim) map.water[c] = WATER_SHALLOW\n\t\t\t}\n\t\t\t// the ground rolls within a level, lower under the water\n\t\t\tconst vx = width + 1\n\t\t\tfor (let iz = 0; iz <= depth; iz++)\n\t\t\t\tfor (let ix = 0; ix <= width; ix++) {\n\t\t\t\t\tconst v = iz * vx + ix\n\t\t\t\t\tmap.ground[v] = 1 + (roll(ix, iz) - 0.5) * roughness * 1.5\n\t\t\t\t}\n\t\t\tif (options.ramps !== false) cutRamps(ctx, Math.max(2, Math.round(options.rampWidth ?? 3)))\n\t\t}\n\t}\n}\n\n/**\n * Ramps between the levels, so that every part of the ground joins the rest: the parts of a level (a flood fill on the\n * level map, water left out) joined by a ramp each across the straightest stretch of cliff between two of them, the\n * nearest the middle of both first, until all are one; mirrored as the map is\n */\nfunction cutRamps(ctx: GeneratorContext, rampWidth: number): void {\n\tconst { map } = ctx\n\tconst { width, depth, levels, water, ramps } = map\n\tconst { setCell } = internals(ctx)\n\t// the parts: cells of one level, joined, with no water\n\tconst part = new Int32Array(width * depth).fill(-1)\n\tconst parts: { cells: number; x: number; z: number }[] = []\n\tconst queue = new Int32Array(width * depth)\n\tfor (let start = 0; start < part.length; start++) {\n\t\tif (part[start] >= 0 || water[start] === WATER_DEEP) continue\n\t\tconst id = parts.length\n\t\tconst sum = { cells: 0, x: 0, z: 0 }\n\t\tparts.push(sum)\n\t\tlet head = 0\n\t\tlet tail = 0\n\t\tqueue[tail++] = start\n\t\tpart[start] = id\n\t\twhile (head < tail) {\n\t\t\tconst c = queue[head++]\n\t\t\tconst cx = c % width\n\t\t\tconst cz = (c - cx) / width\n\t\t\tsum.cells++\n\t\t\tsum.x += cx + 0.5\n\t\t\tsum.z += cz + 0.5\n\t\t\tfor (const [dx, dz] of NEIGHBOURS) {\n\t\t\t\tconst nx = cx + dx\n\t\t\t\tconst nz = cz + dz\n\t\t\t\tif (!on(map, nx, nz)) continue\n\t\t\t\tconst n = nz * width + nx\n\t\t\t\tif (part[n] >= 0 || water[n] === WATER_DEEP || levels[n] !== levels[c]) continue\n\t\t\t\tpart[n] = id\n\t\t\t\tqueue[tail++] = n\n\t\t\t}\n\t\t}\n\t}\n\tfor (const each of parts) {\n\t\teach.x /= each.cells\n\t\teach.z /= each.cells\n\t}\n\tif (parts.length < 2) return\n\t// a ramp can go where a stretch of cliff is straight: `rampWidth` cells along the edge, two deep either side, all of\n\t// one level a side, none of it water. Each a candidate between the two parts, with how far from their middles it is\n\tconst half = Math.floor(rampWidth / 2)\n\tconst candidates: { a: number; b: number; cells: number[]; cost: number }[] = []\n\tconst straight = (cx: number, cz: number, dx: number, dz: number): number[] | undefined => {\n\t\t// the edge between (cx, cz) and (cx + dx, cz + dz): along it is (dz, dx)\n\t\tconst low = cz * width + cx\n\t\tconst high = (cz + dz) * width + cx + dx\n\t\tif (Math.abs(levels[low] - levels[high]) !== 1) return undefined\n\t\tconst cells: number[] = []\n\t\tfor (let along = -half; along < rampWidth - half; along++) {\n\t\t\tfor (let deep = -1; deep <= 2; deep++) {\n\t\t\t\tconst x = cx + dz * along + dx * deep\n\t\t\t\tconst z = cz + dx * along + dz * deep\n\t\t\t\tif (!on(map, x, z)) return undefined\n\t\t\t\tconst c = z * width + x\n\t\t\t\tif (water[c] !== WATER_NONE) return undefined\n\t\t\t\tif (levels[c] !== (deep <= 0 ? levels[low] : levels[high])) return undefined\n\t\t\t\tif (deep >= 0 && deep <= 1) cells.push(c)\n\t\t\t}\n\t\t}\n\t\treturn cells\n\t}\n\tfor (let cz = 0; cz < depth; cz++)\n\t\tfor (let cx = 0; cx < width; cx++) {\n\t\t\tif (!ctx.canonical(cx, cz)) continue\n\t\t\tfor (const [dx, dz] of [\n\t\t\t\t[1, 0],\n\t\t\t\t[0, 1]\n\t\t\t]) {\n\t\t\t\tif (!on(map, cx + dx, cz + dz)) continue\n\t\t\t\tconst cells = straight(cx, cz, dx, dz)\n\t\t\t\tif (!cells) continue\n\t\t\t\tconst a = part[cz * width + cx]\n\t\t\t\tconst b = part[(cz + dz) * width + cx + dx]\n\t\t\t\tif (a < 0 || b < 0 || a === b) continue\n\t\t\t\tconst mx = (parts[a].x + parts[b].x) / 2\n\t\t\t\tconst mz = (parts[a].z + parts[b].z) / 2\n\t\t\t\tcandidates.push({ a, b, cells, cost: hypot(cx + 0.5 - mx, cz + 0.5 - mz) })\n\t\t\t}\n\t\t}\n\tcandidates.sort((p, q) => p.cost - q.cost)\n\t// joined as a spanning tree: the nearest the middle first, never two between the same two parts\n\tconst root = parts.map((_, i) => i)\n\tconst find = (i: number): number => (root[i] === i ? i : (root[i] = find(root[i])))\n\tfor (const candidate of candidates) {\n\t\tconst a = find(candidate.a)\n\t\tconst b = find(candidate.b)\n\t\tif (a === b) continue\n\t\troot[a] = b\n\t\tfor (const c of candidate.cells) setCell(ramps, c, 1)\n\t}\n}\n\n// ---- the paint\n\n/**\n * What `tilesPass` takes: how a cell is painted, from what the ground is there\n *\n * @beta\n */\nexport interface TilesPassOptions {\n\t/**\n\t * The tile a cell is painted with, by id, or nothing for none (the ground's own colours): from its level, the slope\n\t * there (radians), how wet it is (a noise, 0..1) and whether it is by the water. The engine's own rule when left\n\t * out: `sand` by the water, `rock` on steep ground (the cliffs), `snow` on the top of four levels or more, `dirt`\n\t * where it is dry, each where the game has such a tile\n\t */\n\tby?: (\n\t\tcell: { x: number; z: number; level: number; slope: number; moisture: number; shore: boolean },\n\t\ttiles: readonly string[]\n\t) => string | undefined\n}\n\n/**\n * The paint: each cell a tile by what the ground is there, through the game's tiles by name\n *\n * @beta\n */\nexport function tilesPass(options: TilesPassOptions = {}): GeneratorPass {\n\treturn {\n\t\tid: 'tiles',\n\t\tname: 'The paint',\n\t\trun(ctx) {\n\t\t\tconst { map, registry } = ctx\n\t\t\tconst { width, depth } = map\n\t\t\tconst tiles = registry.tileIds\n\t\t\tif (!tiles.length) return\n\t\t\tconst terrain = mapTerrain(map)\n\t\t\tconst moisture = ctx.noise('moisture', [20, 10])\n\t\t\tlet top = 0\n\t\t\tfor (const level of map.levels) top = Math.max(top, level)\n\t\t\tconst by =\n\t\t\t\toptions.by ??\n\t\t\t\t((cell, ids) => {\n\t\t\t\t\tconst has = (id: string) => (ids.includes(id) ? id : undefined)\n\t\t\t\t\tif (cell.shore) return has('sand')\n\t\t\t\t\tif (cell.slope > 0.5) return has('rock')\n\t\t\t\t\tif (cell.level === top && top >= 3) return has('snow') ?? has('rock')\n\t\t\t\t\tif (cell.moisture < 0.35) return has('dirt')\n\t\t\t\t\treturn undefined\n\t\t\t\t})\n\t\t\tfor (let cz = 0; cz < depth; cz++)\n\t\t\t\tfor (let cx = 0; cx < width; cx++) {\n\t\t\t\t\tconst c = cz * width + cx\n\t\t\t\t\tif (map.water[c] === WATER_DEEP) continue\n\t\t\t\t\tlet shore = map.water[c] === WATER_SHALLOW\n\t\t\t\t\tif (!shore)\n\t\t\t\t\t\tfor (const [dx, dz] of NEIGHBOURS) if (on(map, cx + dx, cz + dz) && map.water[(cz + dz) * width + cx + dx] !== WATER_NONE) shore = true\n\t\t\t\t\tconst id = by(\n\t\t\t\t\t\t{ x: cx, z: cz, level: map.levels[c], slope: cellSlope(terrain, cx, cz), moisture: moisture(cx + 0.5, cz + 0.5), shore },\n\t\t\t\t\t\ttiles\n\t\t\t\t\t)\n\t\t\t\t\tmap.tiles[c] = id ? registry.tile(id) : 0\n\t\t\t\t}\n\t\t}\n\t}\n}\n\n// ---- the starts\n\n/**\n * What `startsPass` takes\n *\n * @beta\n */\nexport interface StartsPassOptions {\n\t/** How many cells around a start are flattened and dried: 6 when left out */\n\tclearing?: number\n\t/** How far from the map's middle the starts stand, 0..0.5 of its size: 0.36 when left out */\n\tspread?: number\n\t/** What a game puts at a start: its town hall and workers. Nothing when left out */\n\tfrom?: (player: MapPlayer, at: Vec2, ctx: GeneratorContext) => void\n}\n\n/**\n * The starts: as far apart as the symmetry allows (mirrored from one, or around the middle), each on flat, dry ground\n * (a clearing made for it), the player's `start` set, and what the game puts there\n *\n * @beta\n */\nexport function startsPass(options: StartsPassOptions = {}): GeneratorPass {\n\treturn {\n\t\tid: 'starts',\n\t\tname: 'The starts',\n\t\trun(ctx) {\n\t\t\tconst { map, rng } = ctx\n\t\t\tconst { width, depth } = map\n\t\t\tconst players = map.players.filter((player) => player.id !== MAP_NEUTRAL && player.id !== MAP_CREEPS)\n\t\t\tif (!players.length) return\n\t\t\tconst clearing = Math.max(2, options.clearing ?? 6)\n\t\t\tconst spread = Math.min(Math.max(options.spread ?? 0.36, 0.1), 0.48)\n\t\t\tconst symmetry = ctx.options.symmetry ?? 'none'\n\t\t\t// how many a mirrored set gives: that many starts from one place\n\t\t\tconst setSize = ctx.symmetric(width * 0.3, depth * 0.2).length\n\t\t\tconst seeds = Math.ceil(players.length / setSize)\n\t\t\tconst places: Vec2[] = []\n\t\t\tconst angle0 = symmetry === 'none' ? rng.next() * Math.PI * 2 : symmetry === 'x' ? Math.PI : symmetry === 'z' ? Math.PI / 2 : Math.PI * 1.25\n\t\t\t// a set can give fewer places than `setSize` (a start on a mirror axis is its own mirror): go on round the ring until each player has one\n\t\t\tfor (let i = 0; i < seeds + players.length && places.length < players.length; i++) {\n\t\t\t\tconst angle = angle0 + (i * Math.PI * 2) / Math.max(seeds * setSize, 1)\n\t\t\t\tconst x = width / 2 + cos(angle) * width * spread\n\t\t\t\tconst z = depth / 2 + sin(angle) * depth * spread\n\t\t\t\tfor (const place of ctx.symmetric(x, z)) if (places.length < players.length) places.push(place)\n\t\t\t}\n\t\t\tplayers.forEach((player, i) => {\n\t\t\t\tconst at = dryGround(ctx, places[i], clearing)\n\t\t\t\tclear(ctx, at, clearing)\n\t\t\t\tplayer.start = { x: at.x, z: at.z }\n\t\t\t\tctx.mark('start', at.x, at.z, clearing)\n\t\t\t\toptions.from?.(player, at, ctx)\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * The nearest place to one that is not in the water, at a cell's middle: for a pass of a game's own that puts something\n * down where the ground may be wet\n *\n * @beta\n */\nexport const nearestDryGround = (ctx: GeneratorContext, at: Vec2, reach: number): Vec2 => dryGround(ctx, at, reach)\n\n/**\n * The ground around a place made flat and dry: one level (the one there, or `level`), no water, no ramps, the ground at\n * one height eased into what is around; mirrored as the map is, unless `alone`. What a start's clearing and a mine's\n * are made with, for a pass of a game's own\n *\n * @beta\n */\nexport const clearGround = (ctx: GeneratorContext, at: Vec2, radius: number, alone = false, level?: number): void =>\n\tclear(ctx, at, radius, alone, level ?? ctx.levelAt(at.x, at.z))\n\n/** The nearest place to one that is not in the water, at a cell's middle */\nfunction dryGround(ctx: GeneratorContext, at: Vec2, reach: number): Vec2 {\n\tconst { map } = ctx\n\tconst { width, depth } = map\n\tconst cx = Math.min(Math.max(Math.floor(at.x), 1), width - 2)\n\tconst cz = Math.min(Math.max(Math.floor(at.z), 1), depth - 2)\n\tfor (let r = 0; r <= reach * 3; r++)\n\t\tfor (let dz = -r; dz <= r; dz++)\n\t\t\tfor (let dx = -r; dx <= r; dx++) {\n\t\t\t\tif (Math.max(Math.abs(dx), Math.abs(dz)) !== r) continue\n\t\t\t\tconst x = cx + dx\n\t\t\t\tconst z = cz + dz\n\t\t\t\tif (x < 1 || z < 1 || x >= width - 1 || z >= depth - 1) continue\n\t\t\t\tif (map.water[z * width + x] === WATER_NONE) return { x: x + 0.5, z: z + 0.5 }\n\t\t\t}\n\treturn { x: cx + 0.5, z: cz + 0.5 }\n}\n\n/** The ground around a place made flat and dry: one level, no water, no ramps, the ground at one height. Mirrored, unless `alone` */\nfunction clear(ctx: GeneratorContext, at: Vec2, radius: number, alone = false, level = ctx.levelAt(at.x, at.z)): void {\n\tconst { map } = ctx\n\tconst { width, depth } = map\n\tconst vx = width + 1\n\tlet height = 0\n\tlet count = 0\n\tfor (let iz = Math.max(Math.floor(at.z - radius), 0); iz <= Math.min(Math.ceil(at.z + radius), depth); iz++)\n\t\tfor (let ix = Math.max(Math.floor(at.x - radius), 0); ix <= Math.min(Math.ceil(at.x + radius), width); ix++) {\n\t\t\theight += map.ground[iz * vx + ix]\n\t\t\tcount++\n\t\t}\n\theight /= Math.max(count, 1)\n\tfor (const place of alone ? [at] : ctx.symmetric(at.x, at.z)) {\n\t\tfor (let cz = Math.max(Math.floor(place.z - radius), 0); cz < Math.min(Math.ceil(place.z + radius), depth); cz++)\n\t\t\tfor (let cx = Math.max(Math.floor(place.x - radius), 0); cx < Math.min(Math.ceil(place.x + radius), width); cx++) {\n\t\t\t\tif (hypot(cx + 0.5 - place.x, cz + 0.5 - place.z) > radius) continue\n\t\t\t\tconst c = cz * width + cx\n\t\t\t\tmap.levels[c] = level\n\t\t\t\tmap.water[c] = WATER_NONE\n\t\t\t\tmap.ramps[c] = 0\n\t\t\t}\n\t\tfor (let iz = Math.max(Math.floor(place.z - radius), 0); iz <= Math.min(Math.ceil(place.z + radius), depth); iz++)\n\t\t\tfor (let ix = Math.max(Math.floor(place.x - radius), 0); ix <= Math.min(Math.ceil(place.x + radius), width); ix++) {\n\t\t\t\tconst d = hypot(ix - place.x, iz - place.z)\n\t\t\t\tif (d > radius) continue\n\t\t\t\t// flat in the middle, eased into the ground around at the rim\n\t\t\t\tconst t = Math.min(Math.max((d - radius * 0.6) / (radius * 0.4), 0), 1)\n\t\t\t\tconst v = iz * vx + ix\n\t\t\t\tmap.ground[v] = height + (map.ground[v] - height) * t * t * (3 - 2 * t)\n\t\t\t}\n\t}\n}\n\n// ---- things scattered\n\n/**\n * What `scatterPass` takes: how much of what, where\n *\n * @beta\n */\nexport interface ScatterPassOptions {\n\t/** What the things are, for the passes after (`placed`): `trees`, `rocks` */\n\tkind: string\n\t/** Puts one down at a place: a doodad, a unit, a camp, a region */\n\twhat: (ctx: GeneratorContext, at: Vec2) => void\n\t/** How much of the map they cover, 0..1: the parameter `<kind>` where the generator has one, or 0.12 */\n\tdensity?: number\n\t/** How far apart they are at least, in cells: 1.5 when left out */\n\tspacing?: number\n\t/** How big each is, for what comes after to keep off: half the spacing when left out */\n\tradius?: number\n\t/** How far from a start they keep, in cells: 10 when left out */\n\tavoid?: number\n\t/** What else they keep off, by kind (`placed`), with how far: the starts always */\n\tavoidKinds?: Record<string, number>\n\t/** Where they may go: a cell's level, slope, water and the noise of the kind (0..1, patches). On any dry ground when left out */\n\twhere?: (cell: { x: number; z: number; level: number; slope: number; noise: number; shore: boolean }) => boolean\n\t/** In patches of a noise (how much the noise decides, 0 even, 1 all in patches): 0.6 when left out */\n\tpatches?: number\n}\n\n/**\n * Things scattered over the map: as many as the density says, in patches of a noise, at least `spacing` apart, off\n * the starts and what else they avoid, where they may go; each put down by `what`, mirrored as the map is. Trees now;\n * rocks, houses, ruins and the rest the same way, with another `what`\n *\n * @beta\n */\nexport function scatterPass(options: ScatterPassOptions): GeneratorPass {\n\treturn {\n\t\tid: `scatter:${options.kind}`,\n\t\tname: `Scattered: ${options.kind}`,\n\t\trun(ctx) {\n\t\t\tconst { map, rng } = ctx\n\t\t\tconst { width, depth } = map\n\t\t\tconst density = Math.min(Math.max(options.density ?? ctx.param(options.kind, 0.12), 0), 1)\n\t\t\tif (density <= 0) return\n\t\t\tconst spacing = Math.max(0.5, options.spacing ?? 1.5)\n\t\t\tconst radius = options.radius ?? spacing / 2\n\t\t\tconst avoid = options.avoid ?? 10\n\t\t\tconst patches = Math.min(Math.max(options.patches ?? 0.6, 0), 1)\n\t\t\tconst noise = ctx.noise(`scatter:${options.kind}`, [24, 12, 6])\n\t\t\t// the slopes, for a `where` that asks: the terrain made once, only then\n\t\t\tlet made: ReturnType<typeof mapTerrain> | undefined\n\t\t\tconst terrain = () => (made ??= mapTerrain(map))\n\t\t\t// what is put down, in a grid of the spacing, so that nothing comes too close\n\t\t\tconst cell = spacing\n\t\t\tconst cols = Math.ceil(width / cell)\n\t\t\tconst rows = Math.ceil(depth / cell)\n\t\t\tconst grid: Vec2[][] = Array.from({ length: cols * rows }, () => [])\n\t\t\tconst tooClose = (x: number, z: number) => {\n\t\t\t\tconst gx = Math.floor(x / cell)\n\t\t\t\tconst gz = Math.floor(z / cell)\n\t\t\t\tfor (let dz = -1; dz <= 1; dz++)\n\t\t\t\t\tfor (let dx = -1; dx <= 1; dx++) {\n\t\t\t\t\t\tconst gxx = gx + dx\n\t\t\t\t\t\tconst gzz = gz + dz\n\t\t\t\t\t\tif (gxx < 0 || gzz < 0 || gxx >= cols || gzz >= rows) continue\n\t\t\t\t\t\tfor (const other of grid[gzz * cols + gxx]) if (hypot(other.x - x, other.z - z) < spacing) return true\n\t\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst put = (x: number, z: number) => {\n\t\t\t\tgrid[Math.floor(z / cell) * cols + Math.floor(x / cell)].push({ x, z })\n\t\t\t\tctx.mark(options.kind, x, z, radius)\n\t\t\t\toptions.what(ctx, { x, z })\n\t\t\t}\n\t\t\t// each cell tries once, the first of its mirrored set for all of them: a draw against the density, in patches\n\t\t\tfor (let cz = 0; cz < depth; cz++)\n\t\t\t\tfor (let cx = 0; cx < width; cx++) {\n\t\t\t\t\tif (!ctx.canonical(cx, cz)) continue\n\t\t\t\t\tconst c = cz * width + cx\n\t\t\t\t\tconst x = cx + rng.next()\n\t\t\t\t\tconst z = cz + rng.next()\n\t\t\t\t\tconst n = noise(x, z)\n\t\t\t\t\tconst chance = density * (1 - patches + patches * Math.min(Math.max((n - 0.35) / 0.3, 0), 1) * 2)\n\t\t\t\t\tif (rng.next() >= chance) continue\n\t\t\t\t\tif (map.water[c] !== WATER_NONE) continue\n\t\t\t\t\tif (options.where) {\n\t\t\t\t\t\tconst shore = NEIGHBOURS.some(([dx, dz]) => on(map, cx + dx, cz + dz) && map.water[(cz + dz) * width + cx + dx] !== WATER_NONE)\n\t\t\t\t\t\tif (!options.where({ x, z, level: map.levels[c], slope: cellSlope(terrain(), cx, cz), noise: n, shore })) continue\n\t\t\t\t\t}\n\t\t\t\t\tif (map.ramps[c]) continue\n\t\t\t\t\tif (!ctx.free(x, z, avoid, ['start'])) continue\n\t\t\t\t\tif (options.avoidKinds && Object.entries(options.avoidKinds).some(([kind, far]) => !ctx.free(x, z, far, [kind]))) continue\n\t\t\t\t\tconst places = ctx.symmetric(x, z).filter((place) => place.x >= 0 && place.z >= 0 && place.x < width && place.z < depth)\n\t\t\t\t\tif (places.some((place) => tooClose(place.x, place.z))) continue\n\t\t\t\t\tfor (const place of places) put(place.x, place.z)\n\t\t\t\t}\n\t\t}\n\t}\n}\n\n// ---- resources\n\n/**\n * What `resourcesPass` takes: where the game's mines go, and what the game puts there\n *\n * @beta\n */\nexport interface ResourcesPassOptions {\n\t/** How far from each start its own stands, in cells: 8 when left out; `false` for none at the starts (a game puts those down itself) */\n\tmain?: number | false\n\t/** How many more there are besides the starts', spread over the map and mirrored: 2 when left out */\n\textra?: number\n\t/** How far apart the extra ones keep from each other and from the starts, in cells: 20 when left out */\n\tspacing?: number\n\t/**\n\t * How many cells around each are made flat and dry for it, as a start's clearing is: 3 when left out, enough for a\n\t * mine of 4 by 4; 0 for none\n\t */\n\tclearing?: number\n\t/** Puts the resource down: the game's mine, a camp guarding it. Told the start it is for, where it is one's */\n\tfrom: (ctx: GeneratorContext, at: Vec2, start?: MapPlayer) => void\n}\n\n/**\n * Resources: one near each start (towards the map's middle, as far as `main` says), and more spread over the map,\n * mirrored as the map is, each put down by the game\n *\n * @beta\n */\nexport function resourcesPass(options: ResourcesPassOptions): GeneratorPass {\n\treturn {\n\t\tid: 'resources',\n\t\tname: 'The resources',\n\t\trun(ctx) {\n\t\t\tconst { map, rng } = ctx\n\t\t\tconst { width, depth } = map\n\t\t\tconst main = options.main ?? 8\n\t\t\tconst spacing = options.spacing ?? 20\n\t\t\tconst clearing = options.clearing ?? 3\n\t\t\tfor (const player of map.players) {\n\t\t\t\tif (!player.start || main === false) continue\n\t\t\t\tconst toward = atan2(depth / 2 - player.start.z, width / 2 - player.start.x) + (rng.next() - 0.5) * 0.8\n\t\t\t\tconst at = dryGround(ctx, { x: player.start.x + cos(toward) * main, z: player.start.z + sin(toward) * main }, 4)\n\t\t\t\t// on the start's level, its clearing reaching the start's: its workers walk to it\n\t\t\t\tif (clearing > 0) clear(ctx, at, clearing, true, ctx.levelAt(player.start.x, player.start.z))\n\t\t\t\tctx.mark('resource', at.x, at.z, 3)\n\t\t\t\toptions.from(ctx, at, player)\n\t\t\t}\n\t\t\tconst extra = Math.max(0, Math.round(options.extra ?? 2))\n\t\t\tlet placed = 0\n\t\t\tfor (let attempt = 0; attempt < extra * 40 && placed < extra; attempt++) {\n\t\t\t\tconst x = 4 + rng.next() * (width - 8)\n\t\t\t\tconst z = 4 + rng.next() * (depth - 8)\n\t\t\t\tif (!ctx.canonical(Math.floor(x), Math.floor(z))) continue\n\t\t\t\tconst places = ctx.symmetric(x, z)\n\t\t\t\tif (!places.every((place) => ctx.walkable(place.x, place.z) && ctx.free(place.x, place.z, spacing, ['start', 'resource']))) continue\n\t\t\t\tfor (const place of places) {\n\t\t\t\t\tconst at = dryGround(ctx, place, 4)\n\t\t\t\t\tif (clearing > 0) clear(ctx, at, clearing, true)\n\t\t\t\t\tctx.mark('resource', at.x, at.z, 3)\n\t\t\t\t\toptions.from(ctx, at)\n\t\t\t\t}\n\t\t\t\tplaced++\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ---- roads\n\n/**\n * What `roadsPass` takes\n *\n * @beta\n */\nexport interface RoadsPassOptions {\n\t/** The tile the road is painted with, by id */\n\ttile: string\n\t/** How wide, in cells: 2 when left out */\n\twidth?: number\n\t/** Between what: every two starts when left out, or places of the map's own */\n\tbetween?: Vec2[]\n}\n\n/**\n * Roads between the starts (or places given), the way something on foot would go (over the level map, by ramps, around\n * water; the gentlest ground preferred), painted with a tile\n *\n * @beta\n */\nexport function roadsPass(options: RoadsPassOptions): GeneratorPass {\n\treturn {\n\t\tid: 'roads',\n\t\tname: 'The roads',\n\t\trun(ctx) {\n\t\t\tconst { map, registry } = ctx\n\t\t\tif (!registry.tileIds.includes(options.tile)) return\n\t\t\tconst tile = registry.tile(options.tile)\n\t\t\tconst wide = Math.max(1, Math.round(options.width ?? 2))\n\t\t\tconst places = options.between ?? map.players.flatMap((player) => (player.start ? [player.start] : []))\n\t\t\tconst terrain = mapTerrain(map)\n\t\t\tfor (let i = 0; i < places.length; i++)\n\t\t\t\tfor (let j = i + 1; j < places.length; j++) {\n\t\t\t\t\tconst path = findPath(map, terrain, places[i], places[j])\n\t\t\t\t\tfor (const c of path) {\n\t\t\t\t\t\tconst cx = c % map.width\n\t\t\t\t\t\tconst cz = (c - cx) / map.width\n\t\t\t\t\t\tfor (let dz = 0; dz < wide; dz++)\n\t\t\t\t\t\t\tfor (let dx = 0; dx < wide; dx++) {\n\t\t\t\t\t\t\t\tconst x = cx + dx - Math.floor(wide / 2)\n\t\t\t\t\t\t\t\tconst z = cz + dz - Math.floor(wide / 2)\n\t\t\t\t\t\t\t\tif (on(map, x, z) && map.water[z * map.width + x] === WATER_NONE) map.tiles[z * map.width + x] = tile\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t}\n\t}\n}\n\n/** The cells of the way from one place to another over the level map: A* with the gentlest ground preferred; nothing where there is none */\nfunction findPath(map: GameMap, terrain: ReturnType<typeof mapTerrain>, from: Vec2, to: Vec2): number[] {\n\tconst { width, depth, levels, ramps, water } = map\n\tconst start = Math.floor(from.z) * width + Math.floor(from.x)\n\tconst goal = Math.floor(to.z) * width + Math.floor(to.x)\n\tconst passable = (a: number, b: number) => levels[a] === levels[b] || ramps[a] > 0 || ramps[b] > 0\n\tconst cost = new Float32Array(width * depth).fill(Infinity)\n\tconst came = new Int32Array(width * depth).fill(-1)\n\tconst closed = new Uint8Array(width * depth)\n\t// a heap of what is to be looked at, the nearest estimate first\n\tconst heapCells: number[] = []\n\tconst heapCosts: number[] = []\n\tconst push = (estimate: number, c: number) => {\n\t\theapCells.push(c)\n\t\theapCosts.push(estimate)\n\t\tlet i = heapCells.length - 1\n\t\twhile (i > 0) {\n\t\t\tconst parent = (i - 1) >> 1\n\t\t\tif (heapCosts[parent] <= heapCosts[i]) break\n\t\t\t;[heapCosts[parent], heapCosts[i]] = [heapCosts[i], heapCosts[parent]]\n\t\t\t;[heapCells[parent], heapCells[i]] = [heapCells[i], heapCells[parent]]\n\t\t\ti = parent\n\t\t}\n\t}\n\tconst pop = (): number => {\n\t\tconst top = heapCells[0]\n\t\tconst lastCell = heapCells.pop()!\n\t\tconst lastCost = heapCosts.pop()!\n\t\tif (heapCells.length) {\n\t\t\theapCells[0] = lastCell\n\t\t\theapCosts[0] = lastCost\n\t\t\tlet i = 0\n\t\t\tfor (;;) {\n\t\t\t\tconst l = i * 2 + 1\n\t\t\t\tconst r = l + 1\n\t\t\t\tlet best = i\n\t\t\t\tif (l < heapCells.length && heapCosts[l] < heapCosts[best]) best = l\n\t\t\t\tif (r < heapCells.length && heapCosts[r] < heapCosts[best]) best = r\n\t\t\t\tif (best === i) break\n\t\t\t\t;[heapCosts[best], heapCosts[i]] = [heapCosts[i], heapCosts[best]]\n\t\t\t\t;[heapCells[best], heapCells[i]] = [heapCells[i], heapCells[best]]\n\t\t\t\ti = best\n\t\t\t}\n\t\t}\n\t\treturn top\n\t}\n\tconst h = (c: number) => hypot((c % width) - (goal % width), Math.floor(c / width) - Math.floor(goal / width))\n\tcost[start] = 0\n\tpush(h(start), start)\n\twhile (heapCells.length) {\n\t\tconst c = pop()\n\t\tif (closed[c]) continue\n\t\tclosed[c] = 1\n\t\tif (c === goal) break\n\t\tconst cx = c % width\n\t\tconst cz = (c - cx) / width\n\t\tfor (const [dx, dz] of NEIGHBOURS) {\n\t\t\tconst nx = cx + dx\n\t\t\tconst nz = cz + dz\n\t\t\tif (!on(map, nx, nz)) continue\n\t\t\tconst n = nz * width + nx\n\t\t\tif (closed[n] || water[n] === WATER_DEEP || !passable(c, n)) continue\n\t\t\tconst step = 1 + terrain.slopeAt(nx + 0.5, nz + 0.5) * 4 + (water[n] ? 2 : 0)\n\t\t\tconst next = cost[c] + step\n\t\t\tif (next >= cost[n]) continue\n\t\t\tcost[n] = next\n\t\t\tcame[n] = c\n\t\t\tpush(next + h(n), n)\n\t\t}\n\t}\n\tif (came[goal] < 0 && goal !== start) return []\n\tconst path: number[] = []\n\tfor (let c = goal; c >= 0; c = came[c]) {\n\t\tpath.push(c)\n\t\tif (c === start) break\n\t}\n\treturn path.reverse()\n}\n\n// ---- a preset\n\n/**\n * What the engine's preset takes from a game: what its scenery is\n *\n * @beta\n */\nexport interface PresetGeneratorOptions {\n\t/** The models of trees, by their paths in `models/`: one picked for each. No trees when left out */\n\ttrees?: string[]\n\t/** How big a tree is drawn, and how much that varies: 1, by a fifth, when left out */\n\ttreeScale?: { scale?: number; vary?: number }\n\t/** The models of rocks, the same way. None when left out */\n\trocks?: string[]\n\t/** What a game puts at a start (`startsPass`): its hall and workers */\n\tstart?: StartsPassOptions['from']\n}\n\n/**\n * A generator to take whole: hills and water, the paint, the starts, trees in patches and rocks about, with the\n * parameters `levels`, `water`, `roughness`, `hills`, `trees` and `rocks`; what the trees and rocks are is the game's\n * to say\n *\n * @beta\n */\nexport function presetGenerator(options: PresetGeneratorOptions = {}): MapGenerator {\n\tconst { trees = [], rocks = [], treeScale = {} } = options\n\tconst scale = treeScale.scale ?? 1\n\tconst vary = treeScale.vary ?? 0.2\n\treturn {\n\t\tparams: [\n\t\t\t{ id: 'levels', name: 'Cliff levels', description: 'How many levels the ground rises through', default: 2, min: 1, max: 4, step: 1 },\n\t\t\t{ id: 'water', name: 'Water', description: 'How much of the map is under water', default: 0.15, min: 0, max: 0.5, step: 0.05 },\n\t\t\t{ id: 'roughness', name: 'Roughness', description: 'How much the ground rolls', default: 0.4, min: 0, max: 1, step: 0.05 },\n\t\t\t{ id: 'hills', name: 'Hills', description: 'How many cells a hill is across', default: 24, min: 8, max: 64, step: 4 },\n\t\t\t{ id: 'trees', name: 'Trees', description: 'How much of the map is woods', default: trees.length ? 0.12 : 0, min: 0, max: 0.5, step: 0.02 },\n\t\t\t{ id: 'rocks', name: 'Rocks', description: 'How many rocks lie about', default: rocks.length ? 0.02 : 0, min: 0, max: 0.2, step: 0.01 }\n\t\t],\n\t\tpasses: [\n\t\t\tterrainPass(),\n\t\t\ttilesPass(),\n\t\t\tstartsPass({ from: options.start }),\n\t\t\t...(trees.length\n\t\t\t\t? [\n\t\t\t\t\t\tscatterPass({\n\t\t\t\t\t\t\tkind: 'trees',\n\t\t\t\t\t\t\tspacing: 1.6,\n\t\t\t\t\t\t\twhat: (ctx, at) => {\n\t\t\t\t\t\t\t\tconst size = scale * (1 + (ctx.rng.next() - 0.5) * 2 * vary)\n\t\t\t\t\t\t\t\tctx.addDoodad({\n\t\t\t\t\t\t\t\t\tmodel: trees[ctx.rng.int(0, trees.length - 1)],\n\t\t\t\t\t\t\t\t\tx: at.x,\n\t\t\t\t\t\t\t\t\tz: at.z,\n\t\t\t\t\t\t\t\t\tyaw: ctx.rng.next() * Math.PI * 2,\n\t\t\t\t\t\t\t\t\tscale: size,\n\t\t\t\t\t\t\t\t\tblocks: 'walk',\n\t\t\t\t\t\t\t\t\tradius: 0.5\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t]\n\t\t\t\t: []),\n\t\t\t...(rocks.length\n\t\t\t\t? [\n\t\t\t\t\t\tscatterPass({\n\t\t\t\t\t\t\tkind: 'rocks',\n\t\t\t\t\t\t\tspacing: 3,\n\t\t\t\t\t\t\tpatches: 0.3,\n\t\t\t\t\t\t\tavoidKinds: { trees: 1 },\n\t\t\t\t\t\t\twhat: (ctx, at) => {\n\t\t\t\t\t\t\t\tconst size = scale * (0.8 + ctx.rng.next() * 0.6)\n\t\t\t\t\t\t\t\tctx.addDoodad({\n\t\t\t\t\t\t\t\t\tmodel: rocks[ctx.rng.int(0, rocks.length - 1)],\n\t\t\t\t\t\t\t\t\tx: at.x,\n\t\t\t\t\t\t\t\t\tz: at.z,\n\t\t\t\t\t\t\t\t\tyaw: ctx.rng.next() * Math.PI * 2,\n\t\t\t\t\t\t\t\t\tscale: size,\n\t\t\t\t\t\t\t\t\tblocks: 'walk',\n\t\t\t\t\t\t\t\t\tradius: 0.6\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t]\n\t\t\t\t: [])\n\t\t]\n\t}\n}\n","import type { AbilityDef, BuffDef, ItemDef, UnitTypeDef, UpgradeDef } from './defs'\nimport { DATA_KINDS, type DataKind, type GameData, withData } from './gameData'\nimport type { GameModule } from './game'\nimport type { GameBuilder, ModDef } from './mods'\nimport type { RaceDef } from './races'\nimport type { RulesInit } from './rules'\n\n/*\n * A pack of content as JSON (campaign plan RC6): definitions, data over them and rules, in a file a game names and\n * fetches before its world is made (`packs/<id>/pack.json`), made into a mod (`packFromJson`) that `composeGame`\n * applies as any other. The same bytes in the same order give the same game: each list is added in the order of its\n * ids, packs in the order they are named, and what a save and a lobby check (the game's hash) has each pack's own.\n */\n\n/**\n * A pack of content as its file has it (`packs/<id>/pack.json`): plain data, checked against the pack's schema\n * (`@v12-engine/engine/schemas/pack.schema.json`) as it is read. Its definitions are added to the game's, or put in the place of those of the same id;\n * then its `data` is laid over the whole as a `data.json` is (`withData`), and its `rules` over the game's\n *\n * @beta\n */\nexport interface PackFile {\n\t/** Letters, digits, dots and dashes: what the game composed of it is called by (`melee+<id>`) */\n\tid: string\n\t/** `major.minor.patch` */\n\tversion: string\n\tname?: string\n\t/** The game and the packs or mods it is made for, as a mod's (`ModDef.requires`) */\n\trequires?: string[]\n\tunits?: UnitTypeDef[]\n\tabilities?: AbilityDef[]\n\tbuffs?: BuffDef[]\n\titems?: ItemDef[]\n\tupgrades?: UpgradeDef[]\n\traces?: RaceDef[]\n\t/** The rules it changes, as data (`GameBuilder.rules`) */\n\trules?: RulesInit\n\t/** Values over the definitions, as a `data.json` has them (`GameData`): the editor's Data panel writes here for a pack */\n\tdata?: GameData\n\t/** What its units look like, as a `looks.json` has them: the client's to lay over the game's view */\n\tlooks?: Record<string, unknown>\n}\n\n/**\n * A mod made of a pack (`packFromJson`): the mod, and the pack's file it was made of\n *\n * @beta\n */\nexport interface PackMod extends ModDef {\n\treadonly pack: PackFile\n\t/** The hash of the pack's bytes as they were read: kept with the game's mods, so the game's hash has it */\n\treadonly hash: string\n}\n\n/**\n * Why a pack's file is not one, where it is first wrong\n *\n * @beta\n */\nexport class PackError extends Error {}\n\nconst ID = /^[a-z0-9][a-z0-9._-]*$/i\nconst VERSION = /^\\d+(\\.\\d+){0,2}$/\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/**\n * Checks a pack's file as it is read (the schema's rules a loader needs: the pack's schema has all of them):\n * its id and version, and that each list is of definitions with an id, once each. Throws `PackError` saying where\n *\n * @beta\n */\nexport function checkPack(json: unknown, where = 'the pack'): PackFile {\n\tconst wrong = (why: string): never => {\n\t\tthrow new PackError(`${where}: ${why}`)\n\t}\n\tif (!isRecord(json)) return wrong('is no object')\n\tif (typeof json.id !== 'string' || !ID.test(json.id)) wrong('its id is letters, digits, dots and dashes')\n\tif (typeof json.version !== 'string' || !VERSION.test(json.version)) wrong('its version is major.minor.patch')\n\tif (json.requires !== undefined && (!Array.isArray(json.requires) || json.requires.some((each) => typeof each !== 'string')))\n\t\twrong('requires is a list of words')\n\tfor (const kind of DATA_KINDS) {\n\t\tconst list = json[kind]\n\t\tif (list === undefined) continue\n\t\tif (!Array.isArray(list)) wrong(`${kind} is no list`)\n\t\tconst seen = new Set<string>()\n\t\tfor (const [at, def] of (list as unknown[]).entries()) {\n\t\t\tif (!isRecord(def) || typeof def.id !== 'string' || !def.id) wrong(`${kind}[${at}] has no id`)\n\t\t\tconst id = (def as { id: string }).id\n\t\t\tif (seen.has(id)) wrong(`${kind} has \"${id}\" twice`)\n\t\t\tseen.add(id)\n\t\t}\n\t}\n\tfor (const part of ['rules', 'data', 'looks'] as const) if (json[part] !== undefined && !isRecord(json[part])) wrong(`${part} is no object`)\n\tconst known = new Set(['$schema', 'id', 'version', 'name', 'requires', ...DATA_KINDS, 'rules', 'data', 'looks'])\n\tconst unknown = Object.keys(json).find((key) => !known.has(key))\n\tif (unknown) wrong(`\"${unknown}\" is nothing a pack has`)\n\treturn json as unknown as PackFile\n}\n\n/** A part of a JSON Schema, as far as the pack's schema uses one (`@v12-engine/engine/schemas/pack.schema.json`) */\ninterface SchemaPart {\n\t$ref?: string\n\ttype?: string | string[]\n\tconst?: unknown\n\tenum?: unknown[]\n\tanyOf?: SchemaPart[]\n\tnot?: SchemaPart\n\tproperties?: Record<string, SchemaPart>\n\trequired?: string[]\n\tadditionalProperties?: boolean | SchemaPart\n\tpropertyNames?: SchemaPart\n\titems?: SchemaPart | SchemaPart[]\n\tminItems?: number\n\tmaxItems?: number\n\tdefinitions?: Record<string, SchemaPart>\n}\n\n/** A word with its article: an object, a number */\nconst an = (word: string) => `${/^[aeiou]/.test(word) ? 'an' : 'a'} ${word}`\n\n/** The type of a value as a schema says it */\nconst typeOf = (value: unknown): string =>\n\tvalue === null ? 'null' : Array.isArray(value) ? 'array' : Number.isInteger(value) ? 'integer' : typeof value\n\n/**\n * Checks a pack's file against the pack's schema (`@v12-engine/engine/schemas/pack.schema.json`, made of `PackFile`):\n * where it is first wrong, in words with its place (`units[2].stats.health: is a string, not a number`), or nothing\n * for one that is right. A small reader of the schema, as far as it uses JSON Schema: what a page that loads packs\n * fetches with them, so that a game without packs carries none of it\n *\n * @beta\n */\nexport function checkPackSchema(json: unknown, schema: object): string | undefined {\n\tconst root = schema as SchemaPart\n\tconst resolve = (part: SchemaPart): SchemaPart => {\n\t\tlet at = part\n\t\tfor (let hops = 0; at.$ref && hops < 32; hops++) at = root.definitions?.[decodeURIComponent(at.$ref.replace('#/definitions/', ''))] ?? {}\n\t\treturn at\n\t}\n\tconst check = (value: unknown, given: SchemaPart, where: string): string | undefined => {\n\t\tconst part = resolve(given)\n\t\tconst type = typeOf(value)\n\t\tif (part.type !== undefined) {\n\t\t\tconst types = Array.isArray(part.type) ? part.type : [part.type]\n\t\t\tif (!types.some((each) => each === type || (each === 'number' && type === 'integer')))\n\t\t\t\treturn `${where || 'the pack'}: is ${an(type)}, not ${types.join(' or ')}`\n\t\t}\n\t\tif ('const' in part && value !== part.const) return `${where || 'the pack'}: is not ${JSON.stringify(part.const)}`\n\t\tif (part.enum && !part.enum.includes(value))\n\t\t\treturn `${where || 'the pack'}: is none of ${part.enum.map((each) => JSON.stringify(each)).join(', ')}`\n\t\tif (part.not && check(value, part.not, where) === undefined) return `${where || 'the pack'}: is what it may not be`\n\t\tif (part.anyOf) {\n\t\t\tconst wrongs = part.anyOf.map((each) => check(value, each, where))\n\t\t\tif (wrongs.every((wrong) => wrong !== undefined)) {\n\t\t\t\t// the form that went furthest says why: the one wrong deepest in\n\t\t\t\treturn wrongs.reduce((deepest, wrong) => (wrong!.length > deepest!.length ? wrong : deepest))\n\t\t\t}\n\t\t}\n\t\tif (type === 'object' && (part.properties || part.required || part.additionalProperties !== undefined || part.propertyNames)) {\n\t\t\tconst object = value as Record<string, unknown>\n\t\t\tfor (const field of part.required ?? []) if (!(field in object)) return `${where || 'the pack'}: has no ${field}`\n\t\t\tfor (const [field, each] of Object.entries(object)) {\n\t\t\t\tconst at = where ? `${where}.${field}` : field\n\t\t\t\tif (part.propertyNames) {\n\t\t\t\t\tconst name = check(field, part.propertyNames, at)\n\t\t\t\t\tif (name) return name\n\t\t\t\t}\n\t\t\t\tconst own = part.properties?.[field]\n\t\t\t\tif (own) {\n\t\t\t\t\tconst wrong = check(each, own, at)\n\t\t\t\t\tif (wrong) return wrong\n\t\t\t\t} else if (part.additionalProperties === false) return `${at}: is nothing ${where || 'a pack'} has`\n\t\t\t\telse if (typeof part.additionalProperties === 'object') {\n\t\t\t\t\tconst wrong = check(each, part.additionalProperties, at)\n\t\t\t\t\tif (wrong) return wrong\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (type === 'array') {\n\t\t\tconst list = value as unknown[]\n\t\t\tif (part.minItems !== undefined && list.length < part.minItems) return `${where || 'the pack'}: has fewer than ${part.minItems}`\n\t\t\tif (part.maxItems !== undefined && list.length > part.maxItems) return `${where || 'the pack'}: has more than ${part.maxItems}`\n\t\t\tif (part.items)\n\t\t\t\tfor (const [at, each] of list.entries()) {\n\t\t\t\t\tconst item = Array.isArray(part.items) ? part.items[at] : part.items\n\t\t\t\t\tconst wrong = item && check(each, item, `${where}[${at}]`)\n\t\t\t\t\tif (wrong) return wrong\n\t\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}\n\treturn check(json, root, '')\n}\n\n/** FNV-1a, twice over with different starts, of a text: as the game's hash is */\nfunction hashOf(text: string): string {\n\tlet a = 0x811c9dc5\n\tlet b = 0x01000193 ^ 0x5bd1e995\n\tfor (let i = 0; i < text.length; i++) {\n\t\tconst c = text.charCodeAt(i)\n\t\ta = Math.imul(a ^ c, 0x01000193)\n\t\tb = Math.imul(b ^ c, 0x5bd1e995)\n\t}\n\treturn (a >>> 0).toString(16).padStart(8, '0') + (b >>> 0).toString(16).padStart(8, '0')\n}\n\nconst byId = <T extends { id: string }>(defs: readonly T[]) => [...defs].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n\n/** The builder's collection of a kind of the game's data */\nconst collectionOf = (game: GameBuilder, kind: DataKind) => game[kind] as unknown as GameBuilder['units']\n\n/**\n * Makes a mod of a pack's file (its text, or what was parsed of it): checked, then applying its definitions (each\n * list in the order of its ids, a definition the game has put in its place), its `data` over the whole and its\n * `rules`. Its hash, of the text as given, goes with the game's mods\n *\n * @beta\n */\nexport function packFromJson(json: string | unknown, where?: string): PackMod {\n\tconst text = typeof json === 'string' ? json : JSON.stringify(json)\n\tlet parsed: unknown\n\ttry {\n\t\tparsed = typeof json === 'string' ? JSON.parse(json) : json\n\t} catch (error) {\n\t\tthrow new PackError(`${where ?? 'the pack'}: is not JSON (${error instanceof Error ? error.message : String(error)})`)\n\t}\n\tconst pack = checkPack(parsed, where)\n\treturn {\n\t\tid: pack.id,\n\t\tversion: pack.version,\n\t\t...(pack.name !== undefined && { name: pack.name }),\n\t\t...(pack.requires !== undefined && { requires: pack.requires }),\n\t\tpack,\n\t\thash: hashOf(text),\n\t\tapply(game) {\n\t\t\tfor (const kind of DATA_KINDS) {\n\t\t\t\tconst defs = pack[kind] as { id: string }[] | undefined\n\t\t\t\tif (!defs) continue\n\t\t\t\tconst collection = collectionOf(game, kind)\n\t\t\t\tfor (const def of byId(defs)) {\n\t\t\t\t\tconst own = structuredClone(def) as UnitTypeDef\n\t\t\t\t\tif (collection.has(def.id)) collection.override(def.id, () => own)\n\t\t\t\t\telse collection.add(own)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (pack.data) layData(game, pack.data)\n\t\t\tif (pack.rules) game.rules(pack.rules)\n\t\t}\n\t}\n}\n\n/** A `data.json`'s values laid over the game as the builder has it: each definition it changes put in its place, those it takes out gone */\nfunction layData(game: GameBuilder, data: GameData): void {\n\tconst before = game.current as GameModule\n\tconst after = withData(before, data)\n\tfor (const kind of DATA_KINDS) {\n\t\tconst collection = collectionOf(game, kind)\n\t\tconst was = new Map(((before[kind] ?? []) as { id: string }[]).map((def) => [def.id, def]))\n\t\tconst now = (after[kind] ?? []) as unknown as UnitTypeDef[]\n\t\tfor (const def of now) {\n\t\t\tif (!was.has(def.id)) collection.add(def)\n\t\t\telse if (was.get(def.id) !== (def as unknown)) collection.override(def.id, () => def)\n\t\t\twas.delete(def.id)\n\t\t}\n\t\tfor (const id of was.keys()) collection.remove(id)\n\t}\n\tif (after.ai !== before.ai) game.set('ai', after.ai)\n}\n\n/**\n * Whether a game was made with packs, and which: those of the mods its composition kept a hash of, by id and version\n *\n * @beta\n */\nexport const packsOf = (game: Pick<GameModule, 'mods'>): { id: string; version: string }[] =>\n\t(game.mods ?? []).filter((mod) => (mod as { hash?: string }).hash !== undefined).map(({ id, version }) => ({ id, version }))\n"],"mappings":"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"}
|