@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
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A regenerating resource pool — mana, stamina, energy — that actions spend from and that refills over time.
|
|
3
|
+
*
|
|
4
|
+
* @capability resource-pool a regenerating pool like mana or stamina that actions spend from
|
|
5
|
+
*/
|
|
1
6
|
export function createResourcePool(config) {
|
|
2
7
|
let max = Math.max(0, config.max);
|
|
3
8
|
const regenPerSecond = Math.max(0, config.regenPerSecond ?? 0);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One indivisible reward to distribute among participants — an opaque result id (a rolled drop, a
|
|
3
|
+
* currency bundle, a quest token) with an optional stack `count` and free-form `tags` for eligibility
|
|
4
|
+
* and provenance. Allocation never interprets the id; generation (loot tables, roll formulas) owns
|
|
5
|
+
* what it means, keeping the seam genre-agnostic.
|
|
6
|
+
*/
|
|
7
|
+
export interface RewardResult {
|
|
8
|
+
id: string;
|
|
9
|
+
count?: number;
|
|
10
|
+
tags?: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A participant that may receive rewards — an opaque recipient id (player, team, party slot) with an
|
|
14
|
+
* optional split `weight` (shared policy), eligibility `tags`, and an `eligible` gate. Ineligible
|
|
15
|
+
* recipients are excluded before any allocation decision so they never perturb others' streams.
|
|
16
|
+
*/
|
|
17
|
+
export interface RewardRecipient {
|
|
18
|
+
id: string;
|
|
19
|
+
weight?: number;
|
|
20
|
+
tags?: readonly string[];
|
|
21
|
+
eligible?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** The distribution policies allocation ships — each a distinct answer to "who gets this result". */
|
|
24
|
+
export type RewardPolicyKind = "instanced" | "shared" | "copy" | "roundRobin" | "assigned" | "claimed";
|
|
25
|
+
/** A `{ result, count }` slice of a reward — the unit shared pools and grants are expressed in. */
|
|
26
|
+
export interface RewardShare {
|
|
27
|
+
result: string;
|
|
28
|
+
count: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* An authoritative, serializable award of one result stack to one recipient — carries `via` (the
|
|
32
|
+
* policy that produced it) and `private` (replication scope) so provenance and visibility survive
|
|
33
|
+
* save/load and viewer projection. Applying a grant twice with the same identity is the caller's
|
|
34
|
+
* idempotency contract; this seam only decides who is owed what.
|
|
35
|
+
*/
|
|
36
|
+
export interface RewardGrant {
|
|
37
|
+
recipient: string;
|
|
38
|
+
result: string;
|
|
39
|
+
count: number;
|
|
40
|
+
via: RewardPolicyKind;
|
|
41
|
+
private: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A serializable pool of results left open for later claiming — first-come contested drops or a
|
|
45
|
+
* `reservedFor` personal reward. Tracks `eligible` claimants, optional `expiresAtMs`, and the
|
|
46
|
+
* authoritative `claimedBy` winner so reconnect and duplicate-claim attempts resolve idempotently.
|
|
47
|
+
*/
|
|
48
|
+
export interface ClaimablePool {
|
|
49
|
+
id: string;
|
|
50
|
+
via: RewardPolicyKind;
|
|
51
|
+
results: RewardShare[];
|
|
52
|
+
eligible: string[];
|
|
53
|
+
reservedFor: string | null;
|
|
54
|
+
expiresAtMs: number | null;
|
|
55
|
+
claimedBy: string | null;
|
|
56
|
+
}
|
|
57
|
+
/** How a `claimed` allocation exposes its pool: open first-come (`first`) or `reserved` to one recipient. */
|
|
58
|
+
export interface RewardClaimSpec {
|
|
59
|
+
mode: "first" | "reserved";
|
|
60
|
+
reservedFor?: string;
|
|
61
|
+
expiresAtMs?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The inputs one allocation pass consumes. `allocationSeed` governs distribution decisions
|
|
65
|
+
* (ordering, round-robin rotation, remainder splits, reservation) while the separate optional
|
|
66
|
+
* `generationSeed` seeds per-recipient `instanced` generation — keeping join order from perturbing
|
|
67
|
+
* other players' rolls. Provide `results` for pre-rolled policies, `generate` for `instanced`,
|
|
68
|
+
* `assignment` for `assigned`, and `claim` for `claimed`.
|
|
69
|
+
*/
|
|
70
|
+
export interface AllocationRequest {
|
|
71
|
+
recipients: readonly RewardRecipient[];
|
|
72
|
+
allocationSeed: string | number;
|
|
73
|
+
generationSeed?: string | number;
|
|
74
|
+
results?: readonly RewardResult[];
|
|
75
|
+
generate?: (rng: () => number, recipient: RewardRecipient) => readonly RewardResult[];
|
|
76
|
+
assignment?: Record<string, readonly string[]>;
|
|
77
|
+
claim?: RewardClaimSpec;
|
|
78
|
+
nowMs?: number;
|
|
79
|
+
private?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/** The serializable result of an allocation pass — immediate `grants` plus any deferred `pools`. */
|
|
82
|
+
export interface AllocationOutcome {
|
|
83
|
+
grants: RewardGrant[];
|
|
84
|
+
pools: ClaimablePool[];
|
|
85
|
+
}
|
|
86
|
+
/** The outcome of a claim attempt — the updated pool and the grants owed (empty when the claim is refused). */
|
|
87
|
+
export interface ClaimOutcome {
|
|
88
|
+
pool: ClaimablePool;
|
|
89
|
+
grants: RewardGrant[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Allocate reward results among participants under a named policy, returning immediate grants and/or
|
|
93
|
+
* claimable pools. Distribution is deterministic and serializable: the same seeds, recipients, and
|
|
94
|
+
* results yield an identical outcome on host and every peer regardless of join order, so allocation
|
|
95
|
+
* replicates as data without re-rolling. Reward *generation* stays upstream (loot tables, roll
|
|
96
|
+
* formulas); this seam only decides who is owed what.
|
|
97
|
+
*
|
|
98
|
+
* @capability reward-allocation distribute reward results among multiplayer participants deterministically
|
|
99
|
+
*/
|
|
100
|
+
export declare function allocateRewards(kind: RewardPolicyKind, request: AllocationRequest): AllocationOutcome;
|
|
101
|
+
/**
|
|
102
|
+
* Resolve an authoritative claim against a pool. Idempotent: re-claiming an already-owned pool returns
|
|
103
|
+
* the same grants without re-awarding, a losing claimant gets no grants, and eligibility, reservation,
|
|
104
|
+
* and expiry are all enforced here — the authority, not UI hiding, decides ownership. Returns the
|
|
105
|
+
* updated (serializable) pool plus the grants owed.
|
|
106
|
+
*
|
|
107
|
+
* @capability reward-allocation resolve idempotent authoritative claims against a reward pool
|
|
108
|
+
*/
|
|
109
|
+
export declare function resolveClaim(pool: ClaimablePool, claimantId: string, options?: {
|
|
110
|
+
nowMs?: number;
|
|
111
|
+
private?: boolean;
|
|
112
|
+
}): ClaimOutcome;
|
|
113
|
+
/**
|
|
114
|
+
* Project an allocation outcome for one viewer, enforcing replication authoritatively: private grants
|
|
115
|
+
* belonging to other recipients are dropped, and pools the viewer cannot claim (not eligible, or
|
|
116
|
+
* reserved for someone else) are hidden — so private rewards never leak across the wire while
|
|
117
|
+
* provenance on the viewer's own grants is preserved.
|
|
118
|
+
*
|
|
119
|
+
* @capability reward-allocation filter reward grants and pools to a viewer so private rewards never leak
|
|
120
|
+
*/
|
|
121
|
+
export declare function filterOutcomeFor(outcome: AllocationOutcome, viewerId: string): AllocationOutcome;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { hashString, seededStreams } from "../random/rng.js";
|
|
2
|
+
function countOf(result) {
|
|
3
|
+
const n = result.count ?? 1;
|
|
4
|
+
return Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;
|
|
5
|
+
}
|
|
6
|
+
/** Eligible recipients in a deterministic, seed-shuffled order independent of input array order. */
|
|
7
|
+
function orderedEligible(request) {
|
|
8
|
+
const eligible = request.recipients.filter((r) => r.eligible !== false);
|
|
9
|
+
const seed = String(request.allocationSeed);
|
|
10
|
+
return [...eligible].sort((a, b) => {
|
|
11
|
+
const ka = hashString(`${seed}:order:${a.id}`);
|
|
12
|
+
const kb = hashString(`${seed}:order:${b.id}`);
|
|
13
|
+
if (ka !== kb)
|
|
14
|
+
return ka - kb;
|
|
15
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function requireResults(request, kind) {
|
|
19
|
+
if (request.results === undefined) {
|
|
20
|
+
throw new Error(`reward policy "${kind}" requires results`);
|
|
21
|
+
}
|
|
22
|
+
return request.results;
|
|
23
|
+
}
|
|
24
|
+
function grant(recipient, result, count, via, isPrivate) {
|
|
25
|
+
return { recipient, result, count, via, private: isPrivate };
|
|
26
|
+
}
|
|
27
|
+
/** Per-recipient independent generation: each eligible recipient rolls its own results from a stable stream. */
|
|
28
|
+
function allocateInstanced(request) {
|
|
29
|
+
if (request.generate === undefined) {
|
|
30
|
+
throw new Error('reward policy "instanced" requires a generate function');
|
|
31
|
+
}
|
|
32
|
+
const streams = seededStreams(request.generationSeed ?? request.allocationSeed);
|
|
33
|
+
const isPrivate = request.private ?? true;
|
|
34
|
+
const grants = [];
|
|
35
|
+
for (const recipient of orderedEligible(request)) {
|
|
36
|
+
const rng = streams(`gen:${recipient.id}`);
|
|
37
|
+
for (const result of request.generate(rng, recipient)) {
|
|
38
|
+
const count = countOf(result);
|
|
39
|
+
if (count > 0)
|
|
40
|
+
grants.push(grant(recipient.id, result.id, count, "instanced", isPrivate));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { grants, pools: [] };
|
|
44
|
+
}
|
|
45
|
+
/** Copy-to-all: every eligible recipient receives a full copy of every result. */
|
|
46
|
+
function allocateCopy(request) {
|
|
47
|
+
const results = requireResults(request, "copy");
|
|
48
|
+
const isPrivate = request.private ?? false;
|
|
49
|
+
const grants = [];
|
|
50
|
+
for (const recipient of orderedEligible(request)) {
|
|
51
|
+
for (const result of results) {
|
|
52
|
+
const count = countOf(result);
|
|
53
|
+
if (count > 0)
|
|
54
|
+
grants.push(grant(recipient.id, result.id, count, "copy", isPrivate));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { grants, pools: [] };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Shared pool: each result's count is split across eligible recipients by `weight` using the
|
|
61
|
+
* largest-remainder method, so the units always sum back to the original count with a deterministic,
|
|
62
|
+
* fair remainder distribution.
|
|
63
|
+
*/
|
|
64
|
+
function allocateShared(request) {
|
|
65
|
+
const results = requireResults(request, "shared");
|
|
66
|
+
const recipients = orderedEligible(request);
|
|
67
|
+
const isPrivate = request.private ?? false;
|
|
68
|
+
const grants = [];
|
|
69
|
+
if (recipients.length === 0)
|
|
70
|
+
return { grants, pools: [] };
|
|
71
|
+
const weights = recipients.map((r) => (r.weight !== undefined && r.weight > 0 ? r.weight : 1));
|
|
72
|
+
const totalWeight = weights.reduce((sum, w) => sum + w, 0);
|
|
73
|
+
for (const result of results) {
|
|
74
|
+
const total = countOf(result);
|
|
75
|
+
if (total === 0)
|
|
76
|
+
continue;
|
|
77
|
+
const exact = weights.map((w) => (total * w) / totalWeight);
|
|
78
|
+
const base = exact.map((x) => Math.floor(x));
|
|
79
|
+
let remaining = total - base.reduce((sum, n) => sum + n, 0);
|
|
80
|
+
const byRemainder = recipients
|
|
81
|
+
.map((_, i) => i)
|
|
82
|
+
.sort((a, b) => {
|
|
83
|
+
const fa = exact[a] - base[a];
|
|
84
|
+
const fb = exact[b] - base[b];
|
|
85
|
+
if (fb !== fa)
|
|
86
|
+
return fb - fa;
|
|
87
|
+
return a - b; // canonical order tie-break
|
|
88
|
+
});
|
|
89
|
+
for (const i of byRemainder) {
|
|
90
|
+
if (remaining <= 0)
|
|
91
|
+
break;
|
|
92
|
+
base[i] += 1;
|
|
93
|
+
remaining -= 1;
|
|
94
|
+
}
|
|
95
|
+
recipients.forEach((recipient, i) => {
|
|
96
|
+
if (base[i] > 0)
|
|
97
|
+
grants.push(grant(recipient.id, result.id, base[i], "shared", isPrivate));
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return { grants, pools: [] };
|
|
101
|
+
}
|
|
102
|
+
/** Round-robin: results are handed out one at a time across recipients in deterministic rotation order. */
|
|
103
|
+
function allocateRoundRobin(request) {
|
|
104
|
+
const results = requireResults(request, "roundRobin");
|
|
105
|
+
const recipients = orderedEligible(request);
|
|
106
|
+
const isPrivate = request.private ?? false;
|
|
107
|
+
const grants = [];
|
|
108
|
+
if (recipients.length === 0)
|
|
109
|
+
return { grants, pools: [] };
|
|
110
|
+
results.forEach((result, index) => {
|
|
111
|
+
const count = countOf(result);
|
|
112
|
+
if (count === 0)
|
|
113
|
+
return;
|
|
114
|
+
const recipient = recipients[index % recipients.length];
|
|
115
|
+
grants.push(grant(recipient.id, result.id, count, "roundRobin", isPrivate));
|
|
116
|
+
});
|
|
117
|
+
return { grants, pools: [] };
|
|
118
|
+
}
|
|
119
|
+
/** Caller-defined assignment: each recipient receives exactly the result ids the `assignment` map names. */
|
|
120
|
+
function allocateAssigned(request) {
|
|
121
|
+
const results = requireResults(request, "assigned");
|
|
122
|
+
if (request.assignment === undefined) {
|
|
123
|
+
throw new Error('reward policy "assigned" requires an assignment map');
|
|
124
|
+
}
|
|
125
|
+
const byId = new Map(results.map((r) => [r.id, r]));
|
|
126
|
+
const eligibleIds = new Set(orderedEligible(request).map((r) => r.id));
|
|
127
|
+
const isPrivate = request.private ?? false;
|
|
128
|
+
const grants = [];
|
|
129
|
+
for (const recipient of orderedEligible(request)) {
|
|
130
|
+
const assigned = request.assignment[recipient.id] ?? [];
|
|
131
|
+
for (const resultId of assigned) {
|
|
132
|
+
const result = byId.get(resultId);
|
|
133
|
+
if (result === undefined)
|
|
134
|
+
throw new Error(`assignment references unknown result "${resultId}"`);
|
|
135
|
+
if (!eligibleIds.has(recipient.id))
|
|
136
|
+
continue;
|
|
137
|
+
const count = countOf(result);
|
|
138
|
+
if (count > 0)
|
|
139
|
+
grants.push(grant(recipient.id, result.id, count, "assigned", isPrivate));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { grants, pools: [] };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Claimed: results are pooled for later claiming rather than granted now. `first` mode leaves an open
|
|
146
|
+
* contested pool; `reserved` mode ties the pool to one recipient — the caller-named `reservedFor` or,
|
|
147
|
+
* absent that, a deterministically seed-picked eligible recipient.
|
|
148
|
+
*/
|
|
149
|
+
function allocateClaimed(request) {
|
|
150
|
+
const results = requireResults(request, "claimed");
|
|
151
|
+
const spec = request.claim ?? { mode: "first" };
|
|
152
|
+
const recipients = orderedEligible(request);
|
|
153
|
+
const shares = [];
|
|
154
|
+
for (const result of results) {
|
|
155
|
+
const count = countOf(result);
|
|
156
|
+
if (count > 0)
|
|
157
|
+
shares.push({ result: result.id, count });
|
|
158
|
+
}
|
|
159
|
+
let reservedFor = null;
|
|
160
|
+
if (spec.mode === "reserved") {
|
|
161
|
+
if (spec.reservedFor !== undefined) {
|
|
162
|
+
reservedFor = spec.reservedFor;
|
|
163
|
+
}
|
|
164
|
+
else if (recipients.length > 0) {
|
|
165
|
+
const pick = seededStreams(request.allocationSeed)("claim:reserve")();
|
|
166
|
+
reservedFor = recipients[Math.min(recipients.length - 1, Math.floor(pick * recipients.length))].id;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const pool = {
|
|
170
|
+
id: `pool:${hashString(`${request.allocationSeed}:claim`).toString(36)}`,
|
|
171
|
+
via: "claimed",
|
|
172
|
+
results: shares,
|
|
173
|
+
eligible: recipients.map((r) => r.id),
|
|
174
|
+
reservedFor,
|
|
175
|
+
expiresAtMs: spec.expiresAtMs ?? null,
|
|
176
|
+
claimedBy: null,
|
|
177
|
+
};
|
|
178
|
+
return { grants: [], pools: [pool] };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Allocate reward results among participants under a named policy, returning immediate grants and/or
|
|
182
|
+
* claimable pools. Distribution is deterministic and serializable: the same seeds, recipients, and
|
|
183
|
+
* results yield an identical outcome on host and every peer regardless of join order, so allocation
|
|
184
|
+
* replicates as data without re-rolling. Reward *generation* stays upstream (loot tables, roll
|
|
185
|
+
* formulas); this seam only decides who is owed what.
|
|
186
|
+
*
|
|
187
|
+
* @capability reward-allocation distribute reward results among multiplayer participants deterministically
|
|
188
|
+
*/
|
|
189
|
+
export function allocateRewards(kind, request) {
|
|
190
|
+
switch (kind) {
|
|
191
|
+
case "instanced":
|
|
192
|
+
return allocateInstanced(request);
|
|
193
|
+
case "copy":
|
|
194
|
+
return allocateCopy(request);
|
|
195
|
+
case "shared":
|
|
196
|
+
return allocateShared(request);
|
|
197
|
+
case "roundRobin":
|
|
198
|
+
return allocateRoundRobin(request);
|
|
199
|
+
case "assigned":
|
|
200
|
+
return allocateAssigned(request);
|
|
201
|
+
case "claimed":
|
|
202
|
+
return allocateClaimed(request);
|
|
203
|
+
default: {
|
|
204
|
+
const exhaustive = kind;
|
|
205
|
+
throw new Error(`unknown reward policy: ${String(exhaustive)}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function poolClaimable(pool, claimantId, nowMs) {
|
|
210
|
+
if (!pool.eligible.includes(claimantId))
|
|
211
|
+
return false;
|
|
212
|
+
if (pool.reservedFor !== null && pool.reservedFor !== claimantId)
|
|
213
|
+
return false;
|
|
214
|
+
if (pool.expiresAtMs !== null && nowMs !== undefined && nowMs > pool.expiresAtMs)
|
|
215
|
+
return false;
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Resolve an authoritative claim against a pool. Idempotent: re-claiming an already-owned pool returns
|
|
220
|
+
* the same grants without re-awarding, a losing claimant gets no grants, and eligibility, reservation,
|
|
221
|
+
* and expiry are all enforced here — the authority, not UI hiding, decides ownership. Returns the
|
|
222
|
+
* updated (serializable) pool plus the grants owed.
|
|
223
|
+
*
|
|
224
|
+
* @capability reward-allocation resolve idempotent authoritative claims against a reward pool
|
|
225
|
+
*/
|
|
226
|
+
export function resolveClaim(pool, claimantId, options) {
|
|
227
|
+
const nowMs = options?.nowMs;
|
|
228
|
+
const grantsFor = (owner) => pool.results.map((share) => grant(owner, share.result, share.count, "claimed", options?.private ?? false));
|
|
229
|
+
if (pool.claimedBy !== null) {
|
|
230
|
+
return { pool, grants: pool.claimedBy === claimantId ? grantsFor(claimantId) : [] };
|
|
231
|
+
}
|
|
232
|
+
if (!poolClaimable(pool, claimantId, nowMs)) {
|
|
233
|
+
return { pool, grants: [] };
|
|
234
|
+
}
|
|
235
|
+
const claimed = { ...pool, claimedBy: claimantId };
|
|
236
|
+
return { pool: claimed, grants: grantsFor(claimantId) };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Project an allocation outcome for one viewer, enforcing replication authoritatively: private grants
|
|
240
|
+
* belonging to other recipients are dropped, and pools the viewer cannot claim (not eligible, or
|
|
241
|
+
* reserved for someone else) are hidden — so private rewards never leak across the wire while
|
|
242
|
+
* provenance on the viewer's own grants is preserved.
|
|
243
|
+
*
|
|
244
|
+
* @capability reward-allocation filter reward grants and pools to a viewer so private rewards never leak
|
|
245
|
+
*/
|
|
246
|
+
export function filterOutcomeFor(outcome, viewerId) {
|
|
247
|
+
return {
|
|
248
|
+
grants: outcome.grants.filter((g) => !g.private || g.recipient === viewerId),
|
|
249
|
+
pools: outcome.pools.filter((p) => p.eligible.includes(viewerId) && (p.reservedFor === null || p.reservedFor === viewerId)),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
import type { EntityPosition } from "../scene/entityStore.js";
|
|
2
|
+
import { type EntityColliderSet } from "../scene/colliders.js";
|
|
2
3
|
import type { Aim } from "../scene/spatial.js";
|
|
3
4
|
/**
|
|
4
5
|
* How a shot's world-space origin (and optional direction) is resolved before prediction/settlement.
|
|
5
|
-
* - `
|
|
6
|
+
* - `converge` — the shot leaves the gun `muzzle` yet still passes through whatever the shooter's
|
|
7
|
+
* sightline (crosshair) covers: origin is the muzzle offset, direction is bent from the muzzle to
|
|
8
|
+
* the eye ray's aim point. The projectile system's default for a free `{ yaw, pitch }` aim, so a
|
|
9
|
+
* bullet visibly comes from the barrel without missing the reticle. Needs a scene raycast to find
|
|
10
|
+
* the aim point (`convergeShot`); a bare `resolveShot` degrades to a straight muzzle ray. Passes an
|
|
11
|
+
* explicit `{ origin, direction }` aim through untouched.
|
|
12
|
+
* - `eye` — `aim.origin` when present, else the shooter's entity position raised to eye height; the
|
|
13
|
+
* shot traces the shooter's sightline, so what the crosshair covers is what gets hit.
|
|
14
|
+
* - `legacy` — `aim.origin` when present, else the shooter's raw entity position (feet).
|
|
6
15
|
* - `entity` — always the shooter's entity position.
|
|
7
16
|
* - `entityOffset` / `muzzle` — entity-local offset rotated by the shooter's yaw (muzzle on a weapon model).
|
|
8
17
|
* - `camera` — explicit camera/reticle world origin (and optional direction override).
|
|
9
18
|
* - `world` — absolute world origin.
|
|
10
19
|
*/
|
|
11
20
|
export type ShotOriginPolicy = {
|
|
21
|
+
kind: "converge";
|
|
22
|
+
muzzle?: EntityPosition;
|
|
23
|
+
height?: number;
|
|
24
|
+
} | {
|
|
25
|
+
kind: "eye";
|
|
26
|
+
height?: number;
|
|
27
|
+
} | {
|
|
12
28
|
kind: "legacy";
|
|
13
29
|
} | {
|
|
14
30
|
kind: "entity";
|
|
@@ -34,7 +50,20 @@ export interface ResolvedShot {
|
|
|
34
50
|
export interface ShotOriginDeps {
|
|
35
51
|
positionOf(instanceId: string): EntityPosition | undefined;
|
|
36
52
|
rotationYOf?(instanceId: string): number | undefined;
|
|
53
|
+
/** When provided, the `eye` policy sizes its height from the shooter's own hitbox instead of the humanoid default. */
|
|
54
|
+
collidersOf?(instanceId: string): EntityColliderSet | null | undefined;
|
|
37
55
|
}
|
|
56
|
+
/** Shot-origin and first-person camera eye height above an entity's position: 90% of the default 1.8m hitbox top. */
|
|
57
|
+
export declare const DEFAULT_EYE_HEIGHT: number;
|
|
58
|
+
/** Eye height derived from a collider set: 90% of the tallest hitbox top, or the humanoid default when unknown. */
|
|
59
|
+
export declare function eyeHeightFromColliders(set: EntityColliderSet | null | undefined): number;
|
|
38
60
|
export declare function aimDirection(aim: Aim): EntityPosition | null;
|
|
39
61
|
export declare function aimSpreadDeg(aim: Aim): number;
|
|
40
62
|
export declare function resolveShot(deps: ShotOriginDeps, from: string, aim: Aim, policy?: ShotOriginPolicy): ResolvedShot | null;
|
|
63
|
+
/**
|
|
64
|
+
* Resolves a `converge` shot with scene knowledge: fires from the gun muzzle but bends the direction
|
|
65
|
+
* so the shot passes through the aim point the shooter's eye ray covers. `sightHit` casts the eye ray
|
|
66
|
+
* and returns where it lands (first impact), or `null` to fall back to a point `range` metres down the
|
|
67
|
+
* sightline. A `{ origin, direction }` aim is passed through unchanged (nothing to converge).
|
|
68
|
+
*/
|
|
69
|
+
export declare function convergeShot(deps: ShotOriginDeps, from: string, aim: Aim, range: number, sightHit: (origin: EntityPosition, direction: EntityPosition) => EntityPosition | null, muzzleOffset?: EntityPosition): ResolvedShot | null;
|
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
import { worldOffset } from "../scene/colliders.js";
|
|
1
|
+
import { resolveColliders, worldOffset } from "../scene/colliders.js";
|
|
2
2
|
const DEFAULT_MUZZLE_OFFSET = [0, 1.4, 0.35];
|
|
3
|
+
const EYE_HEIGHT_RATIO = 0.9;
|
|
4
|
+
/** Shot-origin and first-person camera eye height above an entity's position: 90% of the default 1.8m hitbox top. */
|
|
5
|
+
export const DEFAULT_EYE_HEIGHT = EYE_HEIGHT_RATIO * 1.8;
|
|
6
|
+
/** Eye height derived from a collider set: 90% of the tallest hitbox top, or the humanoid default when unknown. */
|
|
7
|
+
export function eyeHeightFromColliders(set) {
|
|
8
|
+
const colliders = resolveColliders(set);
|
|
9
|
+
let top = 0;
|
|
10
|
+
for (const collider of colliders) {
|
|
11
|
+
const offsetY = collider.shape.offset?.[1] ?? 0;
|
|
12
|
+
const halfHeight = collider.shape.kind === "sphere" ? collider.shape.radius : collider.shape.halfExtents[1];
|
|
13
|
+
top = Math.max(top, offsetY + halfHeight);
|
|
14
|
+
}
|
|
15
|
+
return top > 0 ? top * EYE_HEIGHT_RATIO : DEFAULT_EYE_HEIGHT;
|
|
16
|
+
}
|
|
3
17
|
function normalize(vector) {
|
|
4
18
|
const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
|
|
5
19
|
if (length === 0)
|
|
@@ -15,11 +29,37 @@ export function aimDirection(aim) {
|
|
|
15
29
|
export function aimSpreadDeg(aim) {
|
|
16
30
|
return "origin" in aim ? 0 : aim.spread ?? 0;
|
|
17
31
|
}
|
|
18
|
-
export function resolveShot(deps, from, aim, policy = { kind: "
|
|
32
|
+
export function resolveShot(deps, from, aim, policy = { kind: "eye" }) {
|
|
19
33
|
const aimDir = aimDirection(aim);
|
|
20
34
|
if (aimDir === null && policy.kind !== "camera" && policy.kind !== "world")
|
|
21
35
|
return null;
|
|
22
36
|
switch (policy.kind) {
|
|
37
|
+
case "converge": {
|
|
38
|
+
if ("origin" in aim) {
|
|
39
|
+
if (aimDir === null)
|
|
40
|
+
return null;
|
|
41
|
+
return { origin: aim.origin, direction: aimDir };
|
|
42
|
+
}
|
|
43
|
+
if (aimDir === null)
|
|
44
|
+
return null;
|
|
45
|
+
const muzzle = resolveShot(deps, from, aim, { kind: "muzzle", offset: policy.muzzle });
|
|
46
|
+
return muzzle ?? null;
|
|
47
|
+
}
|
|
48
|
+
case "eye": {
|
|
49
|
+
if ("origin" in aim) {
|
|
50
|
+
if (aimDir === null)
|
|
51
|
+
return null;
|
|
52
|
+
return { origin: aim.origin, direction: aimDir };
|
|
53
|
+
}
|
|
54
|
+
const position = deps.positionOf(from);
|
|
55
|
+
if (position === undefined || aimDir === null)
|
|
56
|
+
return null;
|
|
57
|
+
const height = policy.height ??
|
|
58
|
+
(deps.collidersOf !== undefined
|
|
59
|
+
? eyeHeightFromColliders(deps.collidersOf(from))
|
|
60
|
+
: DEFAULT_EYE_HEIGHT);
|
|
61
|
+
return { origin: [position[0], position[1] + height, position[2]], direction: aimDir };
|
|
62
|
+
}
|
|
23
63
|
case "legacy": {
|
|
24
64
|
const origin = "origin" in aim ? aim.origin : deps.positionOf(from);
|
|
25
65
|
if (origin === undefined || aimDir === null)
|
|
@@ -55,3 +95,31 @@ export function resolveShot(deps, from, aim, policy = { kind: "legacy" }) {
|
|
|
55
95
|
}
|
|
56
96
|
}
|
|
57
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolves a `converge` shot with scene knowledge: fires from the gun muzzle but bends the direction
|
|
100
|
+
* so the shot passes through the aim point the shooter's eye ray covers. `sightHit` casts the eye ray
|
|
101
|
+
* and returns where it lands (first impact), or `null` to fall back to a point `range` metres down the
|
|
102
|
+
* sightline. A `{ origin, direction }` aim is passed through unchanged (nothing to converge).
|
|
103
|
+
*/
|
|
104
|
+
export function convergeShot(deps, from, aim, range, sightHit, muzzleOffset) {
|
|
105
|
+
const sight = resolveShot(deps, from, aim, { kind: "eye", height: undefined });
|
|
106
|
+
if (sight === null)
|
|
107
|
+
return null;
|
|
108
|
+
if ("origin" in aim)
|
|
109
|
+
return sight;
|
|
110
|
+
const muzzle = resolveShot(deps, from, aim, { kind: "muzzle", offset: muzzleOffset });
|
|
111
|
+
if (muzzle === null)
|
|
112
|
+
return sight;
|
|
113
|
+
const aimPoint = sightHit(sight.origin, sight.direction) ??
|
|
114
|
+
[
|
|
115
|
+
sight.origin[0] + sight.direction[0] * range,
|
|
116
|
+
sight.origin[1] + sight.direction[1] * range,
|
|
117
|
+
sight.origin[2] + sight.direction[2] * range,
|
|
118
|
+
];
|
|
119
|
+
const direction = normalize([
|
|
120
|
+
aimPoint[0] - muzzle.origin[0],
|
|
121
|
+
aimPoint[1] - muzzle.origin[1],
|
|
122
|
+
aimPoint[2] - muzzle.origin[2],
|
|
123
|
+
]);
|
|
124
|
+
return { origin: muzzle.origin, direction: direction ?? muzzle.direction };
|
|
125
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a fresh application behaves when the target already carries the status.
|
|
3
|
+
* - `refresh` — reset duration, hold the existing stack count.
|
|
4
|
+
* - `stack` — add `add` stacks (default 1) up to `max`, and refresh duration.
|
|
5
|
+
* - `replace` — overwrite duration and magnitude, stacks reset to 1.
|
|
6
|
+
* - `ignore` — leave the existing instance untouched (first application wins).
|
|
7
|
+
*/
|
|
8
|
+
export type StatusStackPolicy = {
|
|
9
|
+
kind: "refresh";
|
|
10
|
+
} | {
|
|
11
|
+
kind: "stack";
|
|
12
|
+
max?: number;
|
|
13
|
+
add?: number;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "replace";
|
|
16
|
+
} | {
|
|
17
|
+
kind: "ignore";
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* A serializable, effect-agnostic description of a status a hit tries to apply: an opaque
|
|
21
|
+
* `status` id the game routes to its own effect/DoT pipeline, a base landing `chance`, and the
|
|
22
|
+
* duration/ticks/magnitude/attribution/stacking data the resolver needs. The engine never
|
|
23
|
+
* interprets `status` — it is a reference, not a built-in condition.
|
|
24
|
+
*/
|
|
25
|
+
export interface StatusApplicationSpec {
|
|
26
|
+
/** Opaque status/effect id the game applies (`"burn"`, `"slow"`, `"amplify"`). */
|
|
27
|
+
status: string;
|
|
28
|
+
/** Base landing probability in `[0,1]` before matchup scaling; defaults to 1 (always). */
|
|
29
|
+
chance?: number;
|
|
30
|
+
/** Base duration in milliseconds. */
|
|
31
|
+
durationMs?: number;
|
|
32
|
+
/** Base number of periodic ticks, when the status is periodic. */
|
|
33
|
+
ticks?: number;
|
|
34
|
+
/** Base per-application magnitude (damage/heal per tick, buff strength). */
|
|
35
|
+
magnitude?: number;
|
|
36
|
+
/** Behaviour when the target already carries this status; defaults to `refresh`. */
|
|
37
|
+
stack?: StatusStackPolicy;
|
|
38
|
+
}
|
|
39
|
+
/** A live status carried by a target — the serializable, replicable state a status application mutates. */
|
|
40
|
+
export interface StatusInstance {
|
|
41
|
+
status: string;
|
|
42
|
+
/** Current stack count (>= 1 while active). */
|
|
43
|
+
stacks: number;
|
|
44
|
+
/** Milliseconds of life remaining. */
|
|
45
|
+
remainingMs: number;
|
|
46
|
+
/** Remaining periodic ticks, when tracked. */
|
|
47
|
+
ticks: number;
|
|
48
|
+
/** Per-application magnitude in force. */
|
|
49
|
+
magnitude: number;
|
|
50
|
+
/** Attribution: who/what applied (or last refreshed) the status. */
|
|
51
|
+
source?: string;
|
|
52
|
+
}
|
|
53
|
+
/** Statuses a target cannot receive at all — the immunity half of application policy. */
|
|
54
|
+
export interface StatusImmunity {
|
|
55
|
+
statuses?: readonly string[];
|
|
56
|
+
}
|
|
57
|
+
/** Matchup-derived multipliers on the independent application axes. Each defaults to 1. */
|
|
58
|
+
export interface StatusApplicationScale {
|
|
59
|
+
applyChance?: number;
|
|
60
|
+
magnitude?: number;
|
|
61
|
+
duration?: number;
|
|
62
|
+
}
|
|
63
|
+
/** Everything `resolveStatusApplication` needs; all data plus an injected RNG for reproducibility. */
|
|
64
|
+
export interface StatusApplicationInput {
|
|
65
|
+
spec: StatusApplicationSpec;
|
|
66
|
+
/** Independent multipliers (typically from `resolveMatchup`). */
|
|
67
|
+
scale?: StatusApplicationScale;
|
|
68
|
+
/** The target's existing instance of this status, or `null`/absent when unafflicted. */
|
|
69
|
+
current?: StatusInstance | null;
|
|
70
|
+
immunity?: StatusImmunity | null;
|
|
71
|
+
/** Attribution written onto the resulting instance. */
|
|
72
|
+
source?: string;
|
|
73
|
+
/** Deterministic RNG returning `[0,1)`; defaults to `Math.random`. Pass a seeded stream for reproducibility. */
|
|
74
|
+
rng?: () => number;
|
|
75
|
+
}
|
|
76
|
+
/** Why an application did or did not take, plus the roll for provenance. */
|
|
77
|
+
export type StatusApplicationOutcomeKind = "applied" | "refreshed" | "stacked" | "replaced" | "immune" | "missed" | "ignored";
|
|
78
|
+
/** The result of one status application: the outcome, the resulting instance (if any), and the roll. */
|
|
79
|
+
export interface StatusApplicationOutcome {
|
|
80
|
+
kind: StatusApplicationOutcomeKind;
|
|
81
|
+
/** The instance after application, or `null` when the status did not land / was blocked. */
|
|
82
|
+
instance: StatusInstance | null;
|
|
83
|
+
/** Effective landing chance after scaling, clamped to `[0,1]`. */
|
|
84
|
+
chance: number;
|
|
85
|
+
/** The RNG draw compared against `chance`; `null` when no roll was taken (immune/ignored). */
|
|
86
|
+
roll: number | null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resolve one status application: reject on immunity, roll landing chance against injected RNG,
|
|
90
|
+
* scale magnitude/duration by the matchup, then fold into any existing instance per the stacking
|
|
91
|
+
* policy. Deterministic given a seeded `rng`; pure over serializable data, so authority can run it
|
|
92
|
+
* and replicate only the returned `instance`.
|
|
93
|
+
*
|
|
94
|
+
* @capability status-application resolve a data-defined status application with chance, matchup scaling, and stacking policy
|
|
95
|
+
*/
|
|
96
|
+
export declare function resolveStatusApplication(input: StatusApplicationInput): StatusApplicationOutcome;
|