@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,118 @@
|
|
|
1
|
+
import { hashString } from "../random/rng.js";
|
|
2
|
+
/**
|
|
3
|
+
* A deterministic `[0,1)` cadence phase derived from a stable id, for staggering sibling gates so a
|
|
4
|
+
* batch of agents spawned together does not fire their first active tick on the same frame. Pass the
|
|
5
|
+
* result as the `phase` argument to {@link createInterestGateState}.
|
|
6
|
+
*
|
|
7
|
+
* @capability interest-stagger deterministic per-id cadence phase that spreads sibling gate ticks across frames
|
|
8
|
+
*/
|
|
9
|
+
export function interestPhase(seed) {
|
|
10
|
+
const hashed = typeof seed === "number" ? hashString(String(seed)) : hashString(seed);
|
|
11
|
+
return (hashed % 100000) / 100000;
|
|
12
|
+
}
|
|
13
|
+
function nominalInterval(config) {
|
|
14
|
+
return config.activeInterval ?? config.tiers?.[0]?.interval ?? 0;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a dormant gate state, staggered by `phase` (`[0,1)`, typically {@link interestPhase} of the
|
|
18
|
+
* agent id) so siblings created together do not all fire their first active tick on the same frame.
|
|
19
|
+
*
|
|
20
|
+
* @capability interest-gate per-agent sleep/wake + cadence gate state so far agents skip expensive ticks
|
|
21
|
+
*/
|
|
22
|
+
export function createInterestGateState(config, phase = 0) {
|
|
23
|
+
const clamped = phase - Math.floor(phase);
|
|
24
|
+
return {
|
|
25
|
+
state: "dormant",
|
|
26
|
+
clock: clamped * nominalInterval(config),
|
|
27
|
+
awakeHold: 0,
|
|
28
|
+
phase: clamped,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function intervalFor(config, proximity) {
|
|
32
|
+
if (config.tiers !== undefined && proximity !== null) {
|
|
33
|
+
for (const tier of config.tiers) {
|
|
34
|
+
if (proximity <= tier.within)
|
|
35
|
+
return Math.max(0, tier.interval);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return Math.max(0, config.activeInterval ?? 0);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Advance one gate by `dt` seconds against this tick's `input`, mutating `state` in place and
|
|
42
|
+
* returning what the caller should do. Sleeping skips the expensive work (`active: false`) while the
|
|
43
|
+
* gate's timers keep advancing, so state is preserved; a `wake` signal or crossing `wakeRadius`
|
|
44
|
+
* flips it back to active and fires an immediate tick.
|
|
45
|
+
*
|
|
46
|
+
* @capability interest-scheduler advance a sleep/wake gate with hysteresis, cadence tiers, and stagger
|
|
47
|
+
*/
|
|
48
|
+
export function advanceInterestGate(state, config, dt, input = {}) {
|
|
49
|
+
const wakeRadius = config.wakeRadius;
|
|
50
|
+
const sleepRadius = Math.max(config.sleepRadius ?? wakeRadius, wakeRadius);
|
|
51
|
+
const proximity = input.proximity ?? null;
|
|
52
|
+
const prev = state.state;
|
|
53
|
+
if (input.wake === true) {
|
|
54
|
+
state.awakeHold = Math.max(state.awakeHold, config.stayAwakeSeconds ?? 0);
|
|
55
|
+
}
|
|
56
|
+
let want;
|
|
57
|
+
if (input.wake === true || state.awakeHold > 0) {
|
|
58
|
+
want = "active";
|
|
59
|
+
}
|
|
60
|
+
else if (proximity === null) {
|
|
61
|
+
want = prev;
|
|
62
|
+
}
|
|
63
|
+
else if (prev === "dormant") {
|
|
64
|
+
want = proximity <= wakeRadius ? "active" : "dormant";
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
want = proximity > sleepRadius ? "dormant" : "active";
|
|
68
|
+
}
|
|
69
|
+
state.state = want;
|
|
70
|
+
const woke = prev === "dormant" && want === "active";
|
|
71
|
+
const slept = prev === "active" && want === "dormant";
|
|
72
|
+
let active = false;
|
|
73
|
+
if (want === "active") {
|
|
74
|
+
const interval = intervalFor(config, proximity);
|
|
75
|
+
if (interval <= 0 || woke || input.wake === true) {
|
|
76
|
+
active = true;
|
|
77
|
+
state.clock = 0;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
state.clock += dt;
|
|
81
|
+
if (state.clock >= interval) {
|
|
82
|
+
active = true;
|
|
83
|
+
state.clock -= interval;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Dormant: expensive work is skipped, but the gate keeps its timers so a later wake resumes cleanly.
|
|
89
|
+
state.clock = 0;
|
|
90
|
+
}
|
|
91
|
+
if (state.awakeHold > 0)
|
|
92
|
+
state.awakeHold = Math.max(0, state.awakeHold - dt);
|
|
93
|
+
return { state: want, active, woke, slept };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create a census accumulator so the caller can tally active/dormant gates during the loop it already
|
|
97
|
+
* runs, avoiding any separate full-world scan just to report scheduler metrics.
|
|
98
|
+
*
|
|
99
|
+
* @capability interest-census running active/dormant gate tally folded into the caller's tick loop
|
|
100
|
+
*/
|
|
101
|
+
export function createInterestCensus() {
|
|
102
|
+
let active = 0;
|
|
103
|
+
let dormant = 0;
|
|
104
|
+
return {
|
|
105
|
+
record(state) {
|
|
106
|
+
const value = typeof state === "string" ? state : state.state;
|
|
107
|
+
if (value === "active")
|
|
108
|
+
active += 1;
|
|
109
|
+
else
|
|
110
|
+
dormant += 1;
|
|
111
|
+
},
|
|
112
|
+
snapshot: () => ({ active, dormant, total: active + dormant }),
|
|
113
|
+
reset() {
|
|
114
|
+
active = 0;
|
|
115
|
+
dormant = 0;
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
package/dist/ai/jobBoard.d.ts
CHANGED
package/dist/ai/jobBoard.js
CHANGED
package/dist/ai/laneSelect.d.ts
CHANGED
|
@@ -15,7 +15,10 @@ export interface PickLaneOptions<TId extends string = string> {
|
|
|
15
15
|
* Live cost-based selection over parallel corridors (#286.7) — the racing-line / lane-merge pick
|
|
16
16
|
* every AI driver hand-rolled. Evaluate each lane's cost this tick (crowding, hazards, distance)
|
|
17
17
|
* and let stickiness hysteresis stop the agent flip-flopping between near-equal lanes.
|
|
18
|
-
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
19
20
|
export declare function pickLane<TId extends string>(candidates: readonly LaneCandidate<TId>[], options?: PickLaneOptions<TId>): TId | null;
|
|
20
|
-
/** Sum a live cost function over a corridor's sample points — the standard way to build `LaneCandidate.cost`.
|
|
21
|
+
/** Sum a live cost function over a corridor's sample points — the standard way to build `LaneCandidate.cost`.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
21
24
|
export declare function corridorCost(points: readonly (readonly [number, number])[], costAt: (x: number, z: number) => number): number;
|
package/dist/ai/laneSelect.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Live cost-based selection over parallel corridors (#286.7) — the racing-line / lane-merge pick
|
|
3
3
|
* every AI driver hand-rolled. Evaluate each lane's cost this tick (crowding, hazards, distance)
|
|
4
4
|
* and let stickiness hysteresis stop the agent flip-flopping between near-equal lanes.
|
|
5
|
-
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
6
7
|
export function pickLane(candidates, options = {}) {
|
|
7
8
|
if (candidates.length === 0)
|
|
8
9
|
return null;
|
|
@@ -28,7 +29,9 @@ export function pickLane(candidates, options = {}) {
|
|
|
28
29
|
}
|
|
29
30
|
return best.id;
|
|
30
31
|
}
|
|
31
|
-
/** Sum a live cost function over a corridor's sample points — the standard way to build `LaneCandidate.cost`.
|
|
32
|
+
/** Sum a live cost function over a corridor's sample points — the standard way to build `LaneCandidate.cost`.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
32
35
|
export function corridorCost(points, costAt) {
|
|
33
36
|
let total = 0;
|
|
34
37
|
for (const [x, z] of points)
|
package/dist/ai/mobBrain.d.ts
CHANGED
package/dist/ai/mobBrain.js
CHANGED
|
@@ -9,6 +9,7 @@ const HOLD = {
|
|
|
9
9
|
function distance(a, b) {
|
|
10
10
|
return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
|
|
11
11
|
}
|
|
12
|
+
/** @internal */
|
|
12
13
|
export function createMobBrain(config, deps) {
|
|
13
14
|
const threat = createThreatTable(config.threat);
|
|
14
15
|
const stickiness = config.stickiness ?? 1.15;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NavPoint } from "../nav/navGrid.js";
|
|
2
|
+
import { type RandomSeed } from "../random/rng.js";
|
|
2
3
|
export interface SpawnEntry {
|
|
3
4
|
id: string;
|
|
4
5
|
cost: number;
|
|
@@ -32,7 +33,8 @@ export interface SpawnDirectorState {
|
|
|
32
33
|
alert: number;
|
|
33
34
|
spawnedThisWave: number;
|
|
34
35
|
spawnedTotal: number;
|
|
35
|
-
|
|
36
|
+
/** Opaque PRNG cursor — round-trip it as part of the state, never read or set it directly. */
|
|
37
|
+
rng: RandomSeed;
|
|
36
38
|
done: boolean;
|
|
37
39
|
}
|
|
38
40
|
export interface DirectorContext {
|
|
@@ -47,6 +49,19 @@ export interface SpawnRequest {
|
|
|
47
49
|
point?: NavPoint;
|
|
48
50
|
laneId?: number;
|
|
49
51
|
}
|
|
52
|
+
/** Preference for picking a spawn point relative to `avoid` positions: closer, farther, or unweighted. */
|
|
53
|
+
export type SpawnPointDistanceBias = "near" | "far" | "none";
|
|
54
|
+
/** How strongly `distanceBias` weights candidates by distance from `avoid` — a named intent, not a weighting exponent. */
|
|
55
|
+
export type SpawnPointBiasStrength = "subtle" | "moderate" | "strong";
|
|
56
|
+
/** Semantic options for selecting a spawn point without exposing weighting internals. */
|
|
57
|
+
export interface SpawnPointSelectionOptions {
|
|
58
|
+
candidates: readonly NavPoint[];
|
|
59
|
+
avoid?: readonly NavPoint[];
|
|
60
|
+
random: () => number;
|
|
61
|
+
distanceBias?: SpawnPointDistanceBias;
|
|
62
|
+
/** Default `"moderate"`. */
|
|
63
|
+
biasStrength?: SpawnPointBiasStrength;
|
|
64
|
+
}
|
|
50
65
|
export interface DirectorStep {
|
|
51
66
|
state: SpawnDirectorState;
|
|
52
67
|
spawns: SpawnRequest[];
|
|
@@ -55,6 +70,9 @@ export declare function createSpawnDirectorState(config: SpawnDirectorConfig): S
|
|
|
55
70
|
export declare function raiseAlert(state: SpawnDirectorState, amount: number): SpawnDirectorState;
|
|
56
71
|
export declare function advanceWave(config: SpawnDirectorConfig, state: SpawnDirectorState): SpawnDirectorState;
|
|
57
72
|
export declare function advanceSpawnDirector(config: SpawnDirectorConfig, state: SpawnDirectorState, dt: number, ctx: DirectorContext): DirectorStep;
|
|
73
|
+
/** Selects a candidate spawn point using a semantic distance preference and caller-supplied randomness. */
|
|
74
|
+
export declare function pickSpawnPoint(options: SpawnPointSelectionOptions): NavPoint | null;
|
|
75
|
+
/** @deprecated Pass one SpawnPointSelectionOptions object instead. */
|
|
58
76
|
export declare function pickSpawnPoint(points: readonly NavPoint[], players: readonly NavPoint[], options: {
|
|
59
77
|
roll: number;
|
|
60
78
|
bias?: number;
|
package/dist/ai/spawnDirector.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import { randomSeedFrom, stepRandomSeed } from "../random/rng.js";
|
|
2
|
+
const BIAS_STRENGTH_EXPONENT = {
|
|
3
|
+
subtle: 0.5,
|
|
4
|
+
moderate: 1,
|
|
5
|
+
strong: 2,
|
|
6
|
+
};
|
|
7
|
+
function biasStrengthFromMagnitude(magnitude) {
|
|
8
|
+
return magnitude <= 0.5 ? "subtle" : magnitude >= 1.5 ? "strong" : "moderate";
|
|
9
|
+
}
|
|
1
10
|
const DEFAULT_MAX_SPAWNS_PER_TICK = 64;
|
|
2
11
|
const DEFAULT_ALERT_DECAY = 0.1;
|
|
3
|
-
function nextRandom(seed) {
|
|
4
|
-
const next = (seed + 0x6d2b79f5) | 0;
|
|
5
|
-
let t = Math.imul(next ^ (next >>> 15), 1 | next);
|
|
6
|
-
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
7
|
-
const value = ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
8
|
-
return [value, next];
|
|
9
|
-
}
|
|
10
12
|
function clamp01(value) {
|
|
11
13
|
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
12
14
|
}
|
|
@@ -20,7 +22,7 @@ export function createSpawnDirectorState(config) {
|
|
|
20
22
|
alert: 0,
|
|
21
23
|
spawnedThisWave: 0,
|
|
22
24
|
spawnedTotal: 0,
|
|
23
|
-
rng: (config.seed ?? 1)
|
|
25
|
+
rng: randomSeedFrom(config.seed ?? 1),
|
|
24
26
|
done: config.waves.length === 0,
|
|
25
27
|
};
|
|
26
28
|
}
|
|
@@ -56,7 +58,7 @@ function pickEntry(entries, wave, budget, rng) {
|
|
|
56
58
|
}
|
|
57
59
|
if (affordable.length === 0 || total <= 0)
|
|
58
60
|
return null;
|
|
59
|
-
const [roll, nextRng] =
|
|
61
|
+
const [roll, nextRng] = stepRandomSeed(rng);
|
|
60
62
|
let cursor = roll * total;
|
|
61
63
|
for (const entry of affordable) {
|
|
62
64
|
cursor -= entry.weight ?? 1;
|
|
@@ -116,9 +118,16 @@ export function advanceSpawnDirector(config, state, dt, ctx) {
|
|
|
116
118
|
budget -= picked.entry.cost;
|
|
117
119
|
const spawn = { entryId: picked.entry.id, cost: picked.entry.cost, wave };
|
|
118
120
|
if (spawnPoints !== undefined && spawnPoints.length > 0) {
|
|
119
|
-
const [roll, nextRng] =
|
|
121
|
+
const [roll, nextRng] = stepRandomSeed(rng);
|
|
120
122
|
rng = nextRng;
|
|
121
|
-
const
|
|
123
|
+
const bias = config.spawnPointBias ?? 1;
|
|
124
|
+
const point = pickSpawnPoint({
|
|
125
|
+
candidates: spawnPoints,
|
|
126
|
+
avoid: playerPositions,
|
|
127
|
+
random: () => roll,
|
|
128
|
+
distanceBias: bias < 0 ? "far" : bias > 0 ? "near" : "none",
|
|
129
|
+
biasStrength: biasStrengthFromMagnitude(Math.abs(bias)),
|
|
130
|
+
});
|
|
122
131
|
if (point !== null) {
|
|
123
132
|
spawn.point = point;
|
|
124
133
|
spawn.laneId = spawnPoints.indexOf(point);
|
|
@@ -134,29 +143,47 @@ export function advanceSpawnDirector(config, state, dt, ctx) {
|
|
|
134
143
|
spawns,
|
|
135
144
|
};
|
|
136
145
|
}
|
|
137
|
-
export function pickSpawnPoint(
|
|
138
|
-
|
|
146
|
+
export function pickSpawnPoint(optionsOrPoints, legacyPlayers = [], legacyOptions = { roll: 0 }) {
|
|
147
|
+
let options;
|
|
148
|
+
if (Array.isArray(optionsOrPoints)) {
|
|
149
|
+
const legacyBias = legacyOptions.bias ?? 1;
|
|
150
|
+
options = {
|
|
151
|
+
candidates: optionsOrPoints,
|
|
152
|
+
avoid: legacyPlayers,
|
|
153
|
+
random: () => legacyOptions.roll,
|
|
154
|
+
distanceBias: legacyBias < 0 ? "far" : legacyBias > 0 ? "near" : "none",
|
|
155
|
+
biasStrength: biasStrengthFromMagnitude(Math.abs(legacyBias)),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
options = optionsOrPoints;
|
|
160
|
+
}
|
|
161
|
+
const { candidates, avoid = [], random, distanceBias = "near", biasStrength = "moderate" } = options;
|
|
162
|
+
if (candidates.length === 0)
|
|
139
163
|
return null;
|
|
140
|
-
|
|
164
|
+
if (distanceBias === "none" || avoid.length === 0) {
|
|
165
|
+
return candidates[Math.min(candidates.length - 1, Math.floor(clamp01(random()) * candidates.length))];
|
|
166
|
+
}
|
|
167
|
+
const strength = BIAS_STRENGTH_EXPONENT[biasStrength];
|
|
168
|
+
const exponent = distanceBias === "far" ? strength : -strength;
|
|
141
169
|
const weights = [];
|
|
142
170
|
let total = 0;
|
|
143
|
-
for (const point of
|
|
171
|
+
for (const point of candidates) {
|
|
144
172
|
let nearest = Number.POSITIVE_INFINITY;
|
|
145
|
-
for (const
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
148
|
-
nearest =
|
|
173
|
+
for (const avoidedPoint of avoid) {
|
|
174
|
+
const distance = Math.hypot(point[0] - avoidedPoint[0], point[1] - avoidedPoint[1]);
|
|
175
|
+
if (distance < nearest)
|
|
176
|
+
nearest = distance;
|
|
149
177
|
}
|
|
150
|
-
const
|
|
151
|
-
const weight = Math.max(1e-6, (1 + distance) ** -bias);
|
|
178
|
+
const weight = Math.max(1e-6, (1 + nearest) ** exponent);
|
|
152
179
|
weights.push(weight);
|
|
153
180
|
total += weight;
|
|
154
181
|
}
|
|
155
|
-
let cursor = clamp01(
|
|
156
|
-
for (let
|
|
157
|
-
cursor -= weights[
|
|
182
|
+
let cursor = clamp01(random()) * total;
|
|
183
|
+
for (let index = 0; index < candidates.length; index += 1) {
|
|
184
|
+
cursor -= weights[index];
|
|
158
185
|
if (cursor <= 0)
|
|
159
|
-
return
|
|
186
|
+
return candidates[index];
|
|
160
187
|
}
|
|
161
|
-
return
|
|
188
|
+
return candidates[candidates.length - 1];
|
|
162
189
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NavPoint } from "../nav/navGrid.js";
|
|
2
|
+
import { type SpawnPointDistanceBias, type SpawnPointSelectionOptions } from "./spawnDirector.js";
|
|
3
|
+
export type { SpawnPointDistanceBias, SpawnPointSelectionOptions };
|
|
4
|
+
/** Selects a spawn point by game intent while keeping weighting mechanics internal.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare function selectSpawnPoint(options: SpawnPointSelectionOptions): NavPoint | null;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable target acquisition: the "which enemy do I lock onto?" decision split into the
|
|
3
|
+
* independent concerns every aggro system tangles together — a bounded candidate provider, an
|
|
4
|
+
* eligibility filter, a per-pair acquisition envelope (dynamic range), a perception/LOS gate,
|
|
5
|
+
* scoring, deterministic tie-break, and retention hysteresis. This owns *policy*; threat, brains,
|
|
6
|
+
* and movement stay separate. Feed `candidates` a spatial-index query, never a full-world scan.
|
|
7
|
+
*/
|
|
8
|
+
/** A per-pair acquisition range: a static radius, or a function that varies range by pair. */
|
|
9
|
+
export type AcquisitionEnvelope = number | ((selfId: string, candidateId: string) => number);
|
|
10
|
+
/** Retention hysteresis that keeps an already-held target from flickering under churn. */
|
|
11
|
+
export interface AcquisitionRetention {
|
|
12
|
+
/**
|
|
13
|
+
* A challenger's score must beat the held target's by at least this additive margin to steal
|
|
14
|
+
* acquisition. Keeps the lock stable when scores are near-tied. Default `0` (any win switches).
|
|
15
|
+
*/
|
|
16
|
+
readonly switchMargin?: number;
|
|
17
|
+
/**
|
|
18
|
+
* The held target keeps acquisition out to `range * dropRangeScale` before it is dropped, so a
|
|
19
|
+
* target does not un-acquire the instant it steps past the acquisition edge. Default `1`.
|
|
20
|
+
*/
|
|
21
|
+
readonly dropRangeScale?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A fully composed acquisition policy. Every concern is an independent, injectable seam; the only
|
|
25
|
+
* required pieces are the bounded `candidates` provider and the `distance` metric. Omit the rest to
|
|
26
|
+
* fall back to the thin default — a static/unbounded range, everything eligible and perceptible,
|
|
27
|
+
* nearest-wins scoring, id tie-break, no hysteresis — which matches a plain proximity aggro radius.
|
|
28
|
+
*/
|
|
29
|
+
export interface AcquisitionPolicy {
|
|
30
|
+
/** Bounded candidate ids for `selfId` — wire a spatial-index query here, not a whole-world list. */
|
|
31
|
+
readonly candidates: (selfId: string) => Iterable<string>;
|
|
32
|
+
/** Distance self→candidate; `null` rejects the candidate (despawned / unmeasurable). */
|
|
33
|
+
readonly distance: (selfId: string, candidateId: string) => number | null;
|
|
34
|
+
/** Per-pair acquisition range (the dynamic envelope). Default `Infinity` (range-unbounded). */
|
|
35
|
+
readonly range?: AcquisitionEnvelope;
|
|
36
|
+
/** Eligibility filter run first — faction, alive, targetable, stealth, ownership. Default: all pass. */
|
|
37
|
+
readonly eligible?: (selfId: string, candidateId: string) => boolean;
|
|
38
|
+
/** Perception / line-of-sight gate run last (after range) because it is the costly check. */
|
|
39
|
+
readonly perceptible?: (selfId: string, candidateId: string, distance: number) => boolean;
|
|
40
|
+
/** Score of an in-range candidate; the highest wins. Default: nearest (`-distance`). */
|
|
41
|
+
readonly score?: (selfId: string, candidateId: string, distance: number) => number;
|
|
42
|
+
/** Deterministic tie-break when scores are equal (return <0 to prefer `a`). Default: id order. */
|
|
43
|
+
readonly tieBreak?: (a: string, b: string) => number;
|
|
44
|
+
/** Retention/hysteresis for an already-held target. Omit for no stickiness. */
|
|
45
|
+
readonly retention?: AcquisitionRetention;
|
|
46
|
+
}
|
|
47
|
+
/** Outcome of one acquisition pass. */
|
|
48
|
+
export interface AcquisitionResult {
|
|
49
|
+
/** The chosen target, or `null` when nothing qualifies. */
|
|
50
|
+
readonly targetId: string | null;
|
|
51
|
+
/** True when `targetId` differs from the `held` target passed in (a fresh acquire or a switch). */
|
|
52
|
+
readonly changed: boolean;
|
|
53
|
+
/** Candidates that passed eligibility + range + perception this pass — a cheap tuning/metric signal. */
|
|
54
|
+
readonly considered: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Run one acquisition pass and pick the best target under `policy`. Pass the currently `held` target
|
|
58
|
+
* so retention hysteresis (`switchMargin`, `dropRangeScale`) can keep the lock stable; pass `null`
|
|
59
|
+
* for a cold acquire. Pure and allocation-light — the caller owns the held-target state.
|
|
60
|
+
*
|
|
61
|
+
* @capability target-acquisition composable candidate/eligibility/range/perception/score/tie-break/retention target pick
|
|
62
|
+
*/
|
|
63
|
+
export declare function acquireTarget(policy: AcquisitionPolicy, selfId: string, held?: string | null): AcquisitionResult;
|
|
64
|
+
/** A stateful acquirer that holds the current target across passes — sugar over {@link acquireTarget}. */
|
|
65
|
+
export interface TargetAcquirer {
|
|
66
|
+
/** Re-run acquisition for `selfId`, update the held target, and return it. */
|
|
67
|
+
acquire(selfId: string): string | null;
|
|
68
|
+
/** The held target without re-running acquisition. */
|
|
69
|
+
target(): string | null;
|
|
70
|
+
/** Candidates considered on the last {@link acquire} pass. */
|
|
71
|
+
considered(): number;
|
|
72
|
+
/** Force the held target — external override for taunt, script, or ownership handoff. */
|
|
73
|
+
hold(targetId: string | null): void;
|
|
74
|
+
/** Drop back to unacquired. */
|
|
75
|
+
clear(): void;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Wrap an {@link AcquisitionPolicy} in a small object that remembers the held target between passes,
|
|
79
|
+
* so callers get retention hysteresis for free without threading the previous target by hand. The
|
|
80
|
+
* only state is the held id (a string) — trivially serializable; round-trip it with {@link TargetAcquirer.hold}.
|
|
81
|
+
*
|
|
82
|
+
* @capability target-acquirer stateful held-target wrapper over an acquisition policy with retention
|
|
83
|
+
*/
|
|
84
|
+
export declare function createTargetAcquirer(policy: AcquisitionPolicy): TargetAcquirer;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable target acquisition: the "which enemy do I lock onto?" decision split into the
|
|
3
|
+
* independent concerns every aggro system tangles together — a bounded candidate provider, an
|
|
4
|
+
* eligibility filter, a per-pair acquisition envelope (dynamic range), a perception/LOS gate,
|
|
5
|
+
* scoring, deterministic tie-break, and retention hysteresis. This owns *policy*; threat, brains,
|
|
6
|
+
* and movement stay separate. Feed `candidates` a spatial-index query, never a full-world scan.
|
|
7
|
+
*/
|
|
8
|
+
function resolveRange(range, selfId, candidateId) {
|
|
9
|
+
if (range === undefined)
|
|
10
|
+
return Number.POSITIVE_INFINITY;
|
|
11
|
+
return typeof range === "number" ? range : range(selfId, candidateId);
|
|
12
|
+
}
|
|
13
|
+
function defaultTieBreak(a, b) {
|
|
14
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Run one acquisition pass and pick the best target under `policy`. Pass the currently `held` target
|
|
18
|
+
* so retention hysteresis (`switchMargin`, `dropRangeScale`) can keep the lock stable; pass `null`
|
|
19
|
+
* for a cold acquire. Pure and allocation-light — the caller owns the held-target state.
|
|
20
|
+
*
|
|
21
|
+
* @capability target-acquisition composable candidate/eligibility/range/perception/score/tie-break/retention target pick
|
|
22
|
+
*/
|
|
23
|
+
export function acquireTarget(policy, selfId, held = null) {
|
|
24
|
+
const tieBreak = policy.tieBreak ?? defaultTieBreak;
|
|
25
|
+
const dropScale = Math.max(0, policy.retention?.dropRangeScale ?? 1);
|
|
26
|
+
const switchMargin = policy.retention?.switchMargin ?? 0;
|
|
27
|
+
let considered = 0;
|
|
28
|
+
let bestId = null;
|
|
29
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
30
|
+
let heldSeen = false;
|
|
31
|
+
let heldScore = Number.NEGATIVE_INFINITY;
|
|
32
|
+
for (const candidateId of policy.candidates(selfId)) {
|
|
33
|
+
if (candidateId === selfId)
|
|
34
|
+
continue;
|
|
35
|
+
if (policy.eligible !== undefined && !policy.eligible(selfId, candidateId))
|
|
36
|
+
continue;
|
|
37
|
+
const d = policy.distance(selfId, candidateId);
|
|
38
|
+
if (d === null)
|
|
39
|
+
continue;
|
|
40
|
+
const range = resolveRange(policy.range, selfId, candidateId);
|
|
41
|
+
const effectiveRange = candidateId === held ? range * dropScale : range;
|
|
42
|
+
if (d > effectiveRange)
|
|
43
|
+
continue;
|
|
44
|
+
if (policy.perceptible !== undefined && !policy.perceptible(selfId, candidateId, d))
|
|
45
|
+
continue;
|
|
46
|
+
considered += 1;
|
|
47
|
+
const score = policy.score === undefined ? -d : policy.score(selfId, candidateId, d);
|
|
48
|
+
if (candidateId === held) {
|
|
49
|
+
heldSeen = true;
|
|
50
|
+
heldScore = score;
|
|
51
|
+
}
|
|
52
|
+
if (bestId === null ||
|
|
53
|
+
score > bestScore ||
|
|
54
|
+
(score === bestScore && tieBreak(candidateId, bestId) < 0)) {
|
|
55
|
+
bestId = candidateId;
|
|
56
|
+
bestScore = score;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Retention: an in-range held target keeps the lock unless a challenger clears the switch margin.
|
|
60
|
+
if (heldSeen && held !== null && bestId !== held && bestScore < heldScore + switchMargin) {
|
|
61
|
+
return { targetId: held, changed: false, considered };
|
|
62
|
+
}
|
|
63
|
+
return { targetId: bestId, changed: bestId !== held, considered };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Wrap an {@link AcquisitionPolicy} in a small object that remembers the held target between passes,
|
|
67
|
+
* so callers get retention hysteresis for free without threading the previous target by hand. The
|
|
68
|
+
* only state is the held id (a string) — trivially serializable; round-trip it with {@link TargetAcquirer.hold}.
|
|
69
|
+
*
|
|
70
|
+
* @capability target-acquirer stateful held-target wrapper over an acquisition policy with retention
|
|
71
|
+
*/
|
|
72
|
+
export function createTargetAcquirer(policy) {
|
|
73
|
+
let held = null;
|
|
74
|
+
let considered = 0;
|
|
75
|
+
return {
|
|
76
|
+
acquire(selfId) {
|
|
77
|
+
const result = acquireTarget(policy, selfId, held);
|
|
78
|
+
held = result.targetId;
|
|
79
|
+
considered = result.considered;
|
|
80
|
+
return held;
|
|
81
|
+
},
|
|
82
|
+
target: () => held,
|
|
83
|
+
considered: () => considered,
|
|
84
|
+
hold(targetId) {
|
|
85
|
+
held = targetId;
|
|
86
|
+
},
|
|
87
|
+
clear() {
|
|
88
|
+
held = null;
|
|
89
|
+
considered = 0;
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
package/dist/anim/easing.d.ts
CHANGED
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
export type Easing = (t: number) => number;
|
|
2
|
+
/** Linearly interpolate from `from` to `to` by fraction `t` (unclamped).
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
2
5
|
export declare function lerp(from: number, to: number, t: number): number;
|
|
6
|
+
/** Constrain `t` to the unit range `[0, 1]`.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
3
9
|
export declare function clamp01(t: number): number;
|
|
10
|
+
/** Smooth Hermite interpolation of `t` across `[0, 1]`, easing both ends.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
4
13
|
export declare function smoothstep(t: number): number;
|
|
14
|
+
/** @internal */
|
|
5
15
|
export declare function easeInQuad(t: number): number;
|
|
16
|
+
/** @internal */
|
|
6
17
|
export declare function easeOutQuad(t: number): number;
|
|
18
|
+
/** @internal */
|
|
7
19
|
export declare function easeInOutQuad(t: number): number;
|
|
20
|
+
/** @internal */
|
|
8
21
|
export declare function easeInCubic(t: number): number;
|
|
22
|
+
/** @internal */
|
|
9
23
|
export declare function easeOutCubic(t: number): number;
|
|
24
|
+
/** @internal */
|
|
10
25
|
export declare function easeInOutCubic(t: number): number;
|
|
26
|
+
/** @internal */
|
|
11
27
|
export declare function easeOutBack(t: number): number;
|
|
28
|
+
/** @internal */
|
|
12
29
|
export declare function easeOutElastic(t: number): number;
|
|
30
|
+
/** @internal */
|
|
13
31
|
export declare function tween(from: number, to: number, t: number, easing?: Easing): number;
|
|
32
|
+
/** @internal */
|
|
14
33
|
export declare function timedProgress(startedAt: number, now: number, durationMs: number): number;
|
package/dist/anim/easing.js
CHANGED
|
@@ -1,53 +1,72 @@
|
|
|
1
|
+
/** Linearly interpolate from `from` to `to` by fraction `t` (unclamped).
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
1
4
|
export function lerp(from, to, t) {
|
|
2
5
|
return from + (to - from) * t;
|
|
3
6
|
}
|
|
7
|
+
/** Constrain `t` to the unit range `[0, 1]`.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
4
10
|
export function clamp01(t) {
|
|
5
11
|
return t < 0 ? 0 : t > 1 ? 1 : t;
|
|
6
12
|
}
|
|
13
|
+
/** Smooth Hermite interpolation of `t` across `[0, 1]`, easing both ends.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
7
16
|
export function smoothstep(t) {
|
|
8
17
|
const c = clamp01(t);
|
|
9
18
|
return c * c * (3 - 2 * c);
|
|
10
19
|
}
|
|
20
|
+
/** @internal */
|
|
11
21
|
export function easeInQuad(t) {
|
|
12
22
|
const c = clamp01(t);
|
|
13
23
|
return c * c;
|
|
14
24
|
}
|
|
25
|
+
/** @internal */
|
|
15
26
|
export function easeOutQuad(t) {
|
|
16
27
|
const c = clamp01(t);
|
|
17
28
|
return 1 - (1 - c) * (1 - c);
|
|
18
29
|
}
|
|
30
|
+
/** @internal */
|
|
19
31
|
export function easeInOutQuad(t) {
|
|
20
32
|
const c = clamp01(t);
|
|
21
33
|
return c < 0.5 ? 2 * c * c : 1 - ((-2 * c + 2) ** 2) / 2;
|
|
22
34
|
}
|
|
35
|
+
/** @internal */
|
|
23
36
|
export function easeInCubic(t) {
|
|
24
37
|
const c = clamp01(t);
|
|
25
38
|
return c * c * c;
|
|
26
39
|
}
|
|
40
|
+
/** @internal */
|
|
27
41
|
export function easeOutCubic(t) {
|
|
28
42
|
const c = clamp01(t);
|
|
29
43
|
return 1 - (1 - c) ** 3;
|
|
30
44
|
}
|
|
45
|
+
/** @internal */
|
|
31
46
|
export function easeInOutCubic(t) {
|
|
32
47
|
const c = clamp01(t);
|
|
33
48
|
return c < 0.5 ? 4 * c * c * c : 1 - ((-2 * c + 2) ** 3) / 2;
|
|
34
49
|
}
|
|
35
50
|
const BACK_OVERSHOOT = 1.70158;
|
|
51
|
+
/** @internal */
|
|
36
52
|
export function easeOutBack(t) {
|
|
37
53
|
const c = clamp01(t);
|
|
38
54
|
const s = BACK_OVERSHOOT + 1;
|
|
39
55
|
return 1 + s * (c - 1) ** 3 + BACK_OVERSHOOT * (c - 1) ** 2;
|
|
40
56
|
}
|
|
41
57
|
const ELASTIC_PERIOD = (2 * Math.PI) / 3;
|
|
58
|
+
/** @internal */
|
|
42
59
|
export function easeOutElastic(t) {
|
|
43
60
|
const c = clamp01(t);
|
|
44
61
|
if (c === 0 || c === 1)
|
|
45
62
|
return c;
|
|
46
63
|
return 2 ** (-10 * c) * Math.sin((c * 10 - 0.75) * ELASTIC_PERIOD) + 1;
|
|
47
64
|
}
|
|
65
|
+
/** @internal */
|
|
48
66
|
export function tween(from, to, t, easing = smoothstep) {
|
|
49
67
|
return lerp(from, to, easing(clamp01(t)));
|
|
50
68
|
}
|
|
69
|
+
/** @internal */
|
|
51
70
|
export function timedProgress(startedAt, now, durationMs) {
|
|
52
71
|
if (durationMs <= 0)
|
|
53
72
|
return now >= startedAt ? 1 : 0;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Sawtooth ramp: rises 0→1 over each `period` then resets, for looping sweeps and scrolls.
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
4
|
+
export declare function sawWave(time: number, period: number): number;
|
|
5
|
+
/** Triangle wave: ramps 0→1→0 across each `period`, for patrols, searchlights, and pulsing glows.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare function triangleWave(time: number, period: number): number;
|
|
9
|
+
/** Ping-pong a value across `[0, length]`, bouncing at each edge — the index/position analog of {@link triangleWave}.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function pingPong(value: number, length: number): number;
|