@jgengine/core 0.9.0 → 0.11.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 +34 -3
- 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/spawnDirector.d.ts +19 -1
- package/dist/ai/spawnDirector.js +53 -26
- package/dist/ai/spawnPoint.d.ts +7 -0
- package/dist/ai/spawnPoint.js +7 -0
- 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/audio/audioFalloff.d.ts +5 -2
- package/dist/audio/music.d.ts +53 -0
- package/dist/audio/music.js +34 -0
- package/dist/audio/synth.d.ts +60 -0
- package/dist/audio/synth.js +8 -0
- package/dist/authoring.d.ts +15 -0
- package/dist/authoring.js +15 -0
- 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 +47 -0
- package/dist/combat/dotField.js +52 -0
- 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 +7 -2
- package/dist/combat/projectiles.js +48 -17
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +39 -0
- package/dist/combat/regenShield.js +49 -0
- 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 +30 -1
- package/dist/combat/shotOrigin.js +70 -2
- 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 +34 -0
- package/dist/combat.js +34 -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/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/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/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/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commands.d.ts +248 -0
- package/dist/editor/commands.js +865 -0
- package/dist/editor/document.d.ts +186 -0
- package/dist/editor/document.js +884 -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 +97 -0
- package/dist/editor/index.js +10 -0
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/types.d.ts +175 -0
- package/dist/editor/types.js +29 -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/connectedPlayers.d.ts +30 -0
- package/dist/game/connectedPlayers.js +21 -0
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +141 -2
- package/dist/game/defineGame.js +39 -1
- package/dist/game/defineSystem.d.ts +88 -0
- package/dist/game/defineSystem.js +45 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +50 -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/keyValueStore.d.ts +25 -0
- package/dist/game/keyValueStore.js +61 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/levelSequence.d.ts +24 -2
- package/dist/game/levelSequence.js +51 -2
- 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 +21 -0
- package/dist/game/lootTable.js +15 -4
- package/dist/game/modelAnimation.d.ts +8 -0
- package/dist/game/modelAnimation.js +18 -0
- 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 +160 -12
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +29 -0
- package/dist/game/race.d.ts +141 -0
- package/dist/game/race.js +169 -0
- package/dist/game/recordBook.d.ts +5 -5
- 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/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 +91 -0
- package/dist/gameplay.js +91 -0
- package/dist/index.d.ts +5 -7
- package/dist/index.js +5 -7
- package/dist/input/actionBindings.d.ts +24 -5
- package/dist/input/actionBindings.js +23 -5
- package/dist/input/axisInput.d.ts +13 -1
- package/dist/input/axisInput.js +22 -1
- 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/contextMenu.d.ts +1 -0
- package/dist/interaction/contextMenu.js +1 -0
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +5 -1
- package/dist/interaction/proximityPrompt.js +5 -3
- 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/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 +5 -0
- 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 +36 -1
- 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 +38 -7
- package/dist/movement/movementModel.js +54 -13
- package/dist/movement/playerMovement.d.ts +41 -0
- package/dist/movement/playerMovement.js +236 -0
- 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 +3 -0
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +9 -1
- package/dist/multiplayer/presenceModel.js +9 -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 +29 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/kinematicVehicle.d.ts +21 -1
- package/dist/physics/kinematicVehicle.js +23 -8
- package/dist/physics/physicsWorld.d.ts +24 -12
- package/dist/physics/physicsWorld.js +11 -5
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -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 +24 -0
- package/dist/random/rng.js +30 -8
- 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 +76 -0
- package/dist/render/postProcessing.js +21 -0
- 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 +58 -0
- package/dist/runtime/adapter.js +54 -5
- 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/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -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 +134 -0
- package/dist/runtime/descriptors/features.d.ts +74 -0
- package/dist/runtime/descriptors/features.js +281 -0
- package/dist/runtime/gameContext.d.ts +163 -19
- package/dist/runtime/gameContext.js +385 -339
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +60 -0
- package/dist/runtime/headlessRunner.js +44 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostedGameRunner.d.ts +54 -0
- package/dist/runtime/hostedGameRunner.js +85 -0
- package/dist/runtime/hostedWorldSession.d.ts +73 -0
- package/dist/runtime/hostedWorldSession.js +64 -0
- package/dist/runtime/inputSnapshot.d.ts +21 -3
- package/dist/runtime/inputSnapshot.js +8 -2
- package/dist/runtime/motionIntents.d.ts +12 -1
- package/dist/runtime/motionIntents.js +26 -1
- 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 +62 -0
- package/dist/runtime/worldChannel.js +114 -0
- package/dist/runtime/worldMirror.d.ts +36 -0
- package/dist/runtime/worldMirror.js +44 -0
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +69 -0
- package/dist/runtime/worldReplication.js +217 -0
- package/dist/runtime/worldSnapshot.d.ts +44 -0
- package/dist/runtime/worldSnapshot.js +30 -0
- package/dist/scene/assetCatalog.d.ts +22 -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 +259 -0
- package/dist/scene/authoredTriggers.d.ts +169 -0
- package/dist/scene/authoredTriggers.js +340 -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 +62 -0
- package/dist/scene/colliders.d.ts +18 -0
- package/dist/scene/colliders.js +61 -1
- package/dist/scene/entityStats.d.ts +13 -0
- package/dist/scene/entityStats.js +30 -0
- package/dist/scene/entityStore.d.ts +41 -1
- package/dist/scene/entityStore.js +75 -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 +240 -0
- package/dist/scene/sceneKinds.js +214 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -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/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -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 +9 -0
- package/dist/store/observableKeyedStore.js +43 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -55
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +5 -0
- package/dist/tactics/fallingGrid.d.ts +6 -4
- package/dist/tactics/fallingGrid.js +6 -4
- 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 +144 -0
- package/dist/ui/gameLayout.js +148 -0
- package/dist/ui/hudDocument.d.ts +114 -0
- package/dist/ui/hudDocument.js +220 -0
- package/dist/ui/hudLayout.d.ts +33 -1
- package/dist/ui/hudLayout.js +204 -17
- package/dist/ui/orientation.d.ts +39 -0
- package/dist/ui/orientation.js +49 -0
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/swingTimer.d.ts +42 -0
- package/dist/ui/swingTimer.js +38 -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/visibility/spatialIndex.js +34 -20
- 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/authoredObjects.d.ts +58 -0
- package/dist/world/authoredObjects.js +69 -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/environmentSummary.d.ts +11 -2
- package/dist/world/environmentSummary.js +11 -1
- package/dist/world/features.d.ts +244 -7
- package/dist/world/features.js +92 -4
- 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/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +77 -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/polyline.d.ts +34 -0
- package/dist/world/polyline.js +81 -0
- package/dist/world/roads.d.ts +55 -0
- package/dist/world/roads.js +184 -0
- 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 +80 -0
- package/dist/world/streets.js +144 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +655 -20
- package/dist/world/terrain.d.ts +138 -12
- package/dist/world/terrain.js +346 -28
- 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 +132 -0
- package/dist/world.js +132 -0
- package/package.json +32 -8
- package/skills/jgengine/SKILL.md +51 -0
- package/skills/jgengine/api.md +434 -0
- package/skills/jgengine/capabilities.md +29 -0
- package/skills/jgengine/reference-cartridge.md +72 -0
- package/skills/jgengine-combat/SKILL.md +34 -0
- package/skills/jgengine-combat/api.md +549 -0
- package/skills/jgengine-combat/capabilities.md +169 -0
- package/skills/jgengine-combat/reference.md +98 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1794 -0
- package/skills/jgengine-gameplay/capabilities.md +378 -0
- package/skills/jgengine-gameplay/reference-systems.md +60 -0
- package/skills/jgengine-world/SKILL.md +38 -0
- package/skills/jgengine-world/api.md +2652 -0
- package/skills/jgengine-world/capabilities.md +370 -0
- package/skills/jgengine-world/reference.md +222 -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 -4983
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
function clone(phase) {
|
|
2
|
+
const copy = { id: phase.id };
|
|
3
|
+
if (phase.data !== undefined)
|
|
4
|
+
copy.data = phase.data;
|
|
5
|
+
if (phase.completion !== undefined)
|
|
6
|
+
copy.completion = phase.completion;
|
|
7
|
+
if (phase.spawn !== undefined)
|
|
8
|
+
copy.spawn = phase.spawn;
|
|
9
|
+
if (phase.repeat !== undefined)
|
|
10
|
+
copy.repeat = phase.repeat;
|
|
11
|
+
if (phase.children !== undefined)
|
|
12
|
+
copy.children = phase.children.map(clone);
|
|
13
|
+
return copy;
|
|
14
|
+
}
|
|
15
|
+
function readNumber(params, key, fallback) {
|
|
16
|
+
const value = params[key];
|
|
17
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
18
|
+
}
|
|
19
|
+
function readString(params, key) {
|
|
20
|
+
const value = params[key];
|
|
21
|
+
return typeof value === "string" ? value : null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Built-in completion predicates covering the common encounter gates: `immediate` (leaf
|
|
25
|
+
* marker), `manual`/`flag` (external event via a caller flag), `timer` (phase seconds),
|
|
26
|
+
* `cleared` (tagged entity count drained), `metric` (threshold on a live value), `event`
|
|
27
|
+
* (cumulative event count), and `quorum` (at least N of nested predicates met). Merge your
|
|
28
|
+
* own over these through {@link EncounterConfig.predicates}.
|
|
29
|
+
*
|
|
30
|
+
* @capability encounter-predicates gate encounter phase completion on timers, cleared spawns, metrics, events, or a quorum of conditions
|
|
31
|
+
*/
|
|
32
|
+
export const BUILTIN_COMPLETION_PREDICATES = {
|
|
33
|
+
immediate: () => true,
|
|
34
|
+
manual: (params, ctx) => {
|
|
35
|
+
const flag = readString(params, "flag") ?? ctx.phaseId;
|
|
36
|
+
return ctx.signals.flags?.[flag] === true;
|
|
37
|
+
},
|
|
38
|
+
flag: (params, ctx) => {
|
|
39
|
+
const flag = readString(params, "flag") ?? ctx.phaseId;
|
|
40
|
+
return ctx.signals.flags?.[flag] === true;
|
|
41
|
+
},
|
|
42
|
+
timer: (params, ctx) => ctx.phaseElapsed >= readNumber(params, "seconds", 0),
|
|
43
|
+
cleared: (params, ctx) => {
|
|
44
|
+
const tag = readString(params, "tag");
|
|
45
|
+
if (tag === null)
|
|
46
|
+
return false;
|
|
47
|
+
const remaining = readNumber(params, "remaining", 0);
|
|
48
|
+
return (ctx.signals.counts?.[tag] ?? 0) <= remaining;
|
|
49
|
+
},
|
|
50
|
+
metric: (params, ctx) => {
|
|
51
|
+
const name = readString(params, "name");
|
|
52
|
+
if (name === null)
|
|
53
|
+
return false;
|
|
54
|
+
const value = ctx.signals.metrics?.[name] ?? 0;
|
|
55
|
+
const target = readNumber(params, "target", 0);
|
|
56
|
+
return readString(params, "direction") === "atMost" ? value <= target : value >= target;
|
|
57
|
+
},
|
|
58
|
+
event: (params, ctx) => {
|
|
59
|
+
const name = readString(params, "name");
|
|
60
|
+
if (name === null)
|
|
61
|
+
return false;
|
|
62
|
+
return (ctx.signals.events?.[name] ?? 0) >= readNumber(params, "count", 1);
|
|
63
|
+
},
|
|
64
|
+
quorum: (params, ctx) => {
|
|
65
|
+
const refs = params["predicates"];
|
|
66
|
+
if (!Array.isArray(refs))
|
|
67
|
+
return false;
|
|
68
|
+
const need = readNumber(params, "count", refs.length);
|
|
69
|
+
let met = 0;
|
|
70
|
+
for (const raw of refs) {
|
|
71
|
+
const ref = raw;
|
|
72
|
+
const predicate = BUILTIN_COMPLETION_PREDICATES[ref.kind];
|
|
73
|
+
if (predicate !== undefined && predicate(ref.params ?? {}, ctx))
|
|
74
|
+
met += 1;
|
|
75
|
+
if (met >= need)
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Built-in spawn providers. `points` reads a named authored scene point list from context
|
|
83
|
+
* and cycles it to emit `count` requests, keeping coordinates in the scene rather than the
|
|
84
|
+
* sequence. `list` echoes literal requests authored in `params.requests`. Merge your own
|
|
85
|
+
* catalog- or director-backed providers through {@link EncounterConfig.spawnProviders}.
|
|
86
|
+
*
|
|
87
|
+
* @capability encounter-spawn-providers turn an entered encounter phase into spawn requests from authored scene points or an inline list
|
|
88
|
+
*/
|
|
89
|
+
export const BUILTIN_SPAWN_PROVIDERS = {
|
|
90
|
+
points: (params, ctx) => {
|
|
91
|
+
const ref = readString(params, "ref");
|
|
92
|
+
if (ref === null)
|
|
93
|
+
return [];
|
|
94
|
+
const points = ctx.spawnPoints[ref] ?? [];
|
|
95
|
+
if (points.length === 0)
|
|
96
|
+
return [];
|
|
97
|
+
const count = Math.max(0, Math.floor(readNumber(params, "count", points.length)));
|
|
98
|
+
const entityRef = readString(params, "entity") ?? ref;
|
|
99
|
+
const requests = [];
|
|
100
|
+
for (let index = 0; index < count; index += 1) {
|
|
101
|
+
requests.push({ ref: entityRef, point: points[index % points.length] });
|
|
102
|
+
}
|
|
103
|
+
return requests;
|
|
104
|
+
},
|
|
105
|
+
list: (params) => {
|
|
106
|
+
const raw = params["requests"];
|
|
107
|
+
return Array.isArray(raw) ? raw : [];
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
function collectIds(phases, out) {
|
|
111
|
+
for (const phase of phases) {
|
|
112
|
+
if (out.has(phase.id))
|
|
113
|
+
throw new Error(`encounter phase id "${phase.id}" is not unique`);
|
|
114
|
+
out.add(phase.id);
|
|
115
|
+
if (phase.children !== undefined)
|
|
116
|
+
collectIds(phase.children, out);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function indexTree(phases, parent, index) {
|
|
120
|
+
for (const phase of phases) {
|
|
121
|
+
index.set(phase.id, { phase, parent });
|
|
122
|
+
if (phase.children !== undefined)
|
|
123
|
+
indexTree(phase.children, phase, index);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function ensureRuntime(state, id) {
|
|
127
|
+
let runtime = state.nodes[id];
|
|
128
|
+
if (runtime === undefined) {
|
|
129
|
+
runtime = { status: "pending", iteration: 0, enteredAt: state.elapsed };
|
|
130
|
+
state.nodes[id] = runtime;
|
|
131
|
+
}
|
|
132
|
+
return runtime;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Build the initial, serializable state for an encounter from its config. Deep-copies the
|
|
136
|
+
* authored phase tree (so later injection never mutates the config), verifies phase ids are
|
|
137
|
+
* unique, and leaves every node pending. Does not enter the first phase — call
|
|
138
|
+
* {@link startEncounter} for that.
|
|
139
|
+
*
|
|
140
|
+
* @capability encounter-state create the serializable starting state of a hierarchical encounter sequence
|
|
141
|
+
*/
|
|
142
|
+
export function createEncounterState(config) {
|
|
143
|
+
const ids = new Set();
|
|
144
|
+
collectIds(config.phases, ids);
|
|
145
|
+
const roots = config.phases.map(clone);
|
|
146
|
+
const nodes = {};
|
|
147
|
+
for (const id of ids)
|
|
148
|
+
nodes[id] = { status: "pending", iteration: 0, enteredAt: 0 };
|
|
149
|
+
return { roots, nodes, activePath: [], elapsed: 0, started: false, done: false };
|
|
150
|
+
}
|
|
151
|
+
function access(state) {
|
|
152
|
+
const index = new Map();
|
|
153
|
+
indexTree(state.roots, null, index);
|
|
154
|
+
return {
|
|
155
|
+
index,
|
|
156
|
+
siblingsOf(id) {
|
|
157
|
+
const parent = index.get(id)?.parent;
|
|
158
|
+
return parent?.children ?? state.roots;
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function resetSubtree(state, phase) {
|
|
163
|
+
const runtime = ensureRuntime(state, phase.id);
|
|
164
|
+
runtime.status = "pending";
|
|
165
|
+
if (phase.children !== undefined)
|
|
166
|
+
for (const child of phase.children)
|
|
167
|
+
resetSubtree(state, child);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Enter a node and, if it is a group, descend to its first child, pushing every entered id
|
|
171
|
+
* onto the active path and emitting enter + spawn events. Leaves the deepest entered node
|
|
172
|
+
* as the new cursor. Bounded by tree depth.
|
|
173
|
+
*/
|
|
174
|
+
function enterChain(config, state, tree, startId, ctx, events, spawned) {
|
|
175
|
+
let currentId = startId;
|
|
176
|
+
const providers = { ...BUILTIN_SPAWN_PROVIDERS, ...config.spawnProviders };
|
|
177
|
+
let guard = tree.index.size + 1;
|
|
178
|
+
while (currentId !== undefined && guard > 0) {
|
|
179
|
+
guard -= 1;
|
|
180
|
+
const entry = tree.index.get(currentId);
|
|
181
|
+
if (entry === undefined)
|
|
182
|
+
return;
|
|
183
|
+
const phase = entry.phase;
|
|
184
|
+
const runtime = ensureRuntime(state, currentId);
|
|
185
|
+
runtime.status = "active";
|
|
186
|
+
runtime.enteredAt = state.elapsed;
|
|
187
|
+
state.activePath.push(currentId);
|
|
188
|
+
events.push({ type: "enter", phaseId: currentId, iteration: runtime.iteration });
|
|
189
|
+
if (phase.spawn !== undefined) {
|
|
190
|
+
// A phase that introduces spawns cannot complete on the same tick it enters — the
|
|
191
|
+
// caller has not observed the spawn yet — so defer its evaluation to the next update.
|
|
192
|
+
spawned.add(currentId);
|
|
193
|
+
const provider = providers[phase.spawn.kind];
|
|
194
|
+
if (provider !== undefined) {
|
|
195
|
+
const requests = provider(phase.spawn.params ?? {}, {
|
|
196
|
+
phaseId: currentId,
|
|
197
|
+
iteration: runtime.iteration,
|
|
198
|
+
elapsed: state.elapsed,
|
|
199
|
+
spawnPoints: ctx.spawnPoints ?? {},
|
|
200
|
+
});
|
|
201
|
+
if (requests.length > 0)
|
|
202
|
+
events.push({ type: "spawn", phaseId: currentId, provider: phase.spawn.kind, requests });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const firstChild = phase.children?.[0];
|
|
206
|
+
currentId = firstChild?.id;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Start a created encounter: enter the first root phase, descending to its first leaf, and
|
|
211
|
+
* return the initial enter/spawn events. A no-op (with no events) on an already-started or
|
|
212
|
+
* empty encounter. Mutates and returns `state`.
|
|
213
|
+
*
|
|
214
|
+
* @capability encounter-start enter the first phase of a hierarchical encounter and emit its opening spawn events
|
|
215
|
+
*/
|
|
216
|
+
export function startEncounter(config, state, ctx = {}) {
|
|
217
|
+
const events = [];
|
|
218
|
+
if (state.started || state.done || state.roots.length === 0)
|
|
219
|
+
return { state, events };
|
|
220
|
+
state.started = true;
|
|
221
|
+
const tree = access(state);
|
|
222
|
+
enterChain(config, state, tree, state.roots[0].id, ctx, events, new Set());
|
|
223
|
+
return { state, events };
|
|
224
|
+
}
|
|
225
|
+
function predicateMet(config, phase, runtime, state, ctx) {
|
|
226
|
+
const completion = phase.completion;
|
|
227
|
+
if (completion === undefined)
|
|
228
|
+
return { met: true, reason: phase.children === undefined ? "immediate" : "children" };
|
|
229
|
+
const predicates = { ...BUILTIN_COMPLETION_PREDICATES, ...config.predicates };
|
|
230
|
+
const predicate = predicates[completion.kind];
|
|
231
|
+
if (predicate === undefined)
|
|
232
|
+
return { met: false, reason: completion.kind };
|
|
233
|
+
const met = predicate(completion.params ?? {}, {
|
|
234
|
+
phaseId: phase.id,
|
|
235
|
+
iteration: runtime.iteration,
|
|
236
|
+
elapsed: state.elapsed,
|
|
237
|
+
phaseElapsed: state.elapsed - runtime.enteredAt,
|
|
238
|
+
signals: ctx.signals ?? {},
|
|
239
|
+
});
|
|
240
|
+
return { met, reason: completion.kind };
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Advance an encounter by `dt` seconds against the caller `ctx`. Accumulates time, then
|
|
244
|
+
* repeatedly: evaluates the cursor node's completion predicate; on completion, either
|
|
245
|
+
* re-runs its subtree (`repeat`) or marks it complete and advances to the next sibling —
|
|
246
|
+
* bubbling up to parent groups whose children are exhausted — entering the next chain and
|
|
247
|
+
* emitting enter/spawn/complete events. Emits a final `done` event when the last phase
|
|
248
|
+
* completes. Bounded per call by node count; mutates and returns `state`.
|
|
249
|
+
*
|
|
250
|
+
* @capability encounter-advance step a hierarchical encounter, resolving predicate-gated completion, repeats, and nested advance with lifecycle events
|
|
251
|
+
*/
|
|
252
|
+
export function updateEncounter(config, state, dt, ctx = {}) {
|
|
253
|
+
const events = [];
|
|
254
|
+
if (!state.started || state.done || state.activePath.length === 0)
|
|
255
|
+
return { state, events };
|
|
256
|
+
if (dt > 0)
|
|
257
|
+
state.elapsed += dt;
|
|
258
|
+
const tree = access(state);
|
|
259
|
+
const justSpawned = new Set();
|
|
260
|
+
let guard = tree.index.size * 2 + 2;
|
|
261
|
+
while (guard > 0 && state.activePath.length > 0) {
|
|
262
|
+
guard -= 1;
|
|
263
|
+
const cursorId = state.activePath[state.activePath.length - 1];
|
|
264
|
+
// A phase that spawned earlier in this same step defers its completion to the next update.
|
|
265
|
+
if (justSpawned.has(cursorId))
|
|
266
|
+
break;
|
|
267
|
+
const entry = tree.index.get(cursorId);
|
|
268
|
+
if (entry === undefined) {
|
|
269
|
+
state.activePath.pop();
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
const phase = entry.phase;
|
|
273
|
+
const runtime = ensureRuntime(state, cursorId);
|
|
274
|
+
const { met, reason } = predicateMet(config, phase, runtime, state, ctx);
|
|
275
|
+
if (!met)
|
|
276
|
+
break;
|
|
277
|
+
if (runtime.iteration < Math.max(0, Math.floor(phase.repeat ?? 0))) {
|
|
278
|
+
runtime.iteration += 1;
|
|
279
|
+
if (phase.children !== undefined)
|
|
280
|
+
for (const child of phase.children)
|
|
281
|
+
resetSubtree(state, child);
|
|
282
|
+
state.activePath.pop();
|
|
283
|
+
enterChain(config, state, tree, cursorId, ctx, events, justSpawned);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
runtime.status = "complete";
|
|
287
|
+
events.push({ type: "complete", phaseId: cursorId, iteration: runtime.iteration, reason });
|
|
288
|
+
state.activePath.pop();
|
|
289
|
+
const siblings = tree.siblingsOf(cursorId);
|
|
290
|
+
const position = siblings.findIndex((sibling) => sibling.id === cursorId);
|
|
291
|
+
const nextSibling = position >= 0 ? siblings[position + 1] : undefined;
|
|
292
|
+
if (nextSibling !== undefined) {
|
|
293
|
+
enterChain(config, state, tree, nextSibling.id, ctx, events, justSpawned);
|
|
294
|
+
}
|
|
295
|
+
else if (state.activePath.length === 0) {
|
|
296
|
+
state.done = true;
|
|
297
|
+
events.push({ type: "done" });
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return { state, events };
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Force the deepest active phase (or a named active phase) to complete now, regardless of
|
|
305
|
+
* its predicate — the escape hatch for external/scripted completion and failure/retry flows.
|
|
306
|
+
* Advances into the next phase and emits the same lifecycle events as a natural completion.
|
|
307
|
+
* Returns no events if the phase is not currently active. Mutates and returns `state`.
|
|
308
|
+
*
|
|
309
|
+
* @capability encounter-force-complete externally complete an active encounter phase to drive scripted or failure-retry transitions
|
|
310
|
+
*/
|
|
311
|
+
export function forceCompletePhase(config, state, ctx = {}, phaseId) {
|
|
312
|
+
const events = [];
|
|
313
|
+
if (!state.started || state.done || state.activePath.length === 0)
|
|
314
|
+
return { state, events };
|
|
315
|
+
const targetId = phaseId ?? state.activePath[state.activePath.length - 1];
|
|
316
|
+
if (!state.activePath.includes(targetId))
|
|
317
|
+
return { state, events };
|
|
318
|
+
// Collapse the active path down to the target so update resolves it as the cursor, then
|
|
319
|
+
// advance it via an always-true synthetic predicate scoped to this single phase.
|
|
320
|
+
while (state.activePath.length > 0 && state.activePath[state.activePath.length - 1] !== targetId) {
|
|
321
|
+
state.activePath.pop();
|
|
322
|
+
}
|
|
323
|
+
const tree = access(state);
|
|
324
|
+
const entry = tree.index.get(targetId);
|
|
325
|
+
if (entry === undefined)
|
|
326
|
+
return { state, events };
|
|
327
|
+
const originalCompletion = entry.phase.completion;
|
|
328
|
+
entry.phase.completion = { kind: "__forced__" };
|
|
329
|
+
const forcedConfig = {
|
|
330
|
+
...config,
|
|
331
|
+
predicates: { ...config.predicates, __forced__: () => true },
|
|
332
|
+
};
|
|
333
|
+
const step = updateEncounter(forcedConfig, state, 0, ctx);
|
|
334
|
+
// Restore the authored predicate on the (possibly repeating) phase for future runs.
|
|
335
|
+
if (originalCompletion === undefined)
|
|
336
|
+
delete entry.phase.completion;
|
|
337
|
+
else
|
|
338
|
+
entry.phase.completion = originalCompletion;
|
|
339
|
+
return step;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Insert a phase into the working tree at runtime — before/after a sibling, or as a child of
|
|
343
|
+
* a group — without disturbing already-completed or active nodes. The injected subtree
|
|
344
|
+
* becomes part of the serializable state (so a mid-encounter save preserves it) and is
|
|
345
|
+
* reached in normal order if it sits ahead of the cursor. Ids must stay tree-unique. Mutates
|
|
346
|
+
* and returns `state`.
|
|
347
|
+
*
|
|
348
|
+
* @capability encounter-inject-phase dynamically insert a phase or branch into a running encounter, e.g. a boss on the final wave
|
|
349
|
+
*/
|
|
350
|
+
export function injectPhase(state, phase, at) {
|
|
351
|
+
const existing = new Set();
|
|
352
|
+
collectIds(state.roots, existing);
|
|
353
|
+
const incoming = new Set();
|
|
354
|
+
collectIds([phase], incoming);
|
|
355
|
+
for (const id of incoming)
|
|
356
|
+
if (existing.has(id))
|
|
357
|
+
throw new Error(`encounter phase id "${id}" is not unique`);
|
|
358
|
+
const copy = clone(phase);
|
|
359
|
+
const tree = access(state);
|
|
360
|
+
if ("childOf" in at) {
|
|
361
|
+
const parentEntry = tree.index.get(at.childOf);
|
|
362
|
+
if (parentEntry === undefined)
|
|
363
|
+
throw new Error(`inject target "${at.childOf}" not found`);
|
|
364
|
+
const parent = parentEntry.phase;
|
|
365
|
+
const children = parent.children !== undefined ? [...parent.children] : [];
|
|
366
|
+
const index = at.index === undefined ? children.length : Math.max(0, Math.min(children.length, at.index));
|
|
367
|
+
children.splice(index, 0, copy);
|
|
368
|
+
parent.children = children;
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
const targetId = "before" in at ? at.before : at.after;
|
|
372
|
+
const targetEntry = tree.index.get(targetId);
|
|
373
|
+
if (targetEntry === undefined)
|
|
374
|
+
throw new Error(`inject target "${targetId}" not found`);
|
|
375
|
+
const siblings = targetEntry.parent?.children ?? state.roots;
|
|
376
|
+
const list = [...siblings];
|
|
377
|
+
const position = list.findIndex((sibling) => sibling.id === targetId);
|
|
378
|
+
const insertAt = "before" in at ? position : position + 1;
|
|
379
|
+
list.splice(insertAt, 0, copy);
|
|
380
|
+
if (targetEntry.parent === null)
|
|
381
|
+
state.roots = list;
|
|
382
|
+
else
|
|
383
|
+
targetEntry.parent.children = list;
|
|
384
|
+
}
|
|
385
|
+
resetSubtree(state, copy);
|
|
386
|
+
return state;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* The deepest active phase id — the completion cursor a HUD reads to label the current
|
|
390
|
+
* wave/phase — or null before start and once done.
|
|
391
|
+
*
|
|
392
|
+
* @capability encounter-active-phase read the id of the phase an encounter is currently waiting on
|
|
393
|
+
*/
|
|
394
|
+
export function activePhaseId(state) {
|
|
395
|
+
return state.activePath.length > 0 ? state.activePath[state.activePath.length - 1] : null;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* The runtime status of a phase by id (pending/active/complete), or null if the id is
|
|
399
|
+
* unknown — for driving per-phase HUD ticks and objective checklists.
|
|
400
|
+
*
|
|
401
|
+
* @capability encounter-phase-status read whether a specific encounter phase is pending, active, or complete
|
|
402
|
+
*/
|
|
403
|
+
export function phaseStatus(state, id) {
|
|
404
|
+
return state.nodes[id]?.status ?? null;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Progress across the whole tree: how many phases have completed out of the total node
|
|
408
|
+
* count, plus whether the encounter has finished. Counts injected phases.
|
|
409
|
+
*
|
|
410
|
+
* @capability encounter-progress read completed-vs-total progress across a hierarchical encounter for HUD or objective display
|
|
411
|
+
*/
|
|
412
|
+
export function encounterProgress(state) {
|
|
413
|
+
let total = 0;
|
|
414
|
+
let completed = 0;
|
|
415
|
+
const walk = (phases) => {
|
|
416
|
+
for (const phase of phases) {
|
|
417
|
+
total += 1;
|
|
418
|
+
if (state.nodes[phase.id]?.status === "complete")
|
|
419
|
+
completed += 1;
|
|
420
|
+
if (phase.children !== undefined)
|
|
421
|
+
walk(phase.children);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
walk(state.roots);
|
|
425
|
+
return { completed, total, done: state.done };
|
|
426
|
+
}
|
|
@@ -8,6 +8,10 @@ export interface HitReactionConfig {
|
|
|
8
8
|
knockback: number;
|
|
9
9
|
vertical?: number;
|
|
10
10
|
shake?: CameraShake;
|
|
11
|
+
/** Trauma (0..1) fed to a trauma² camera-shake channel — the calibrated alternative to `shake`. */
|
|
12
|
+
trauma?: number;
|
|
13
|
+
/** Slow-mo factor during hitstop (e.g. 0.05 = 5% speed); read by the game's own time-scale system, not applied here. */
|
|
14
|
+
timescale?: number;
|
|
11
15
|
}
|
|
12
16
|
export interface HitReactionInput {
|
|
13
17
|
attackerPos: EntityPosition;
|
|
@@ -18,6 +22,58 @@ export interface HitReaction {
|
|
|
18
22
|
hitstopMs: number;
|
|
19
23
|
impulse: [number, number, number];
|
|
20
24
|
shake: CameraShake | null;
|
|
25
|
+
trauma: number | null;
|
|
26
|
+
timescale: number | null;
|
|
21
27
|
}
|
|
22
|
-
|
|
28
|
+
/** A calibrated `resolveHitReaction` config for a named impact event — hitstop + trauma so feel works with zero tuning. */
|
|
29
|
+
export interface ImpactPreset {
|
|
30
|
+
hitstopMs: number;
|
|
31
|
+
trauma: number;
|
|
32
|
+
timescale?: number;
|
|
33
|
+
knockback?: number;
|
|
34
|
+
vertical?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Calibrated per-event impact feel — hitstop and trauma numbers harvested
|
|
38
|
+
* from a shipped game-feel reference, not hand-invented per game. `explosion`
|
|
39
|
+
* and `playerHit` are "heavy hit" events (60–90ms hitstop @ 0.05 timescale);
|
|
40
|
+
* `pickup`/`jumpLand` are light events with no hitstop. Trauma is later
|
|
41
|
+
* clamped to 1.0 by `resolveHitReaction`.
|
|
42
|
+
*
|
|
43
|
+
* @capability impact-feel calibrated hitstop + trauma preset for a named impact event
|
|
44
|
+
*/
|
|
45
|
+
export declare const impactPresets: {
|
|
46
|
+
readonly pickup: {
|
|
47
|
+
readonly hitstopMs: 0;
|
|
48
|
+
readonly trauma: 0.15;
|
|
49
|
+
};
|
|
50
|
+
readonly jumpLand: {
|
|
51
|
+
readonly hitstopMs: 0;
|
|
52
|
+
readonly trauma: 0.2;
|
|
53
|
+
};
|
|
54
|
+
readonly enemyKilled: {
|
|
55
|
+
readonly hitstopMs: 40;
|
|
56
|
+
readonly trauma: 0.3;
|
|
57
|
+
};
|
|
58
|
+
readonly playerHit: {
|
|
59
|
+
readonly hitstopMs: 70;
|
|
60
|
+
readonly trauma: 0.4;
|
|
61
|
+
readonly timescale: 0.05;
|
|
62
|
+
};
|
|
63
|
+
readonly explosion: {
|
|
64
|
+
readonly hitstopMs: 90;
|
|
65
|
+
readonly trauma: 0.7;
|
|
66
|
+
readonly timescale: 0.05;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/** A named key into {@link impactPresets} (`"pickup" | "jumpLand" | "enemyKilled" | "playerHit" | "explosion"`). */
|
|
70
|
+
export type ImpactPresetName = keyof typeof impactPresets;
|
|
71
|
+
/**
|
|
72
|
+
* Resolves hit feel (hitstop, knockback impulse, camera shake) from either a
|
|
73
|
+
* named `impactPresets` event (`resolveHitReaction("explosion", input)`) or a
|
|
74
|
+
* raw `HitReactionConfig` override.
|
|
75
|
+
*
|
|
76
|
+
* @capability impact-feel resolve hitstop/knockback/shake feel from an impact preset or raw config
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveHitReaction(config: HitReactionConfig | ImpactPresetName, input: HitReactionInput): HitReaction;
|
|
23
79
|
export declare function applyImpulse(position: EntityPosition, impulse: [number, number, number]): EntityPosition;
|
|
@@ -1,18 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calibrated per-event impact feel — hitstop and trauma numbers harvested
|
|
3
|
+
* from a shipped game-feel reference, not hand-invented per game. `explosion`
|
|
4
|
+
* and `playerHit` are "heavy hit" events (60–90ms hitstop @ 0.05 timescale);
|
|
5
|
+
* `pickup`/`jumpLand` are light events with no hitstop. Trauma is later
|
|
6
|
+
* clamped to 1.0 by `resolveHitReaction`.
|
|
7
|
+
*
|
|
8
|
+
* @capability impact-feel calibrated hitstop + trauma preset for a named impact event
|
|
9
|
+
*/
|
|
10
|
+
export const impactPresets = {
|
|
11
|
+
pickup: { hitstopMs: 0, trauma: 0.15 },
|
|
12
|
+
jumpLand: { hitstopMs: 0, trauma: 0.2 },
|
|
13
|
+
enemyKilled: { hitstopMs: 40, trauma: 0.3 },
|
|
14
|
+
playerHit: { hitstopMs: 70, trauma: 0.4, timescale: 0.05 },
|
|
15
|
+
explosion: { hitstopMs: 90, trauma: 0.7, timescale: 0.05 },
|
|
16
|
+
};
|
|
17
|
+
function clamp01(value) {
|
|
18
|
+
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
19
|
+
}
|
|
20
|
+
function configFromPreset(name) {
|
|
21
|
+
const preset = impactPresets[name];
|
|
22
|
+
return {
|
|
23
|
+
hitstopMs: preset.hitstopMs,
|
|
24
|
+
knockback: preset.knockback ?? 0,
|
|
25
|
+
trauma: preset.trauma,
|
|
26
|
+
...(preset.vertical === undefined ? {} : { vertical: preset.vertical }),
|
|
27
|
+
...(preset.timescale === undefined ? {} : { timescale: preset.timescale }),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolves hit feel (hitstop, knockback impulse, camera shake) from either a
|
|
32
|
+
* named `impactPresets` event (`resolveHitReaction("explosion", input)`) or a
|
|
33
|
+
* raw `HitReactionConfig` override.
|
|
34
|
+
*
|
|
35
|
+
* @capability impact-feel resolve hitstop/knockback/shake feel from an impact preset or raw config
|
|
36
|
+
*/
|
|
1
37
|
export function resolveHitReaction(config, input) {
|
|
38
|
+
const resolved = typeof config === "string" ? configFromPreset(config) : config;
|
|
2
39
|
const power = input.power ?? 1;
|
|
3
40
|
const dx = input.targetPos[0] - input.attackerPos[0];
|
|
4
41
|
const dz = input.targetPos[2] - input.attackerPos[2];
|
|
5
42
|
const planar = Math.hypot(dx, dz);
|
|
6
43
|
const nx = planar === 0 ? 0 : dx / planar;
|
|
7
44
|
const nz = planar === 0 ? 0 : dz / planar;
|
|
8
|
-
const magnitude =
|
|
9
|
-
const shake =
|
|
45
|
+
const magnitude = resolved.knockback * power;
|
|
46
|
+
const shake = resolved.shake === undefined
|
|
10
47
|
? null
|
|
11
|
-
: { amplitude:
|
|
48
|
+
: { amplitude: resolved.shake.amplitude * power, decay: resolved.shake.decay };
|
|
49
|
+
const trauma = resolved.trauma === undefined ? null : clamp01(resolved.trauma * power);
|
|
12
50
|
return {
|
|
13
|
-
hitstopMs:
|
|
14
|
-
impulse: [nx * magnitude, (
|
|
51
|
+
hitstopMs: resolved.hitstopMs,
|
|
52
|
+
impulse: [nx * magnitude, (resolved.vertical ?? 0) * power, nz * magnitude],
|
|
15
53
|
shake,
|
|
54
|
+
trauma,
|
|
55
|
+
timescale: resolved.timescale ?? null,
|
|
16
56
|
};
|
|
17
57
|
}
|
|
18
58
|
export function applyImpulse(position, impulse) {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Draws ammo for a `Magazine`'s reload from wherever the reserve pool actually lives. */
|
|
2
|
+
export interface MagazineReserve {
|
|
3
|
+
current(): number;
|
|
4
|
+
spend(amount: number): boolean;
|
|
5
|
+
gain?(amount: number): void;
|
|
6
|
+
}
|
|
7
|
+
/** Tuning for `createMagazine`: mag capacity, reload delay, and where reserve ammo is drawn from. */
|
|
8
|
+
export interface MagazineConfig {
|
|
9
|
+
capacity: number;
|
|
10
|
+
reloadMs: number;
|
|
11
|
+
/** Starting loaded count; defaults to `capacity` (a full mag). */
|
|
12
|
+
loaded?: number;
|
|
13
|
+
/**
|
|
14
|
+
* A plain number seeds a self-contained reserve pool; a `MagazineReserve` bridges reload draws
|
|
15
|
+
* into an externally-owned pool (a shared ammo-type stat, another `ResourcePool`); omitted means
|
|
16
|
+
* an infinite reserve (classic arcade shooter, never locked out of reloading).
|
|
17
|
+
*/
|
|
18
|
+
reserve?: number | MagazineReserve;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A per-weapon magazine: discrete loaded rounds, a timed reload that refills from a reserve pool,
|
|
22
|
+
* and the reserve-pool interaction itself — the primitive that replaces hand-rolling mag size,
|
|
23
|
+
* reload delay, and reserve bookkeeping per game (#536.2).
|
|
24
|
+
*/
|
|
25
|
+
export interface Magazine {
|
|
26
|
+
loaded(): number;
|
|
27
|
+
capacity(): number;
|
|
28
|
+
/** Reserve rounds available to reload from, or `null` when the reserve is infinite. */
|
|
29
|
+
reserve(): number | null;
|
|
30
|
+
isReloading(): boolean;
|
|
31
|
+
/** Reload progress in `[0, 1]`; 0 while idle. */
|
|
32
|
+
reloadFraction(): number;
|
|
33
|
+
isEmpty(): boolean;
|
|
34
|
+
isFull(): boolean;
|
|
35
|
+
canFire(rounds?: number): boolean;
|
|
36
|
+
/** Spend `rounds` (default 1) loaded ammo; returns false without effect when insufficient. */
|
|
37
|
+
fire(rounds?: number): boolean;
|
|
38
|
+
/** True when a reload could start: not already full, not already reloading, reserve has rounds. */
|
|
39
|
+
canReload(): boolean;
|
|
40
|
+
/** Begin the reload timer if `canReload()`; returns whether it started. */
|
|
41
|
+
startReload(): boolean;
|
|
42
|
+
/** Abort an in-progress reload; loaded/reserve are unchanged (only completion moves ammo). */
|
|
43
|
+
cancelReload(): void;
|
|
44
|
+
/** Add `amount` to a self-contained numeric reserve (a pickup); a no-op against an infinite or externally-owned reserve without a `gain`. */
|
|
45
|
+
addReserve(amount: number): void;
|
|
46
|
+
/** Advance the reload timer; completes the reload once `reloadMs` has elapsed. */
|
|
47
|
+
tick(dtSeconds: number): void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Builds a {@link Magazine}: discrete loaded ammo, a timed reload, and reserve-pool interaction.
|
|
51
|
+
*
|
|
52
|
+
* @capability magazine a weapon magazine with capacity, timed reload, and reserve-pool interaction
|
|
53
|
+
*/
|
|
54
|
+
export declare function createMagazine(config: MagazineConfig): Magazine;
|