@jgengine/core 0.10.0 → 0.12.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/CHANGELOG.md +39 -2
- package/LICENSE +203 -661
- package/README.md +1 -1
- package/dist/ai/crowd.d.ts +55 -0
- package/dist/ai/crowd.js +114 -0
- package/dist/ai/flock.d.ts +5 -2
- package/dist/ai/flock.js +5 -2
- package/dist/ai/groupAssist.d.ts +1 -0
- package/dist/ai/groupAssist.js +1 -0
- package/dist/ai/heatSystem.d.ts +76 -0
- package/dist/ai/heatSystem.js +97 -0
- package/dist/ai/interestScheduler.d.ts +107 -0
- package/dist/ai/interestScheduler.js +118 -0
- package/dist/ai/jobBoard.d.ts +1 -0
- package/dist/ai/jobBoard.js +1 -0
- package/dist/ai/laneSelect.d.ts +5 -2
- package/dist/ai/laneSelect.js +5 -2
- package/dist/ai/mobBrain.d.ts +1 -0
- package/dist/ai/mobBrain.js +1 -0
- package/dist/ai/populationDirector.d.ts +103 -0
- package/dist/ai/populationDirector.js +190 -0
- package/dist/ai/pursuit.d.ts +56 -0
- package/dist/ai/pursuit.js +53 -0
- package/dist/ai/spawnDirector.d.ts +7 -2
- package/dist/ai/spawnDirector.js +18 -15
- package/dist/ai/spawnPoint.d.ts +3 -1
- package/dist/ai/spawnPoint.js +3 -1
- package/dist/ai/targetAcquisition.d.ts +84 -0
- package/dist/ai/targetAcquisition.js +92 -0
- package/dist/anim/easing.d.ts +19 -0
- package/dist/anim/easing.js +19 -0
- package/dist/anim/oscillator.d.ts +12 -0
- package/dist/anim/oscillator.js +25 -0
- package/dist/area/areaEffectField.d.ts +127 -0
- package/dist/area/areaEffectField.js +175 -0
- package/dist/area/stackPolicy.d.ts +47 -0
- package/dist/area/stackPolicy.js +99 -0
- package/dist/authoring.d.ts +2 -1
- package/dist/authoring.js +2 -1
- package/dist/board/laneBoard.d.ts +13 -0
- package/dist/board/laneBoard.js +13 -0
- package/dist/board/timelineBoard.d.ts +10 -0
- package/dist/board/timelineBoard.js +10 -0
- package/dist/combat/abilityKit.d.ts +18 -0
- package/dist/combat/abilityKit.js +24 -9
- package/dist/combat/animationState.d.ts +5 -0
- package/dist/combat/animationState.js +5 -0
- package/dist/combat/breakMeters.d.ts +10 -0
- package/dist/combat/breakMeters.js +10 -0
- package/dist/combat/castRunner.d.ts +5 -0
- package/dist/combat/castRunner.js +5 -0
- package/dist/combat/comboPoints.d.ts +5 -0
- package/dist/combat/comboPoints.js +5 -0
- package/dist/combat/comboString.d.ts +5 -0
- package/dist/combat/comboString.js +5 -0
- package/dist/combat/damageInterceptors.d.ts +192 -0
- package/dist/combat/damageInterceptors.js +251 -0
- package/dist/combat/damageMatchup.d.ts +68 -0
- package/dist/combat/damageMatchup.js +42 -0
- package/dist/combat/damageResolution.d.ts +63 -0
- package/dist/combat/damageResolution.js +50 -0
- package/dist/combat/death.d.ts +7 -1
- package/dist/combat/death.js +5 -0
- package/dist/combat/deathReason.d.ts +14 -0
- package/dist/combat/deathReason.js +1 -0
- package/dist/combat/defensiveWindow.d.ts +5 -0
- package/dist/combat/defensiveWindow.js +5 -0
- package/dist/combat/dotField.d.ts +5 -1
- package/dist/combat/dotField.js +5 -1
- package/dist/combat/downed.d.ts +5 -0
- package/dist/combat/downed.js +5 -0
- package/dist/combat/effects.d.ts +5 -0
- package/dist/combat/effects.js +5 -0
- package/dist/combat/encounterSequence.d.ts +258 -0
- package/dist/combat/encounterSequence.js +426 -0
- package/dist/combat/hitReaction.d.ts +57 -1
- package/dist/combat/hitReaction.js +45 -5
- package/dist/combat/magazine.d.ts +54 -0
- package/dist/combat/magazine.js +96 -0
- package/dist/combat/projectiles.d.ts +5 -0
- package/dist/combat/projectiles.js +32 -14
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +5 -1
- package/dist/combat/regenShield.js +5 -1
- package/dist/combat/renderCues.d.ts +51 -0
- package/dist/combat/renderCues.js +44 -0
- package/dist/combat/resourcePool.d.ts +5 -0
- package/dist/combat/resourcePool.js +5 -0
- package/dist/combat/rewardAllocation.d.ts +121 -0
- package/dist/combat/rewardAllocation.js +251 -0
- package/dist/combat/shotOrigin.d.ts +18 -1
- package/dist/combat/shotOrigin.js +39 -0
- package/dist/combat/statusApplication.d.ts +96 -0
- package/dist/combat/statusApplication.js +81 -0
- package/dist/combat/telegraph.d.ts +11 -2
- package/dist/combat/telegraph.js +11 -2
- package/dist/combat/thresholdCrossings.d.ts +85 -0
- package/dist/combat/thresholdCrossings.js +116 -0
- package/dist/combat.d.ts +35 -0
- package/dist/combat.js +35 -0
- package/dist/commands/commandRegistry.d.ts +11 -0
- package/dist/commands/commandRegistry.js +9 -2
- package/dist/crafting/crop.d.ts +18 -0
- package/dist/crafting/crop.js +18 -0
- package/dist/crafting/production.d.ts +5 -0
- package/dist/crafting/production.js +5 -0
- package/dist/devtools/controls.d.ts +38 -0
- package/dist/devtools/controls.js +181 -0
- package/dist/devtools/devtools.d.ts +5 -197
- package/dist/devtools/devtools.js +38 -774
- package/dist/devtools/discover.d.ts +32 -0
- package/dist/devtools/discover.js +240 -0
- package/dist/devtools/fallbackSeams.d.ts +50 -0
- package/dist/devtools/fallbackSeams.js +111 -0
- package/dist/devtools/frame.d.ts +15 -0
- package/dist/devtools/frame.js +247 -0
- package/dist/devtools/logs.d.ts +15 -0
- package/dist/devtools/logs.js +86 -0
- package/dist/devtools/overrides.d.ts +16 -0
- package/dist/devtools/overrides.js +66 -0
- package/dist/devtools/rewriteTunables.d.ts +17 -0
- package/dist/devtools/rewriteTunables.js +276 -0
- package/dist/devtools/saveEndpoint.d.ts +46 -0
- package/dist/devtools/saveEndpoint.js +48 -0
- package/dist/devtools/transformTunables.d.ts +3 -0
- package/dist/devtools/transformTunables.js +3 -0
- package/dist/devtools/tunableSchema.d.ts +31 -0
- package/dist/devtools/tunableSchema.js +31 -0
- package/dist/devtools/types.d.ts +212 -0
- package/dist/devtools/types.js +1 -0
- package/dist/economy/auctionBook.d.ts +122 -0
- package/dist/economy/auctionBook.js +213 -0
- package/dist/economy/currency.d.ts +12 -1
- package/dist/economy/currency.js +12 -1
- package/dist/economy/listingBook.d.ts +91 -0
- package/dist/economy/listingBook.js +144 -0
- package/dist/economy/priceHistory.d.ts +44 -0
- package/dist/economy/priceHistory.js +89 -0
- package/dist/economy/resourceLedger.d.ts +222 -0
- package/dist/economy/resourceLedger.js +353 -0
- package/dist/economy/sharedWallet.d.ts +14 -0
- package/dist/economy/sharedWallet.js +14 -0
- package/dist/economy/techTree.d.ts +12 -0
- package/dist/economy/techTree.js +12 -0
- package/dist/economy/unlockPoints.d.ts +92 -0
- package/dist/economy/unlockPoints.js +103 -0
- package/dist/economy/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commandApply.d.ts +5 -0
- package/dist/editor/commandApply.js +755 -0
- package/dist/editor/commands.d.ts +235 -7
- package/dist/editor/commands.js +82 -124
- package/dist/editor/directives.d.ts +94 -0
- package/dist/editor/directives.js +206 -0
- package/dist/editor/document.d.ts +194 -13
- package/dist/editor/document.js +1166 -19
- package/dist/editor/entityCatalog.d.ts +42 -0
- package/dist/editor/entityCatalog.js +101 -0
- package/dist/editor/environment.d.ts +74 -0
- package/dist/editor/environment.js +169 -0
- package/dist/editor/grid.d.ts +229 -0
- package/dist/editor/grid.js +366 -0
- package/dist/editor/gridAdapters.d.ts +80 -0
- package/dist/editor/gridAdapters.js +134 -0
- package/dist/editor/index.d.ts +98 -6
- package/dist/editor/index.js +13 -2
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/minimap.d.ts +31 -0
- package/dist/editor/minimap.js +73 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/streamer.d.ts +66 -0
- package/dist/editor/streamer.js +68 -0
- package/dist/editor/types.d.ts +250 -1
- package/dist/editor/world.d.ts +136 -0
- package/dist/editor/world.js +303 -0
- package/dist/faction/reputation.d.ts +5 -0
- package/dist/faction/reputation.js +5 -0
- package/dist/format/distance.d.ts +17 -0
- package/dist/format/distance.js +18 -0
- package/dist/format/duration.d.ts +27 -0
- package/dist/format/duration.js +45 -0
- package/dist/format/speed.d.ts +17 -0
- package/dist/format/speed.js +25 -0
- package/dist/game/breeding.d.ts +161 -0
- package/dist/game/breeding.js +181 -0
- package/dist/game/cameraConfig.d.ts +451 -0
- package/dist/game/cameraConfig.js +1 -0
- package/dist/game/connectedPlayers.d.ts +6 -4
- package/dist/game/connectedPlayers.js +2 -2
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +110 -5
- package/dist/game/defineGame.js +49 -4
- package/dist/game/defineSystem.d.ts +90 -0
- package/dist/game/defineSystem.js +47 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +63 -13
- package/dist/game/events.js +5 -0
- package/dist/game/feed.d.ts +33 -0
- package/dist/game/feed.js +35 -2
- package/dist/game/gamePhase.d.ts +11 -0
- package/dist/game/gamePhase.js +16 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/loadout.d.ts +5 -0
- package/dist/game/loadout.js +5 -0
- package/dist/game/lootFilter.d.ts +2 -0
- package/dist/game/lootFilter.js +2 -0
- package/dist/game/lootPipeline.d.ts +164 -0
- package/dist/game/lootPipeline.js +216 -0
- package/dist/game/lootTable.d.ts +19 -2
- package/dist/game/lootTable.js +15 -5
- package/dist/game/objectives.d.ts +43 -0
- package/dist/game/objectives.js +36 -0
- package/dist/game/paramLayers.d.ts +148 -0
- package/dist/game/paramLayers.js +185 -0
- package/dist/game/ping.d.ts +5 -0
- package/dist/game/ping.js +5 -0
- package/dist/game/playableGame.d.ts +116 -432
- package/dist/game/playableGame.js +1 -1
- package/dist/game/progression.d.ts +35 -0
- package/dist/game/progression.js +19 -0
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +30 -3
- package/dist/game/race.d.ts +141 -0
- package/dist/game/race.js +169 -0
- package/dist/game/recordBook.d.ts +3 -1
- package/dist/game/recordBook.js +4 -1
- package/dist/game/ruleSelection.d.ts +75 -0
- package/dist/game/ruleSelection.js +127 -0
- package/dist/game/runDraft.d.ts +5 -0
- package/dist/game/runDraft.js +5 -0
- package/dist/game/saveStore.d.ts +111 -0
- package/dist/game/saveStore.js +312 -0
- package/dist/game/snapshotHistory.d.ts +67 -0
- package/dist/game/snapshotHistory.js +95 -0
- package/dist/game/social.d.ts +38 -1
- package/dist/game/social.js +71 -0
- package/dist/game/spawnPoints.d.ts +5 -0
- package/dist/game/spawnPoints.js +5 -0
- package/dist/game/systemRuntime.d.ts +50 -0
- package/dist/game/systemRuntime.js +157 -0
- package/dist/game/systemSchedule.d.ts +72 -0
- package/dist/game/systemSchedule.js +242 -0
- package/dist/game/toasts.d.ts +43 -0
- package/dist/game/toasts.js +44 -0
- package/dist/game/trade.d.ts +10 -0
- package/dist/game/trade.js +10 -0
- package/dist/game/tribe.d.ts +184 -0
- package/dist/game/tribe.js +432 -0
- package/dist/game/unlocks.d.ts +8 -0
- package/dist/game/unlocks.js +16 -0
- package/dist/game/vfxInstance.d.ts +138 -0
- package/dist/game/vfxInstance.js +96 -0
- package/dist/game/worldItem.d.ts +17 -4
- package/dist/game/worldItem.js +17 -4
- package/dist/gameplay.d.ts +93 -0
- package/dist/gameplay.js +93 -0
- package/dist/index.d.ts +5 -14
- package/dist/index.js +5 -14
- package/dist/input/actionBindings.d.ts +23 -6
- package/dist/input/actionBindings.js +23 -6
- package/dist/input/axisInput.d.ts +7 -2
- package/dist/input/axisInput.js +7 -2
- package/dist/input/controlGroups.d.ts +67 -0
- package/dist/input/controlGroups.js +41 -0
- package/dist/input/touchScheme.d.ts +82 -6
- package/dist/input/touchScheme.js +123 -10
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +2 -0
- package/dist/interaction/proximityPrompt.js +2 -0
- package/dist/interaction/qte.d.ts +5 -0
- package/dist/interaction/qte.js +5 -0
- package/dist/interaction/skillCheck.d.ts +5 -0
- package/dist/interaction/skillCheck.js +5 -0
- package/dist/inventory/encumbrance.d.ts +69 -0
- package/dist/inventory/encumbrance.js +68 -0
- package/dist/inventory/inventoryModel.d.ts +12 -0
- package/dist/inventory/inventoryModel.js +12 -0
- package/dist/inventory/shapedGrid.d.ts +16 -0
- package/dist/inventory/shapedGrid.js +16 -0
- package/dist/inventory/slotModel.d.ts +10 -0
- package/dist/inventory/slotModel.js +10 -0
- package/dist/item/durability.d.ts +5 -0
- package/dist/item/durability.js +6 -3
- package/dist/item/itemIdentity.d.ts +171 -0
- package/dist/item/itemIdentity.js +138 -0
- package/dist/item/itemInstanceRegistry.d.ts +32 -0
- package/dist/item/itemInstanceRegistry.js +34 -0
- package/dist/item/itemgen.d.ts +163 -0
- package/dist/item/itemgen.js +151 -0
- package/dist/item/modularItem.d.ts +5 -0
- package/dist/item/modularItem.js +5 -0
- package/dist/item/use.d.ts +5 -0
- package/dist/item/use.js +5 -0
- package/dist/item/useBehavior.d.ts +142 -0
- package/dist/item/useBehavior.js +105 -0
- package/dist/item/weapon.d.ts +5 -0
- package/dist/item/weapon.js +5 -0
- package/dist/math/scalar.d.ts +25 -0
- package/dist/math/scalar.js +47 -0
- package/dist/meta/changelog.d.ts +4 -1
- package/dist/meta/changelog.js +39 -2
- package/dist/movement/avoidance.d.ts +45 -0
- package/dist/movement/avoidance.js +123 -0
- package/dist/movement/cameraRig.d.ts +8 -0
- package/dist/movement/cameraRig.js +8 -0
- package/dist/movement/dash.d.ts +11 -0
- package/dist/movement/dash.js +11 -0
- package/dist/movement/formation.d.ts +135 -0
- package/dist/movement/formation.js +194 -0
- package/dist/movement/glideModel.d.ts +5 -0
- package/dist/movement/glideModel.js +5 -0
- package/dist/movement/grappleSwing.d.ts +5 -0
- package/dist/movement/grappleSwing.js +5 -0
- package/dist/movement/leaderTrail.d.ts +5 -0
- package/dist/movement/leaderTrail.js +5 -0
- package/dist/movement/movementModel.d.ts +50 -9
- package/dist/movement/movementModel.js +75 -29
- package/dist/movement/playerMovement.js +167 -12
- package/dist/movement/poseState.d.ts +13 -0
- package/dist/movement/poseState.js +16 -0
- package/dist/movement/steering.d.ts +8 -0
- package/dist/movement/steering.js +18 -0
- package/dist/multiplayer/combatSnapshot.d.ts +3 -0
- package/dist/multiplayer/combatSnapshot.js +16 -8
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +11 -1
- package/dist/multiplayer/presenceModel.js +17 -1
- package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
- package/dist/multiplayer/simultaneousCommit.js +3 -0
- package/dist/multiplayer.d.ts +11 -0
- package/dist/multiplayer.js +11 -0
- package/dist/nav/pathFollow.d.ts +57 -0
- package/dist/nav/pathFollow.js +109 -0
- package/dist/orders/orderKinds.d.ts +156 -0
- package/dist/orders/orderKinds.js +197 -0
- package/dist/orders/orderQueue.d.ts +208 -0
- package/dist/orders/orderQueue.js +211 -0
- package/dist/physics/drivableVehicle.d.ts +31 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/flightDynamics.d.ts +82 -0
- package/dist/physics/flightDynamics.js +165 -0
- package/dist/physics/gravityField.d.ts +25 -0
- package/dist/physics/gravityField.js +41 -0
- package/dist/physics/kinematicVehicle.d.ts +108 -1
- package/dist/physics/kinematicVehicle.js +212 -15
- package/dist/physics/physicsWorld.d.ts +50 -12
- package/dist/physics/physicsWorld.js +120 -122
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -0
- package/dist/physics/vehicleObstacles.d.ts +44 -0
- package/dist/physics/vehicleObstacles.js +115 -0
- package/dist/procedural.d.ts +3 -0
- package/dist/procedural.js +3 -0
- package/dist/progression/statGraph.d.ts +116 -0
- package/dist/progression/statGraph.js +318 -0
- package/dist/puzzle/cellGrid.d.ts +9 -0
- package/dist/puzzle/cellGrid.js +9 -0
- package/dist/puzzle/fallingPiece.d.ts +9 -0
- package/dist/puzzle/fallingPiece.js +9 -0
- package/dist/puzzle/nonogram.d.ts +39 -0
- package/dist/puzzle/nonogram.js +136 -0
- package/dist/random/nameGen.d.ts +5 -0
- package/dist/random/nameGen.js +5 -0
- package/dist/random/pick.d.ts +8 -0
- package/dist/random/pick.js +31 -0
- package/dist/random/rng.d.ts +26 -1
- package/dist/random/rng.js +32 -9
- package/dist/random/seedLink.d.ts +4 -0
- package/dist/random/seedLink.js +4 -0
- package/dist/relation/keyedValues.d.ts +54 -0
- package/dist/relation/keyedValues.js +115 -0
- package/dist/relation/thresholds.d.ts +62 -0
- package/dist/relation/thresholds.js +62 -0
- package/dist/render/color.d.ts +12 -0
- package/dist/render/color.js +26 -0
- package/dist/render/lookPreset.d.ts +41 -0
- package/dist/render/lookPreset.js +29 -0
- package/dist/render/postProcessing.d.ts +20 -0
- package/dist/render/postProcessing.js +21 -1
- package/dist/rules/predicate.d.ts +53 -0
- package/dist/rules/predicate.js +64 -0
- package/dist/rules/ruleEffects.d.ts +38 -0
- package/dist/rules/ruleEffects.js +37 -0
- package/dist/rules/triggeredRules.d.ts +160 -0
- package/dist/rules/triggeredRules.js +241 -0
- package/dist/runtime/adapter.d.ts +55 -3
- package/dist/runtime/adapter.js +57 -1
- package/dist/runtime/cameraDirector.d.ts +1 -0
- package/dist/runtime/cameraDirector.js +1 -0
- package/dist/runtime/commandRunner.d.ts +1 -0
- package/dist/runtime/commandRunner.js +1 -0
- package/dist/runtime/context/combat.d.ts +51 -0
- package/dist/runtime/context/combat.js +130 -0
- package/dist/runtime/context/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/deathLoot.d.ts +30 -0
- package/dist/runtime/context/deathLoot.js +39 -0
- package/dist/runtime/context/player.d.ts +48 -0
- package/dist/runtime/context/player.js +125 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -0
- package/dist/runtime/context/scene.d.ts +59 -0
- package/dist/runtime/context/scene.js +291 -0
- package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
- package/dist/runtime/context/snapshotCodecs.js +26 -0
- package/dist/runtime/context/worldItems.d.ts +21 -0
- package/dist/runtime/context/worldItems.js +37 -0
- package/dist/runtime/descriptors/baseline.d.ts +48 -0
- package/dist/runtime/descriptors/baseline.js +157 -0
- package/dist/runtime/descriptors/features.d.ts +79 -0
- package/dist/runtime/descriptors/features.js +299 -0
- package/dist/runtime/gameContext.d.ts +2 -327
- package/dist/runtime/gameContext.js +273 -778
- package/dist/runtime/gameContextTypes.d.ts +467 -0
- package/dist/runtime/gameContextTypes.js +1 -0
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +62 -0
- package/dist/runtime/headlessRunner.js +45 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostPolicy.d.ts +51 -0
- package/dist/runtime/hostPolicy.js +68 -0
- package/dist/runtime/hostedGameRunner.d.ts +11 -4
- package/dist/runtime/hostedGameRunner.js +27 -3
- package/dist/runtime/hostedWorldSession.d.ts +15 -5
- package/dist/runtime/hostedWorldSession.js +12 -4
- package/dist/runtime/inputSnapshot.d.ts +8 -3
- package/dist/runtime/inputSnapshot.js +6 -2
- package/dist/runtime/motionIntents.d.ts +11 -2
- package/dist/runtime/motionIntents.js +16 -2
- package/dist/runtime/perContext.d.ts +15 -0
- package/dist/runtime/perContext.js +21 -0
- package/dist/runtime/runtimeSave.d.ts +79 -0
- package/dist/runtime/runtimeSave.js +105 -0
- package/dist/runtime/save.d.ts +4 -0
- package/dist/runtime/save.js +4 -0
- package/dist/runtime/snapshot.d.ts +7 -0
- package/dist/runtime/snapshot.js +7 -0
- package/dist/runtime/visibility.d.ts +2 -1
- package/dist/runtime/visibility.js +2 -1
- package/dist/runtime/worldChannel.d.ts +7 -3
- package/dist/runtime/worldChannel.js +51 -6
- package/dist/runtime/worldMirror.d.ts +14 -2
- package/dist/runtime/worldMirror.js +15 -2
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +30 -7
- package/dist/runtime/worldReplication.js +41 -9
- package/dist/runtime/worldSnapshot.d.ts +42 -3
- package/dist/runtime/worldSnapshot.js +34 -7
- package/dist/scene/assetCatalog.d.ts +26 -0
- package/dist/scene/assetCatalog.js +4 -0
- package/dist/scene/assetDiagnostics.d.ts +69 -0
- package/dist/scene/assetDiagnostics.js +110 -0
- package/dist/scene/assetGenerator.d.ts +65 -0
- package/dist/scene/assetGenerator.js +64 -0
- package/dist/scene/assetSpace.d.ts +137 -0
- package/dist/scene/assetSpace.js +257 -0
- package/dist/scene/authoredTriggers.d.ts +219 -0
- package/dist/scene/authoredTriggers.js +454 -0
- package/dist/scene/behaviorRuntime.d.ts +75 -0
- package/dist/scene/behaviorRuntime.js +217 -0
- package/dist/scene/behaviors.d.ts +14 -2
- package/dist/scene/behaviors.js +7 -2
- package/dist/scene/bodyBind.d.ts +60 -0
- package/dist/scene/bodyBind.js +51 -0
- package/dist/scene/builtinSceneKinds.d.ts +5 -0
- package/dist/scene/builtinSceneKinds.js +67 -0
- package/dist/scene/colliders.d.ts +71 -1
- package/dist/scene/colliders.js +145 -1
- package/dist/scene/collisionMesh.d.ts +94 -0
- package/dist/scene/collisionMesh.js +699 -0
- package/dist/scene/companion.d.ts +147 -0
- package/dist/scene/companion.js +193 -0
- package/dist/scene/entityStats.d.ts +18 -11
- package/dist/scene/entityStats.js +21 -16
- package/dist/scene/entityStore.d.ts +12 -1
- package/dist/scene/entityStore.js +15 -0
- package/dist/scene/facing.d.ts +18 -0
- package/dist/scene/facing.js +26 -0
- package/dist/scene/modelSockets.d.ts +33 -0
- package/dist/scene/modelSockets.js +29 -0
- package/dist/scene/objectQuery.d.ts +2 -0
- package/dist/scene/objectQuery.js +2 -0
- package/dist/scene/objectStore.d.ts +4 -0
- package/dist/scene/objectStore.js +6 -0
- package/dist/scene/possession.d.ts +8 -0
- package/dist/scene/possession.js +14 -0
- package/dist/scene/roster.d.ts +3 -0
- package/dist/scene/roster.js +12 -0
- package/dist/scene/sceneKinds.d.ts +256 -0
- package/dist/scene/sceneKinds.js +218 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -0
- package/dist/scene/sceneRaycast.js +15 -0
- package/dist/scene/selectionBookmarks.d.ts +93 -0
- package/dist/scene/selectionBookmarks.js +122 -0
- package/dist/scene/vehicleSeat.d.ts +68 -0
- package/dist/scene/vehicleSeat.js +59 -0
- package/dist/sensor/concealment.d.ts +3 -0
- package/dist/sensor/concealment.js +3 -0
- package/dist/sensor/freezeMonitor.d.ts +1 -0
- package/dist/sensor/freezeMonitor.js +1 -0
- package/dist/sensor/frustumSensor.d.ts +7 -3
- package/dist/sensor/frustumSensor.js +7 -3
- package/dist/sensor/hiddenStateProbe.d.ts +5 -2
- package/dist/sensor/hiddenStateProbe.js +5 -2
- package/dist/sensor/recordingBuffer.d.ts +2 -1
- package/dist/sensor/recordingBuffer.js +2 -1
- package/dist/sensor/replayLoop.d.ts +6 -2
- package/dist/sensor/replayLoop.js +6 -2
- package/dist/sensor/revealQuery.d.ts +2 -1
- package/dist/sensor/revealQuery.js +2 -1
- package/dist/sensor/visionCone.d.ts +10 -3
- package/dist/sensor/visionCone.js +10 -3
- package/dist/session/contestedChannel.d.ts +1 -0
- package/dist/session/contestedChannel.js +1 -0
- package/dist/session/extraction.d.ts +1 -0
- package/dist/session/extraction.js +1 -0
- package/dist/session/roles.d.ts +6 -0
- package/dist/session/roles.js +6 -0
- package/dist/session/roundState.d.ts +8 -0
- package/dist/session/roundState.js +2 -0
- package/dist/settings/settingsModel.d.ts +1 -0
- package/dist/settings/settingsModel.js +1 -0
- package/dist/stats/accumulatorMeter.d.ts +6 -0
- package/dist/stats/accumulatorMeter.js +6 -0
- package/dist/stats/eventMeter.d.ts +5 -0
- package/dist/stats/eventMeter.js +5 -0
- package/dist/stats/rollCheck.d.ts +5 -0
- package/dist/stats/rollCheck.js +5 -0
- package/dist/stats/spawnLevelStats.d.ts +110 -0
- package/dist/stats/spawnLevelStats.js +140 -0
- package/dist/stats/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -0
- package/dist/stats/statPool.d.ts +70 -0
- package/dist/stats/statPool.js +59 -0
- package/dist/store/changeSignal.d.ts +3 -0
- package/dist/store/changeSignal.js +2 -0
- package/dist/store/defineKeyedStore.d.ts +38 -0
- package/dist/store/defineKeyedStore.js +42 -0
- package/dist/store/defineStore.d.ts +33 -0
- package/dist/store/defineStore.js +35 -0
- package/dist/store/observableKeyedStore.d.ts +7 -0
- package/dist/store/observableKeyedStore.js +35 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -57
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +6 -3
- package/dist/tactics/fallingGrid.d.ts +4 -2
- package/dist/tactics/fallingGrid.js +4 -2
- package/dist/tactics/predictiveQuery.d.ts +3 -0
- package/dist/tactics/predictiveQuery.js +3 -0
- package/dist/tactics/snapshot.d.ts +2 -0
- package/dist/tactics/snapshot.js +2 -0
- package/dist/tactics/surface.d.ts +1 -0
- package/dist/tactics/surface.js +1 -0
- package/dist/tactics/tacticalGrid.d.ts +1 -0
- package/dist/tactics/tacticalGrid.js +1 -0
- package/dist/time/beatClock.d.ts +14 -4
- package/dist/time/beatClock.js +14 -4
- package/dist/time/calendarClock.d.ts +3 -0
- package/dist/time/calendarClock.js +3 -0
- package/dist/time/idleProgress.d.ts +4 -0
- package/dist/time/idleProgress.js +4 -0
- package/dist/time/simClock.d.ts +2 -0
- package/dist/time/simClock.js +20 -5
- package/dist/ui/actionModel.d.ts +110 -0
- package/dist/ui/actionModel.js +159 -0
- package/dist/ui/gameLayout.d.ts +30 -11
- package/dist/ui/gameLayout.js +30 -11
- package/dist/ui/hudDocument.d.ts +114 -0
- package/dist/ui/hudDocument.js +220 -0
- package/dist/ui/hudLayout.d.ts +38 -1
- package/dist/ui/hudLayout.js +220 -17
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/tooltipModel.d.ts +63 -0
- package/dist/ui/tooltipModel.js +82 -0
- package/dist/ui.d.ts +15 -0
- package/dist/ui.js +15 -0
- package/dist/visibility/bounds.d.ts +8 -1
- package/dist/visibility/bounds.js +8 -1
- package/dist/visibility/frustum.d.ts +12 -3
- package/dist/visibility/frustum.js +12 -3
- package/dist/work/jobQueue.d.ts +201 -0
- package/dist/work/jobQueue.js +253 -0
- package/dist/work/unitTraining.d.ts +58 -0
- package/dist/work/unitTraining.js +52 -0
- package/dist/world/authoredEntities.d.ts +29 -0
- package/dist/world/authoredEntities.js +29 -0
- package/dist/world/authoredObjects.d.ts +72 -0
- package/dist/world/authoredObjects.js +81 -0
- package/dist/world/authoredSpawn.d.ts +39 -0
- package/dist/world/authoredSpawn.js +37 -0
- package/dist/world/buildSockets.d.ts +152 -0
- package/dist/world/buildSockets.js +188 -0
- package/dist/world/buildingGenerator.d.ts +18 -0
- package/dist/world/buildingGenerator.js +62 -0
- package/dist/world/buildings.d.ts +5 -0
- package/dist/world/buildings.js +5 -0
- package/dist/world/catenary.d.ts +22 -0
- package/dist/world/catenary.js +69 -0
- package/dist/world/cityBlocks.d.ts +152 -0
- package/dist/world/cityBlocks.js +670 -0
- package/dist/world/cityContent.d.ts +77 -0
- package/dist/world/cityContent.js +261 -0
- package/dist/world/cityGeometry.d.ts +114 -0
- package/dist/world/cityGeometry.js +573 -0
- package/dist/world/cityKind.d.ts +314 -0
- package/dist/world/cityKind.js +1578 -0
- package/dist/world/features.d.ts +133 -10
- package/dist/world/features.js +66 -6
- package/dist/world/footprintGrid.d.ts +59 -0
- package/dist/world/footprintGrid.js +141 -0
- package/dist/world/geometry.d.ts +64 -0
- package/dist/world/geometry.js +94 -0
- package/dist/world/grassKind.d.ts +51 -0
- package/dist/world/grassKind.js +101 -0
- package/dist/world/markers.d.ts +50 -4
- package/dist/world/markers.js +49 -0
- package/dist/world/massing.js +1 -1
- package/dist/world/minimapBake.d.ts +78 -0
- package/dist/world/minimapBake.js +208 -0
- package/dist/world/minimapTrack.d.ts +17 -0
- package/dist/world/minimapTrack.js +22 -0
- package/dist/world/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathNetwork.d.ts +159 -0
- package/dist/world/pathNetwork.js +684 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/place.d.ts +166 -0
- package/dist/world/place.js +96 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +79 -0
- package/dist/world/placement.d.ts +4 -0
- package/dist/world/placement.js +4 -0
- package/dist/world/placementController.d.ts +6 -0
- package/dist/world/placementController.js +6 -0
- package/dist/world/poleLineKind.d.ts +40 -0
- package/dist/world/poleLineKind.js +97 -0
- package/dist/world/polyline.d.ts +34 -0
- package/dist/world/polyline.js +88 -0
- package/dist/world/resourceNode.d.ts +109 -0
- package/dist/world/resourceNode.js +140 -0
- package/dist/world/roads.d.ts +8 -0
- package/dist/world/roads.js +38 -0
- package/dist/world/scatter.js +2 -20
- package/dist/world/scatterRegion.d.ts +164 -0
- package/dist/world/scatterRegion.js +409 -0
- package/dist/world/sceneShapes.d.ts +43 -0
- package/dist/world/sceneShapes.js +1 -0
- package/dist/world/segment.d.ts +27 -0
- package/dist/world/segment.js +43 -0
- package/dist/world/soilKind.d.ts +48 -0
- package/dist/world/soilKind.js +92 -0
- package/dist/world/spatialSample.d.ts +241 -0
- package/dist/world/spatialSample.js +465 -0
- package/dist/world/streets.d.ts +29 -0
- package/dist/world/streets.js +55 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +627 -22
- package/dist/world/terrain.d.ts +164 -20
- package/dist/world/terrain.js +325 -41
- package/dist/world/terrainGuides.d.ts +182 -0
- package/dist/world/terrainGuides.js +343 -0
- package/dist/world/vec2.d.ts +81 -0
- package/dist/world/vec2.js +128 -0
- package/dist/world/vec3.d.ts +49 -0
- package/dist/world/vec3.js +76 -0
- package/dist/world/vegetation.d.ts +71 -0
- package/dist/world/vegetation.js +151 -0
- package/dist/world/visibilityField.d.ts +154 -0
- package/dist/world/visibilityField.js +271 -0
- package/dist/world/volumetricClouds.d.ts +52 -0
- package/dist/world/volumetricClouds.js +43 -0
- package/dist/world/walls.d.ts +9 -0
- package/dist/world/walls.js +9 -0
- package/dist/world/waterKind.d.ts +55 -0
- package/dist/world/waterKind.js +99 -0
- package/dist/world.d.ts +141 -0
- package/dist/world.js +141 -0
- package/package.json +32 -8
- package/skills/game-design/SKILL.md +28 -0
- package/skills/game-design/agents/openai.yaml +4 -0
- package/skills/game-design/references/application-playbook.md +170 -0
- package/skills/game-design/references/field-guide.md +288 -0
- package/skills/jgengine/SKILL.md +54 -0
- package/skills/jgengine/api.md +527 -0
- package/skills/jgengine/capabilities.md +131 -0
- package/skills/jgengine/recipes/minimal-game.md +88 -0
- package/skills/jgengine-combat/SKILL.md +38 -0
- package/skills/jgengine-combat/api.md +585 -0
- package/skills/jgengine-combat/capabilities.md +213 -0
- package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
- package/skills/jgengine-combat/reference.md +108 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1920 -0
- package/skills/jgengine-gameplay/capabilities.md +454 -0
- package/skills/jgengine-gameplay/reference-systems.md +56 -0
- package/skills/jgengine-world/SKILL.md +51 -0
- package/skills/jgengine-world/api.md +3056 -0
- package/skills/jgengine-world/capabilities.md +476 -0
- package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
- package/skills/jgengine-world/reference.md +261 -0
- package/dist/cartridge/runtime.d.ts +0 -15
- package/dist/cartridge/runtime.js +0 -556
- package/dist/cartridge/spec.d.ts +0 -188
- package/dist/cartridge/spec.js +0 -19
- package/dist/cartridge/validate.d.ts +0 -2
- package/dist/cartridge/validate.js +0 -78
- package/dist/store/engineStore.d.ts +0 -22
- package/dist/store/engineStore.js +0 -50
- package/dist/store/features.d.ts +0 -10
- package/dist/store/features.js +0 -23
- package/llms.txt +0 -5389
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { formatDistance } from "./format/distance.js";
|
|
2
|
+
export { formatDelta, formatDuration, formatOrdinal } from "./format/duration.js";
|
|
3
|
+
export { formatSpeed } from "./format/speed.js";
|
|
4
|
+
export { resolveGameLook, type LookPreset } from "./render/lookPreset.js";
|
|
5
|
+
export { STUDIO_STAGE_POST, type GradeConfig, type PostProcessingConfig, type ToneMappingMode, } from "./render/postProcessing.js";
|
|
6
|
+
export { BUILT_IN_SETTING_CATEGORIES, DEFAULT_GRAPHICS_QUALITY, DEFAULT_GRAPHICS_SHADOWS, DEFAULT_MASTER_VOLUME, DEFAULT_UI_SCALE, GRAPHICS_QUALITY_DPR, GRAPHICS_QUALITY_OPTIONS, SETTING_IDS, UI_SCALE_MAX, UI_SCALE_MIN, busVolumeSettingId, createSettingsStore, type GameSettingDef, type GameSettingsConfig, type GraphicsQuality, type SettingCategory, type SettingCategoryDef, type SettingKind, type SettingOption, type SettingValue, type SettingsActionDef, type SettingsStore, type SettingsSurface, type SettingsVariant, } from "./settings/settingsModel.js";
|
|
7
|
+
export { actionByHotkey, actionCooldown, actionCooldownFromFraction, actionCost, moveGridFocus, resolveAction, resolveActionCollection, type ActionCooldown, type ActionCost, type ActionDef, type ActionReason, type FocusDirection, type GridFocusOptions, type ResolvedAction, } from "./ui/actionModel.js";
|
|
8
|
+
export { type GameLayoutMode, type GameViewportLayout, type HudPriority, type Insets, type LayoutCollision, type LayoutCollisionPolicy, type LayoutRect, type LayoutRegion, type MobileHudBehavior, } from "./ui/gameLayout.js";
|
|
9
|
+
export { listHudPanelTypes, registerHudPanelType, resizePanelSize, resolveHudPanelLayout, type EditorUiDocument, type EditorUiPanelLayout, type HudResizeAxes, } from "./ui/hudDocument.js";
|
|
10
|
+
export { HUD_ANCHOR_FRACTIONS, type HudAnchor, type HudLayoutStore, type HudPlacement, type HudSize, } from "./ui/hudLayout.js";
|
|
11
|
+
export { hudScaleForViewport, overflowingPanels, resolveHudFit, type HudPlatform, type HudViewportConfig, } from "./ui/hudScale.js";
|
|
12
|
+
export { orientationGateActive, orientationHintActive, resolveOrientationRequirement, type LayoutOrientation, } from "./ui/orientation.js";
|
|
13
|
+
export { moveSelectionFocus, selectionWindow, summarizeSelection, type EntitySummaryDef, type EntityVital, type SelectionFocusDirection, type SelectionGroup, type SelectionView, type SelectionWindow, type SummarizeSelectionOptions, } from "./ui/selectionModel.js";
|
|
14
|
+
export { swingTimerState, type SwingTargetInput } from "./ui/swingTimer.js";
|
|
15
|
+
export { actionTooltip, placePopover, type PopoverOptions, type PopoverPlacement, type PopoverSide, type TooltipContent, type UiRect, type UiSize, } from "./ui/tooltipModel.js";
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { formatDistance } from "./format/distance.js";
|
|
2
|
+
export { formatDelta, formatDuration, formatOrdinal } from "./format/duration.js";
|
|
3
|
+
export { formatSpeed } from "./format/speed.js";
|
|
4
|
+
export { resolveGameLook } from "./render/lookPreset.js";
|
|
5
|
+
export { STUDIO_STAGE_POST, } from "./render/postProcessing.js";
|
|
6
|
+
export { BUILT_IN_SETTING_CATEGORIES, DEFAULT_GRAPHICS_QUALITY, DEFAULT_GRAPHICS_SHADOWS, DEFAULT_MASTER_VOLUME, DEFAULT_UI_SCALE, GRAPHICS_QUALITY_DPR, GRAPHICS_QUALITY_OPTIONS, SETTING_IDS, UI_SCALE_MAX, UI_SCALE_MIN, busVolumeSettingId, createSettingsStore, } from "./settings/settingsModel.js";
|
|
7
|
+
export { actionByHotkey, actionCooldown, actionCooldownFromFraction, actionCost, moveGridFocus, resolveAction, resolveActionCollection, } from "./ui/actionModel.js";
|
|
8
|
+
export {} from "./ui/gameLayout.js";
|
|
9
|
+
export { listHudPanelTypes, registerHudPanelType, resizePanelSize, resolveHudPanelLayout, } from "./ui/hudDocument.js";
|
|
10
|
+
export { HUD_ANCHOR_FRACTIONS, } from "./ui/hudLayout.js";
|
|
11
|
+
export { hudScaleForViewport, overflowingPanels, resolveHudFit, } from "./ui/hudScale.js";
|
|
12
|
+
export { orientationGateActive, orientationHintActive, resolveOrientationRequirement, } from "./ui/orientation.js";
|
|
13
|
+
export { moveSelectionFocus, selectionWindow, summarizeSelection, } from "./ui/selectionModel.js";
|
|
14
|
+
export { swingTimerState } from "./ui/swingTimer.js";
|
|
15
|
+
export { actionTooltip, placePopover, } from "./ui/tooltipModel.js";
|
|
@@ -42,11 +42,17 @@ export type BoundsSpec = {
|
|
|
42
42
|
};
|
|
43
43
|
/** Conservative default: a unit sphere. Objects without explicit bounds cull as a small volume, never a point. */
|
|
44
44
|
export declare const DEFAULT_BOUNDS: BoundsSpec;
|
|
45
|
+
/** @internal */
|
|
45
46
|
export declare function createRenderBounds(): RenderBounds;
|
|
46
|
-
/** Resolve a spec + world position into concrete bounds. Writes into `out` when supplied (no allocation).
|
|
47
|
+
/** Resolve a spec + world position into concrete bounds. Writes into `out` when supplied (no allocation).
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
47
50
|
export declare function resolveBounds(spec: BoundsSpec, position: Vec3, out?: RenderBounds): RenderBounds;
|
|
51
|
+
/** @internal */
|
|
48
52
|
export declare function expandRenderBounds(bounds: RenderBounds, margin: number, out?: RenderBounds): RenderBounds;
|
|
53
|
+
/** @internal */
|
|
49
54
|
export declare function aabbIntersects(aMinX: number, aMinY: number, aMinZ: number, aMaxX: number, aMaxY: number, aMaxZ: number, bMinX: number, bMinY: number, bMinZ: number, bMaxX: number, bMaxY: number, bMaxZ: number): boolean;
|
|
55
|
+
/** @internal */
|
|
50
56
|
export declare function boundsIntersect(a: RenderBounds, b: RenderBounds): boolean;
|
|
51
57
|
/**
|
|
52
58
|
* BoundsSystem: caches resolved bounds per object and recomputes only when the caller's
|
|
@@ -63,4 +69,5 @@ export interface BoundsCache {
|
|
|
63
69
|
size(): number;
|
|
64
70
|
recomputes(): number;
|
|
65
71
|
}
|
|
72
|
+
/** @internal */
|
|
66
73
|
export declare function createBoundsCache(): BoundsCache;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Conservative default: a unit sphere. Objects without explicit bounds cull as a small volume, never a point. */
|
|
2
2
|
export const DEFAULT_BOUNDS = { kind: "sphere", radius: 1 };
|
|
3
|
+
/** @internal */
|
|
3
4
|
export function createRenderBounds() {
|
|
4
5
|
return {
|
|
5
6
|
centerX: 0,
|
|
@@ -27,7 +28,9 @@ function fillBounds(out, cx, cy, cz, hx, hy, hz) {
|
|
|
27
28
|
out.radius = Math.sqrt(hx * hx + hy * hy + hz * hz);
|
|
28
29
|
return out;
|
|
29
30
|
}
|
|
30
|
-
/** Resolve a spec + world position into concrete bounds. Writes into `out` when supplied (no allocation).
|
|
31
|
+
/** Resolve a spec + world position into concrete bounds. Writes into `out` when supplied (no allocation).
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
31
34
|
export function resolveBounds(spec, position, out = createRenderBounds()) {
|
|
32
35
|
if (spec.kind === "point") {
|
|
33
36
|
return fillBounds(out, position[0], position[1], position[2], 0, 0, 0);
|
|
@@ -49,6 +52,7 @@ export function resolveBounds(spec, position, out = createRenderBounds()) {
|
|
|
49
52
|
return fillBounds(out, cx, cy, cz, spec.halfWidth, spec.halfHeight ?? 0, spec.halfDepth);
|
|
50
53
|
}
|
|
51
54
|
}
|
|
55
|
+
/** @internal */
|
|
52
56
|
export function expandRenderBounds(bounds, margin, out = createRenderBounds()) {
|
|
53
57
|
out.centerX = bounds.centerX;
|
|
54
58
|
out.centerY = bounds.centerY;
|
|
@@ -62,14 +66,17 @@ export function expandRenderBounds(bounds, margin, out = createRenderBounds()) {
|
|
|
62
66
|
out.maxZ = bounds.maxZ + margin;
|
|
63
67
|
return out;
|
|
64
68
|
}
|
|
69
|
+
/** @internal */
|
|
65
70
|
export function aabbIntersects(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ, bMinX, bMinY, bMinZ, bMaxX, bMaxY, bMaxZ) {
|
|
66
71
|
return (aMinX <= bMaxX && aMaxX >= bMinX &&
|
|
67
72
|
aMinY <= bMaxY && aMaxY >= bMinY &&
|
|
68
73
|
aMinZ <= bMaxZ && aMaxZ >= bMinZ);
|
|
69
74
|
}
|
|
75
|
+
/** @internal */
|
|
70
76
|
export function boundsIntersect(a, b) {
|
|
71
77
|
return aabbIntersects(a.minX, a.minY, a.minZ, a.maxX, a.maxY, a.maxZ, b.minX, b.minY, b.minZ, b.maxX, b.maxY, b.maxZ);
|
|
72
78
|
}
|
|
79
|
+
/** @internal */
|
|
73
80
|
export function createBoundsCache() {
|
|
74
81
|
const entries = new Map();
|
|
75
82
|
let recomputes = 0;
|
|
@@ -36,12 +36,21 @@ export interface Frustum {
|
|
|
36
36
|
maxY: number;
|
|
37
37
|
maxZ: number;
|
|
38
38
|
}
|
|
39
|
+
/** @internal */
|
|
39
40
|
export declare function createFrustum(): Frustum;
|
|
41
|
+
/** @internal */
|
|
40
42
|
export declare function updateFrustum(out: Frustum, view: CameraView): Frustum;
|
|
41
|
-
/** Conservative AABB-vs-frustum: never a false negative (may keep a corner-case that is truly outside).
|
|
43
|
+
/** Conservative AABB-vs-frustum: never a false negative (may keep a corner-case that is truly outside).
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
42
46
|
export declare function aabbInFrustum(f: Frustum, minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number): boolean;
|
|
47
|
+
/** @internal */
|
|
43
48
|
export declare function sphereInFrustum(f: Frustum, cx: number, cy: number, cz: number, radius: number): boolean;
|
|
44
|
-
/** Sphere broad-phase reject, then the tight AABB test. Both conservative.
|
|
49
|
+
/** Sphere broad-phase reject, then the tight AABB test. Both conservative.
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
45
52
|
export declare function boundsInFrustum(f: Frustum, b: RenderBounds): boolean;
|
|
46
|
-
/** Push every plane outward by `margin` (unit normals ⇒ d += margin) to form a preload/hysteresis region.
|
|
53
|
+
/** Push every plane outward by `margin` (unit normals ⇒ d += margin) to form a preload/hysteresis region.
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
47
56
|
export declare function dilateFrustum(src: Frustum, margin: number, out: Frustum): Frustum;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const WORLD_UP = [0, 1, 0];
|
|
2
2
|
const ALT_UP = [1, 0, 0];
|
|
3
|
+
/** @internal */
|
|
3
4
|
export function createFrustum() {
|
|
4
5
|
return {
|
|
5
6
|
planes: new Float64Array(24),
|
|
@@ -43,6 +44,7 @@ function planeFromCorners(planes, slot, corners, a, b, c, centroidX, centroidY,
|
|
|
43
44
|
planes[slot * 4 + 2] = nz;
|
|
44
45
|
planes[slot * 4 + 3] = d;
|
|
45
46
|
}
|
|
47
|
+
/** @internal */
|
|
46
48
|
export function updateFrustum(out, view) {
|
|
47
49
|
const { position, target } = view;
|
|
48
50
|
let fx = target[0] - position[0];
|
|
@@ -137,7 +139,9 @@ export function updateFrustum(out, view) {
|
|
|
137
139
|
planeFromCorners(planes, 5, corners, 2, 3, 6, cX, cY, cZ); // bottom
|
|
138
140
|
return out;
|
|
139
141
|
}
|
|
140
|
-
/** Conservative AABB-vs-frustum: never a false negative (may keep a corner-case that is truly outside).
|
|
142
|
+
/** Conservative AABB-vs-frustum: never a false negative (may keep a corner-case that is truly outside).
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
141
145
|
export function aabbInFrustum(f, minX, minY, minZ, maxX, maxY, maxZ) {
|
|
142
146
|
const planes = f.planes;
|
|
143
147
|
for (let i = 0; i < 6; i += 1) {
|
|
@@ -150,6 +154,7 @@ export function aabbInFrustum(f, minX, minY, minZ, maxX, maxY, maxZ) {
|
|
|
150
154
|
}
|
|
151
155
|
return true;
|
|
152
156
|
}
|
|
157
|
+
/** @internal */
|
|
153
158
|
export function sphereInFrustum(f, cx, cy, cz, radius) {
|
|
154
159
|
const planes = f.planes;
|
|
155
160
|
for (let i = 0; i < 6; i += 1) {
|
|
@@ -159,13 +164,17 @@ export function sphereInFrustum(f, cx, cy, cz, radius) {
|
|
|
159
164
|
}
|
|
160
165
|
return true;
|
|
161
166
|
}
|
|
162
|
-
/** Sphere broad-phase reject, then the tight AABB test. Both conservative.
|
|
167
|
+
/** Sphere broad-phase reject, then the tight AABB test. Both conservative.
|
|
168
|
+
* @internal
|
|
169
|
+
*/
|
|
163
170
|
export function boundsInFrustum(f, b) {
|
|
164
171
|
if (!sphereInFrustum(f, b.centerX, b.centerY, b.centerZ, b.radius))
|
|
165
172
|
return false;
|
|
166
173
|
return aabbInFrustum(f, b.minX, b.minY, b.minZ, b.maxX, b.maxY, b.maxZ);
|
|
167
174
|
}
|
|
168
|
-
/** Push every plane outward by `margin` (unit normals ⇒ d += margin) to form a preload/hysteresis region.
|
|
175
|
+
/** Push every plane outward by `margin` (unit normals ⇒ d += margin) to form a preload/hysteresis region.
|
|
176
|
+
* @internal
|
|
177
|
+
*/
|
|
169
178
|
export function dilateFrustum(src, margin, out) {
|
|
170
179
|
const sp = src.planes;
|
|
171
180
|
const op = out.planes;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic timed work queue — a pure-data model for discrete jobs that reserve
|
|
3
|
+
* inputs, advance over game time, can be paused/cancelled, and emit an output on
|
|
4
|
+
* completion. It backs unit training, crafting jobs, construction, research,
|
|
5
|
+
* respawns, downloads, and fabrication without any of them re-implementing the
|
|
6
|
+
* reservation → progress → completion → output-routing loop.
|
|
7
|
+
*
|
|
8
|
+
* The state ({@link WorkQueueState}) is plain serializable data; all policy —
|
|
9
|
+
* duration, ordering, capacity, concurrency, input reservation, refund, and
|
|
10
|
+
* output mapping — lives in {@link WorkQueueConfig}, which is supplied by the
|
|
11
|
+
* caller and is never serialized. Side effects (charging a wallet, spawning an
|
|
12
|
+
* entity) are the caller's: reservations and refunds are returned as data, and
|
|
13
|
+
* completion emits a typed event carrying a pure output payload for an external
|
|
14
|
+
* completion adapter to route.
|
|
15
|
+
*/
|
|
16
|
+
export type JobId = string;
|
|
17
|
+
/** Lifecycle phase of a single queued job. Terminal jobs are removed from state. */
|
|
18
|
+
export type JobStatus = "queued" | "active" | "paused";
|
|
19
|
+
/** One unit of timed work. Plain serializable data (given serializable `TSpec`/`TReserve`). */
|
|
20
|
+
export interface Job<TSpec, TReserve = undefined> {
|
|
21
|
+
/** Stable id, unique within the queue for its lifetime. */
|
|
22
|
+
readonly id: JobId;
|
|
23
|
+
/** Caller-owned description of the work (e.g. `{ unitId }`). */
|
|
24
|
+
readonly spec: TSpec;
|
|
25
|
+
/** Reserved inputs computed at enqueue time (e.g. resource cost, population). */
|
|
26
|
+
readonly reservation: TReserve;
|
|
27
|
+
readonly status: JobStatus;
|
|
28
|
+
/** Seconds of work the job requires. */
|
|
29
|
+
readonly duration: number;
|
|
30
|
+
/** Seconds of work completed so far (0…duration). */
|
|
31
|
+
readonly elapsed: number;
|
|
32
|
+
/** Higher runs sooner under priority ordering; FIFO within equal priority. */
|
|
33
|
+
readonly priority: number;
|
|
34
|
+
/** Monotonic enqueue index — the FIFO tiebreak. */
|
|
35
|
+
readonly seq: number;
|
|
36
|
+
}
|
|
37
|
+
/** Serializable queue state. Holds only non-terminal jobs, so it stays bounded. */
|
|
38
|
+
export interface WorkQueueState<TSpec, TReserve = undefined> {
|
|
39
|
+
readonly jobs: readonly Job<TSpec, TReserve>[];
|
|
40
|
+
readonly nextId: number;
|
|
41
|
+
readonly seq: number;
|
|
42
|
+
}
|
|
43
|
+
/** Comparator over jobs; negative means the first job runs sooner. */
|
|
44
|
+
export type JobOrdering<TSpec, TReserve = undefined> = (a: Job<TSpec, TReserve>, b: Job<TSpec, TReserve>) => number;
|
|
45
|
+
/** Result of pre-enqueue validation (population caps, prerequisites, affordability). */
|
|
46
|
+
export interface JobValidation {
|
|
47
|
+
readonly ok: boolean;
|
|
48
|
+
readonly reason?: string;
|
|
49
|
+
}
|
|
50
|
+
/** Optional per-enqueue overrides. */
|
|
51
|
+
export interface EnqueueOptions {
|
|
52
|
+
/** Higher runs sooner under priority ordering. Defaults to 0. */
|
|
53
|
+
readonly priority?: number;
|
|
54
|
+
/** Explicit id; defaults to a queue-assigned `job-<n>`. */
|
|
55
|
+
readonly id?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Injected policy for a queue. Never serialized — pass the same config to every
|
|
59
|
+
* {@link enqueue}/{@link tick}/{@link cancelJob} call for a given queue.
|
|
60
|
+
*/
|
|
61
|
+
export interface WorkQueueConfig<TSpec, TReserve = undefined, TOutput = undefined> {
|
|
62
|
+
/** Seconds of work a spec requires. Negative values clamp to 0 (instant). */
|
|
63
|
+
duration: (spec: TSpec) => number;
|
|
64
|
+
/** Max concurrent active jobs (multi-server queue). Defaults to 1. */
|
|
65
|
+
concurrency?: number;
|
|
66
|
+
/** Max non-terminal jobs; further enqueues are rejected with `"capacity"`. */
|
|
67
|
+
capacity?: number;
|
|
68
|
+
/** Selection order for queued jobs. Defaults to {@link priorityOrdering}. */
|
|
69
|
+
ordering?: JobOrdering<TSpec, TReserve>;
|
|
70
|
+
/** Compute the reservation stored on the job (charge-now is the caller's job). */
|
|
71
|
+
reserve?: (spec: TSpec) => TReserve;
|
|
72
|
+
/** Validate before enqueue; a non-ok result rejects with its reason. */
|
|
73
|
+
validate?: (spec: TSpec, state: WorkQueueState<TSpec, TReserve>) => JobValidation;
|
|
74
|
+
/** Map a completed job to its output payload for a completion adapter to route. */
|
|
75
|
+
output?: (job: Job<TSpec, TReserve>) => TOutput;
|
|
76
|
+
/** Compute a refund on cancellation from the reservation and progress (0…1). */
|
|
77
|
+
refund?: (job: Job<TSpec, TReserve>, progress: number) => TReserve | null;
|
|
78
|
+
}
|
|
79
|
+
/** Typed lifecycle event emitted from {@link tick}. */
|
|
80
|
+
export type WorkQueueEvent<TSpec, TReserve = undefined, TOutput = undefined> = {
|
|
81
|
+
readonly type: "started";
|
|
82
|
+
readonly job: Job<TSpec, TReserve>;
|
|
83
|
+
} | {
|
|
84
|
+
readonly type: "completed";
|
|
85
|
+
readonly job: Job<TSpec, TReserve>;
|
|
86
|
+
readonly output: TOutput;
|
|
87
|
+
};
|
|
88
|
+
/** Outcome of {@link tick}: advanced state plus the events produced. */
|
|
89
|
+
export interface TickResult<TSpec, TReserve = undefined, TOutput = undefined> {
|
|
90
|
+
readonly state: WorkQueueState<TSpec, TReserve>;
|
|
91
|
+
readonly events: readonly WorkQueueEvent<TSpec, TReserve, TOutput>[];
|
|
92
|
+
}
|
|
93
|
+
/** Outcome of {@link enqueue}. On rejection the state is returned unchanged. */
|
|
94
|
+
export type EnqueueResult<TSpec, TReserve = undefined> = {
|
|
95
|
+
readonly ok: true;
|
|
96
|
+
readonly state: WorkQueueState<TSpec, TReserve>;
|
|
97
|
+
readonly job: Job<TSpec, TReserve>;
|
|
98
|
+
} | {
|
|
99
|
+
readonly ok: false;
|
|
100
|
+
readonly state: WorkQueueState<TSpec, TReserve>;
|
|
101
|
+
readonly reason: string;
|
|
102
|
+
};
|
|
103
|
+
/** Outcome of {@link cancelJob}, carrying the removed job and its computed refund. */
|
|
104
|
+
export type CancelResult<TSpec, TReserve = undefined> = {
|
|
105
|
+
readonly ok: true;
|
|
106
|
+
readonly state: WorkQueueState<TSpec, TReserve>;
|
|
107
|
+
readonly job: Job<TSpec, TReserve>;
|
|
108
|
+
readonly refund: TReserve | null;
|
|
109
|
+
} | {
|
|
110
|
+
readonly ok: false;
|
|
111
|
+
readonly state: WorkQueueState<TSpec, TReserve>;
|
|
112
|
+
readonly reason: string;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Pure FIFO ordering by enqueue sequence.
|
|
116
|
+
*
|
|
117
|
+
* @capability work-order-fifo order queued jobs by enqueue sequence
|
|
118
|
+
*/
|
|
119
|
+
export declare function fifoOrdering<TSpec, TReserve = undefined>(a: Job<TSpec, TReserve>, b: Job<TSpec, TReserve>): number;
|
|
120
|
+
/**
|
|
121
|
+
* Priority-first ordering (higher priority sooner), FIFO within equal priority.
|
|
122
|
+
*
|
|
123
|
+
* @capability work-order-priority order queued jobs by priority, then FIFO within equal priority
|
|
124
|
+
*/
|
|
125
|
+
export declare function priorityOrdering<TSpec, TReserve = undefined>(a: Job<TSpec, TReserve>, b: Job<TSpec, TReserve>): number;
|
|
126
|
+
/**
|
|
127
|
+
* Create an empty timed work queue.
|
|
128
|
+
*
|
|
129
|
+
* @capability work-queue a serializable timed job queue with reservation, cancellation, completion, and output routing
|
|
130
|
+
*/
|
|
131
|
+
export declare function createWorkQueue<TSpec, TReserve = undefined>(): WorkQueueState<TSpec, TReserve>;
|
|
132
|
+
/**
|
|
133
|
+
* Non-terminal job count (queued + active + paused).
|
|
134
|
+
*
|
|
135
|
+
* @capability work-queue-size count non-terminal jobs in a work queue
|
|
136
|
+
*/
|
|
137
|
+
export declare function queueSize<TSpec, TReserve>(state: WorkQueueState<TSpec, TReserve>): number;
|
|
138
|
+
/**
|
|
139
|
+
* Look up a job by id, or `null` if absent/terminal.
|
|
140
|
+
*
|
|
141
|
+
* @capability work-job-by-id look up a queued job by id
|
|
142
|
+
*/
|
|
143
|
+
export declare function jobById<TSpec, TReserve>(state: WorkQueueState<TSpec, TReserve>, id: JobId): Job<TSpec, TReserve> | null;
|
|
144
|
+
/**
|
|
145
|
+
* Jobs waiting for a slot, in selection order.
|
|
146
|
+
*
|
|
147
|
+
* @capability work-queued-jobs list jobs waiting for a slot, in selection order
|
|
148
|
+
*/
|
|
149
|
+
export declare function queuedJobs<TSpec, TReserve>(state: WorkQueueState<TSpec, TReserve>, ordering?: JobOrdering<TSpec, TReserve>): Job<TSpec, TReserve>[];
|
|
150
|
+
/**
|
|
151
|
+
* Jobs currently progressing.
|
|
152
|
+
*
|
|
153
|
+
* @capability work-active-jobs list jobs currently progressing in a work queue
|
|
154
|
+
*/
|
|
155
|
+
export declare function activeJobs<TSpec, TReserve>(state: WorkQueueState<TSpec, TReserve>): Job<TSpec, TReserve>[];
|
|
156
|
+
/**
|
|
157
|
+
* Fractional progress of a job (0…1); a zero-duration job reads as complete.
|
|
158
|
+
*
|
|
159
|
+
* @capability work-job-progress compute a job's fractional progress
|
|
160
|
+
*/
|
|
161
|
+
export declare function jobProgress<TSpec, TReserve>(job: Job<TSpec, TReserve>): number;
|
|
162
|
+
/**
|
|
163
|
+
* Enqueue a new job. Validates capacity and the injected `validate` policy, then
|
|
164
|
+
* computes and stores the reservation. Charging the reservation (now or later) is
|
|
165
|
+
* the caller's responsibility using {@link EnqueueResult.job}'s `reservation`.
|
|
166
|
+
*
|
|
167
|
+
* @capability enqueue-work reserve inputs and add a timed job, honoring capacity and validation policy
|
|
168
|
+
*/
|
|
169
|
+
export declare function enqueue<TSpec, TReserve, TOutput>(state: WorkQueueState<TSpec, TReserve>, config: WorkQueueConfig<TSpec, TReserve, TOutput>, spec: TSpec, options?: EnqueueOptions): EnqueueResult<TSpec, TReserve>;
|
|
170
|
+
/**
|
|
171
|
+
* Cancel a job and compute its refund. Removes the job from the queue and returns
|
|
172
|
+
* a refund payload (full reservation by default, or `config.refund` applied to the
|
|
173
|
+
* job's progress for partial/no refund). Applying the refund is the caller's job.
|
|
174
|
+
*
|
|
175
|
+
* @capability cancel-work remove a job and compute its refund from reservation and progress
|
|
176
|
+
*/
|
|
177
|
+
export declare function cancelJob<TSpec, TReserve, TOutput>(state: WorkQueueState<TSpec, TReserve>, config: WorkQueueConfig<TSpec, TReserve, TOutput>, id: JobId): CancelResult<TSpec, TReserve>;
|
|
178
|
+
/**
|
|
179
|
+
* Pause a queued or active job in place; a paused job keeps its progress and yields its slot.
|
|
180
|
+
*
|
|
181
|
+
* @capability pause-work pause a queued or active job in place, retaining its progress
|
|
182
|
+
*/
|
|
183
|
+
export declare function pauseJob<TSpec, TReserve>(state: WorkQueueState<TSpec, TReserve>, id: JobId): WorkQueueState<TSpec, TReserve>;
|
|
184
|
+
/**
|
|
185
|
+
* Resume a paused job; it re-enters the queue and competes for a slot by ordering.
|
|
186
|
+
*
|
|
187
|
+
* @capability resume-work resume a paused job back into the queue's slot competition
|
|
188
|
+
*/
|
|
189
|
+
export declare function resumeJob<TSpec, TReserve>(state: WorkQueueState<TSpec, TReserve>, id: JobId): WorkQueueState<TSpec, TReserve>;
|
|
190
|
+
/**
|
|
191
|
+
* Advance the queue by `dt` seconds. Promotes queued jobs into up to `concurrency`
|
|
192
|
+
* active slots, advances active jobs, and completes those that reach their
|
|
193
|
+
* duration — emitting `started`/`completed` events in deterministic order. A large
|
|
194
|
+
* `dt` catches up across many jobs in one call: when a job completes with leftover
|
|
195
|
+
* time, the freed slot promotes the next queued job and applies the remainder, so a
|
|
196
|
+
* reconnect or save/load gap resolves in a single bounded pass. Completed jobs are
|
|
197
|
+
* removed from the returned state.
|
|
198
|
+
*
|
|
199
|
+
* @capability tick-work advance jobs over time, completing work and emitting typed lifecycle events
|
|
200
|
+
*/
|
|
201
|
+
export declare function tick<TSpec, TReserve, TOutput>(state: WorkQueueState<TSpec, TReserve>, config: WorkQueueConfig<TSpec, TReserve, TOutput>, dt: number): TickResult<TSpec, TReserve, TOutput>;
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic timed work queue — a pure-data model for discrete jobs that reserve
|
|
3
|
+
* inputs, advance over game time, can be paused/cancelled, and emit an output on
|
|
4
|
+
* completion. It backs unit training, crafting jobs, construction, research,
|
|
5
|
+
* respawns, downloads, and fabrication without any of them re-implementing the
|
|
6
|
+
* reservation → progress → completion → output-routing loop.
|
|
7
|
+
*
|
|
8
|
+
* The state ({@link WorkQueueState}) is plain serializable data; all policy —
|
|
9
|
+
* duration, ordering, capacity, concurrency, input reservation, refund, and
|
|
10
|
+
* output mapping — lives in {@link WorkQueueConfig}, which is supplied by the
|
|
11
|
+
* caller and is never serialized. Side effects (charging a wallet, spawning an
|
|
12
|
+
* entity) are the caller's: reservations and refunds are returned as data, and
|
|
13
|
+
* completion emits a typed event carrying a pure output payload for an external
|
|
14
|
+
* completion adapter to route.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Pure FIFO ordering by enqueue sequence.
|
|
18
|
+
*
|
|
19
|
+
* @capability work-order-fifo order queued jobs by enqueue sequence
|
|
20
|
+
*/
|
|
21
|
+
export function fifoOrdering(a, b) {
|
|
22
|
+
return a.seq - b.seq;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Priority-first ordering (higher priority sooner), FIFO within equal priority.
|
|
26
|
+
*
|
|
27
|
+
* @capability work-order-priority order queued jobs by priority, then FIFO within equal priority
|
|
28
|
+
*/
|
|
29
|
+
export function priorityOrdering(a, b) {
|
|
30
|
+
return b.priority - a.priority || a.seq - b.seq;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create an empty timed work queue.
|
|
34
|
+
*
|
|
35
|
+
* @capability work-queue a serializable timed job queue with reservation, cancellation, completion, and output routing
|
|
36
|
+
*/
|
|
37
|
+
export function createWorkQueue() {
|
|
38
|
+
return { jobs: [], nextId: 1, seq: 0 };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Non-terminal job count (queued + active + paused).
|
|
42
|
+
*
|
|
43
|
+
* @capability work-queue-size count non-terminal jobs in a work queue
|
|
44
|
+
*/
|
|
45
|
+
export function queueSize(state) {
|
|
46
|
+
return state.jobs.length;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Look up a job by id, or `null` if absent/terminal.
|
|
50
|
+
*
|
|
51
|
+
* @capability work-job-by-id look up a queued job by id
|
|
52
|
+
*/
|
|
53
|
+
export function jobById(state, id) {
|
|
54
|
+
return state.jobs.find((job) => job.id === id) ?? null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Jobs waiting for a slot, in selection order.
|
|
58
|
+
*
|
|
59
|
+
* @capability work-queued-jobs list jobs waiting for a slot, in selection order
|
|
60
|
+
*/
|
|
61
|
+
export function queuedJobs(state, ordering = priorityOrdering) {
|
|
62
|
+
return state.jobs.filter((job) => job.status === "queued").sort(ordering);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Jobs currently progressing.
|
|
66
|
+
*
|
|
67
|
+
* @capability work-active-jobs list jobs currently progressing in a work queue
|
|
68
|
+
*/
|
|
69
|
+
export function activeJobs(state) {
|
|
70
|
+
return state.jobs.filter((job) => job.status === "active");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Fractional progress of a job (0…1); a zero-duration job reads as complete.
|
|
74
|
+
*
|
|
75
|
+
* @capability work-job-progress compute a job's fractional progress
|
|
76
|
+
*/
|
|
77
|
+
export function jobProgress(job) {
|
|
78
|
+
if (job.duration <= 0)
|
|
79
|
+
return 1;
|
|
80
|
+
return Math.min(1, Math.max(0, job.elapsed / job.duration));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Enqueue a new job. Validates capacity and the injected `validate` policy, then
|
|
84
|
+
* computes and stores the reservation. Charging the reservation (now or later) is
|
|
85
|
+
* the caller's responsibility using {@link EnqueueResult.job}'s `reservation`.
|
|
86
|
+
*
|
|
87
|
+
* @capability enqueue-work reserve inputs and add a timed job, honoring capacity and validation policy
|
|
88
|
+
*/
|
|
89
|
+
export function enqueue(state, config, spec, options) {
|
|
90
|
+
if (config.capacity !== undefined && state.jobs.length >= config.capacity) {
|
|
91
|
+
return { ok: false, state, reason: "capacity" };
|
|
92
|
+
}
|
|
93
|
+
const validation = config.validate?.(spec, state);
|
|
94
|
+
if (validation !== undefined && !validation.ok) {
|
|
95
|
+
return { ok: false, state, reason: validation.reason ?? "invalid" };
|
|
96
|
+
}
|
|
97
|
+
const reservation = (config.reserve ? config.reserve(spec) : undefined);
|
|
98
|
+
const job = {
|
|
99
|
+
id: options?.id ?? `job-${state.nextId}`,
|
|
100
|
+
spec,
|
|
101
|
+
reservation,
|
|
102
|
+
status: "queued",
|
|
103
|
+
duration: Math.max(0, config.duration(spec)),
|
|
104
|
+
elapsed: 0,
|
|
105
|
+
priority: options?.priority ?? 0,
|
|
106
|
+
seq: state.seq,
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
ok: true,
|
|
110
|
+
job,
|
|
111
|
+
state: { jobs: [...state.jobs, job], nextId: state.nextId + 1, seq: state.seq + 1 },
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Cancel a job and compute its refund. Removes the job from the queue and returns
|
|
116
|
+
* a refund payload (full reservation by default, or `config.refund` applied to the
|
|
117
|
+
* job's progress for partial/no refund). Applying the refund is the caller's job.
|
|
118
|
+
*
|
|
119
|
+
* @capability cancel-work remove a job and compute its refund from reservation and progress
|
|
120
|
+
*/
|
|
121
|
+
export function cancelJob(state, config, id) {
|
|
122
|
+
const job = state.jobs.find((entry) => entry.id === id);
|
|
123
|
+
if (job === undefined)
|
|
124
|
+
return { ok: false, state, reason: "not-found" };
|
|
125
|
+
const refund = config.refund
|
|
126
|
+
? config.refund(job, jobProgress(job))
|
|
127
|
+
: (job.reservation ?? null);
|
|
128
|
+
return { ok: true, state: { ...state, jobs: state.jobs.filter((entry) => entry.id !== id) }, job, refund };
|
|
129
|
+
}
|
|
130
|
+
function setStatus(state, id, from, to) {
|
|
131
|
+
let changed = false;
|
|
132
|
+
const jobs = state.jobs.map((job) => {
|
|
133
|
+
if (job.id === id && job.status === from) {
|
|
134
|
+
changed = true;
|
|
135
|
+
return { ...job, status: to };
|
|
136
|
+
}
|
|
137
|
+
return job;
|
|
138
|
+
});
|
|
139
|
+
return changed ? { ...state, jobs } : state;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Pause a queued or active job in place; a paused job keeps its progress and yields its slot.
|
|
143
|
+
*
|
|
144
|
+
* @capability pause-work pause a queued or active job in place, retaining its progress
|
|
145
|
+
*/
|
|
146
|
+
export function pauseJob(state, id) {
|
|
147
|
+
const active = setStatus(state, id, "active", "paused");
|
|
148
|
+
return active !== state ? active : setStatus(state, id, "queued", "paused");
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Resume a paused job; it re-enters the queue and competes for a slot by ordering.
|
|
152
|
+
*
|
|
153
|
+
* @capability resume-work resume a paused job back into the queue's slot competition
|
|
154
|
+
*/
|
|
155
|
+
export function resumeJob(state, id) {
|
|
156
|
+
return setStatus(state, id, "paused", "queued");
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Advance the queue by `dt` seconds. Promotes queued jobs into up to `concurrency`
|
|
160
|
+
* active slots, advances active jobs, and completes those that reach their
|
|
161
|
+
* duration — emitting `started`/`completed` events in deterministic order. A large
|
|
162
|
+
* `dt` catches up across many jobs in one call: when a job completes with leftover
|
|
163
|
+
* time, the freed slot promotes the next queued job and applies the remainder, so a
|
|
164
|
+
* reconnect or save/load gap resolves in a single bounded pass. Completed jobs are
|
|
165
|
+
* removed from the returned state.
|
|
166
|
+
*
|
|
167
|
+
* @capability tick-work advance jobs over time, completing work and emitting typed lifecycle events
|
|
168
|
+
*/
|
|
169
|
+
export function tick(state, config, dt) {
|
|
170
|
+
if (dt <= 0 || state.jobs.length === 0)
|
|
171
|
+
return { state, events: [] };
|
|
172
|
+
const concurrency = Math.max(1, Math.floor(config.concurrency ?? 1));
|
|
173
|
+
const ordering = config.ordering ?? priorityOrdering;
|
|
174
|
+
const jobs = state.jobs.map((job) => ({ ...job }));
|
|
175
|
+
const events = [];
|
|
176
|
+
const budget = new Map();
|
|
177
|
+
const completedIds = new Set();
|
|
178
|
+
const activeCount = () => jobs.reduce((n, job) => (job.status === "active" ? n + 1 : n), 0);
|
|
179
|
+
const nextQueued = () => {
|
|
180
|
+
let best;
|
|
181
|
+
for (const job of jobs) {
|
|
182
|
+
if (job.status !== "queued")
|
|
183
|
+
continue;
|
|
184
|
+
if (best === undefined || ordering(job, best) < 0)
|
|
185
|
+
best = job;
|
|
186
|
+
}
|
|
187
|
+
return best;
|
|
188
|
+
};
|
|
189
|
+
const promote = (job, slotBudget) => {
|
|
190
|
+
job.status = "active";
|
|
191
|
+
budget.set(job.id, Math.max(0, slotBudget));
|
|
192
|
+
events.push({ type: "started", job: { ...job } });
|
|
193
|
+
};
|
|
194
|
+
// Jobs already active from a prior tick get a fresh full budget this tick.
|
|
195
|
+
for (const job of jobs) {
|
|
196
|
+
if (job.status === "active")
|
|
197
|
+
budget.set(job.id, dt);
|
|
198
|
+
}
|
|
199
|
+
// Fill idle slots up to concurrency with a full tick budget each.
|
|
200
|
+
while (activeCount() < concurrency) {
|
|
201
|
+
const next = nextQueued();
|
|
202
|
+
if (next === undefined)
|
|
203
|
+
break;
|
|
204
|
+
promote(next, dt);
|
|
205
|
+
}
|
|
206
|
+
// Step through completions in time order; each freed slot pulls the next queued
|
|
207
|
+
// job forward with the leftover time. Bounded by the job count.
|
|
208
|
+
const guardMax = jobs.length * 2 + concurrency + 8;
|
|
209
|
+
for (let guard = 0; guard <= guardMax; guard += 1) {
|
|
210
|
+
let chosen;
|
|
211
|
+
let chosenRemaining = Infinity;
|
|
212
|
+
for (const job of jobs) {
|
|
213
|
+
if (job.status !== "active")
|
|
214
|
+
continue;
|
|
215
|
+
const available = budget.get(job.id) ?? 0;
|
|
216
|
+
if (available <= 0)
|
|
217
|
+
continue;
|
|
218
|
+
const remaining = job.duration - job.elapsed;
|
|
219
|
+
if (remaining > available)
|
|
220
|
+
continue;
|
|
221
|
+
if (chosen === undefined ||
|
|
222
|
+
remaining < chosenRemaining ||
|
|
223
|
+
(remaining === chosenRemaining && ordering(job, chosen) < 0)) {
|
|
224
|
+
chosen = job;
|
|
225
|
+
chosenRemaining = remaining;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (chosen === undefined)
|
|
229
|
+
break;
|
|
230
|
+
const leftover = (budget.get(chosen.id) ?? 0) - Math.max(0, chosenRemaining);
|
|
231
|
+
chosen.elapsed = chosen.duration;
|
|
232
|
+
budget.delete(chosen.id);
|
|
233
|
+
completedIds.add(chosen.id);
|
|
234
|
+
const finished = { ...chosen, status: "active" };
|
|
235
|
+
const output = (config.output ? config.output(finished) : undefined);
|
|
236
|
+
events.push({ type: "completed", job: finished, output });
|
|
237
|
+
const next = nextQueued();
|
|
238
|
+
if (next !== undefined)
|
|
239
|
+
promote(next, leftover);
|
|
240
|
+
}
|
|
241
|
+
// Advance any active job that still holds budget but did not complete.
|
|
242
|
+
for (const job of jobs) {
|
|
243
|
+
if (job.status !== "active" || completedIds.has(job.id))
|
|
244
|
+
continue;
|
|
245
|
+
const available = budget.get(job.id) ?? 0;
|
|
246
|
+
if (available > 0)
|
|
247
|
+
job.elapsed = Math.min(job.duration, job.elapsed + available);
|
|
248
|
+
}
|
|
249
|
+
const remaining = jobs
|
|
250
|
+
.filter((job) => !completedIds.has(job.id))
|
|
251
|
+
.map((job) => ({ ...job }));
|
|
252
|
+
return { state: { ...state, jobs: remaining }, events };
|
|
253
|
+
}
|