@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,312 @@
|
|
|
1
|
+
import { defaultKeyValueStorage } from "./keyValueStore.js";
|
|
2
|
+
function readSafe(storage, key) {
|
|
3
|
+
if (storage === null)
|
|
4
|
+
return null;
|
|
5
|
+
try {
|
|
6
|
+
return storage.getItem(key);
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A {@link SaveBackend} over a synchronous {@link KeyValueStorage} — the
|
|
14
|
+
* browser's `localStorage` by default (offline, on-device saves), a test stub,
|
|
15
|
+
* or `null` for memory-only. Storage errors (quota exceeded, private mode, no
|
|
16
|
+
* DOM) degrade to no-ops, so a save never throws into a game tick.
|
|
17
|
+
*
|
|
18
|
+
* @capability local-save persist a game to on-device localStorage (offline)
|
|
19
|
+
*/
|
|
20
|
+
export function localSaveBackend(storage) {
|
|
21
|
+
const store = storage === undefined ? defaultKeyValueStorage() : storage;
|
|
22
|
+
return {
|
|
23
|
+
read: (key) => Promise.resolve(readSafe(store, key)),
|
|
24
|
+
write: (key, value) => {
|
|
25
|
+
if (store !== null) {
|
|
26
|
+
try {
|
|
27
|
+
store.setItem(key, value);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// storage rejected the write; the store keeps the value in memory
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
},
|
|
35
|
+
remove: (key) => {
|
|
36
|
+
if (store !== null) {
|
|
37
|
+
try {
|
|
38
|
+
store.removeItem(key);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// ignore removal failure
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return Promise.resolve();
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** A memory-only {@link SaveBackend} — saves survive a reload only within the same session. For tests, SSR, or a "no persistence" mode that still exercises the same save code path. */
|
|
49
|
+
export function memorySaveBackend() {
|
|
50
|
+
const map = new Map();
|
|
51
|
+
return {
|
|
52
|
+
read: (key) => Promise.resolve(map.get(key) ?? null),
|
|
53
|
+
write: (key, value) => {
|
|
54
|
+
map.set(key, value);
|
|
55
|
+
return Promise.resolve();
|
|
56
|
+
},
|
|
57
|
+
remove: (key) => {
|
|
58
|
+
map.delete(key);
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Adopt any async `read`/`write`/`remove` trio as a {@link SaveBackend} — the seam for cloud saves backed by a database, an HTTP endpoint, or Convex (see `@jgengine/convex/convexSaveBackend`). Reads/writes may reject; the save store surfaces the failure as `"error"` status instead of throwing. */
|
|
64
|
+
export function remoteSaveBackend(backend) {
|
|
65
|
+
return backend;
|
|
66
|
+
}
|
|
67
|
+
function defaultTimers() {
|
|
68
|
+
return {
|
|
69
|
+
set: (handler, ms) => globalThis.setTimeout(handler, ms),
|
|
70
|
+
clear: (handle) => globalThis.clearTimeout(handle),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function normalizeAuto(config) {
|
|
74
|
+
if (config === undefined || config === false)
|
|
75
|
+
return null;
|
|
76
|
+
if (config === true)
|
|
77
|
+
return { debounceMs: 1000, maxWaitMs: 15000 };
|
|
78
|
+
return { debounceMs: config.debounceMs ?? 1000, maxWaitMs: config.maxWaitMs ?? 15000 };
|
|
79
|
+
}
|
|
80
|
+
function isEnvelope(value) {
|
|
81
|
+
return (typeof value === "object" &&
|
|
82
|
+
value !== null &&
|
|
83
|
+
typeof value.version === "number" &&
|
|
84
|
+
"value" in value);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Create a {@link SaveStore}. Same call for offline and cloud — only the
|
|
88
|
+
* `backend` differs (localStorage, memory, or an async DB/Convex endpoint). Turn
|
|
89
|
+
* on `autosave` and every `set`/`patch` persists on a debounce; leave it off and
|
|
90
|
+
* call `save()` at checkpoints. Bump `version` + pass `migrate` when the save
|
|
91
|
+
* shape changes so old players keep their progress.
|
|
92
|
+
*
|
|
93
|
+
* @capability game-save save/load game state with a pluggable backend, autosave, slots, and migration
|
|
94
|
+
*/
|
|
95
|
+
export function createSaveStore(config) {
|
|
96
|
+
const namespace = config.key ?? "save";
|
|
97
|
+
const formatVersion = config.version ?? 1;
|
|
98
|
+
const initial = config.initial;
|
|
99
|
+
const backend = config.backend;
|
|
100
|
+
const clock = config.now ?? (() => Date.now());
|
|
101
|
+
const timers = config.timers ?? defaultTimers();
|
|
102
|
+
const auto = normalizeAuto(config.autosave);
|
|
103
|
+
const serialize = config.serialize ?? ((envelope) => JSON.stringify(envelope));
|
|
104
|
+
const deserialize = config.deserialize ?? ((raw) => JSON.parse(raw));
|
|
105
|
+
const onError = config.onError;
|
|
106
|
+
let currentSlot = config.slot ?? "default";
|
|
107
|
+
let current = initial;
|
|
108
|
+
let status = "idle";
|
|
109
|
+
let revision = 0;
|
|
110
|
+
let dirty = false;
|
|
111
|
+
let firstDirtyAt = null;
|
|
112
|
+
let pendingTimer = null;
|
|
113
|
+
let saveChain = Promise.resolve();
|
|
114
|
+
let disposed = false;
|
|
115
|
+
const listeners = new Set();
|
|
116
|
+
function emit() {
|
|
117
|
+
revision += 1;
|
|
118
|
+
for (const listener of listeners)
|
|
119
|
+
listener();
|
|
120
|
+
}
|
|
121
|
+
function setStatus(next) {
|
|
122
|
+
if (status === next)
|
|
123
|
+
return;
|
|
124
|
+
status = next;
|
|
125
|
+
emit();
|
|
126
|
+
}
|
|
127
|
+
function reportError(error) {
|
|
128
|
+
onError?.(error);
|
|
129
|
+
}
|
|
130
|
+
const dataKey = (slot) => `${namespace}:${slot}`;
|
|
131
|
+
const indexKey = () => `${namespace}:__slots__`;
|
|
132
|
+
function decode(raw) {
|
|
133
|
+
const parsed = deserialize(raw);
|
|
134
|
+
if (isEnvelope(parsed)) {
|
|
135
|
+
if (parsed.version === formatVersion)
|
|
136
|
+
return parsed.value;
|
|
137
|
+
if (config.migrate)
|
|
138
|
+
return config.migrate(parsed.value, parsed.version);
|
|
139
|
+
return parsed.value;
|
|
140
|
+
}
|
|
141
|
+
if (config.migrate)
|
|
142
|
+
return config.migrate(parsed, 0);
|
|
143
|
+
return parsed;
|
|
144
|
+
}
|
|
145
|
+
async function readSlots() {
|
|
146
|
+
try {
|
|
147
|
+
const raw = await backend.read(indexKey());
|
|
148
|
+
if (raw === null)
|
|
149
|
+
return [];
|
|
150
|
+
const parsed = JSON.parse(raw);
|
|
151
|
+
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function rememberSlot(slot) {
|
|
158
|
+
try {
|
|
159
|
+
const list = await readSlots();
|
|
160
|
+
if (list.includes(slot))
|
|
161
|
+
return;
|
|
162
|
+
await backend.write(indexKey(), JSON.stringify([...list, slot]));
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
reportError(error);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async function forgetSlot(slot) {
|
|
169
|
+
try {
|
|
170
|
+
const list = await readSlots();
|
|
171
|
+
if (!list.includes(slot))
|
|
172
|
+
return;
|
|
173
|
+
await backend.write(indexKey(), JSON.stringify(list.filter((entry) => entry !== slot)));
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
reportError(error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function clearTimer() {
|
|
180
|
+
if (pendingTimer !== null) {
|
|
181
|
+
timers.clear(pendingTimer);
|
|
182
|
+
pendingTimer = null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function markDirty() {
|
|
186
|
+
dirty = true;
|
|
187
|
+
if (auto === null)
|
|
188
|
+
return;
|
|
189
|
+
const now = clock();
|
|
190
|
+
if (firstDirtyAt === null)
|
|
191
|
+
firstDirtyAt = now;
|
|
192
|
+
if (auto.maxWaitMs > 0 && now - firstDirtyAt >= auto.maxWaitMs) {
|
|
193
|
+
clearTimer();
|
|
194
|
+
void save();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
clearTimer();
|
|
198
|
+
pendingTimer = timers.set(() => {
|
|
199
|
+
pendingTimer = null;
|
|
200
|
+
void save();
|
|
201
|
+
}, auto.debounceMs);
|
|
202
|
+
}
|
|
203
|
+
async function flush() {
|
|
204
|
+
if (disposed)
|
|
205
|
+
return;
|
|
206
|
+
clearTimer();
|
|
207
|
+
const slot = currentSlot;
|
|
208
|
+
const value = current;
|
|
209
|
+
setStatus("saving");
|
|
210
|
+
try {
|
|
211
|
+
const envelope = { version: formatVersion, savedAt: clock(), value };
|
|
212
|
+
await backend.write(dataKey(slot), serialize(envelope));
|
|
213
|
+
await rememberSlot(slot);
|
|
214
|
+
if (current === value) {
|
|
215
|
+
dirty = false;
|
|
216
|
+
firstDirtyAt = null;
|
|
217
|
+
}
|
|
218
|
+
setStatus("saved");
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
setStatus("error");
|
|
222
|
+
reportError(error);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function save() {
|
|
226
|
+
const run = saveChain.then(() => flush());
|
|
227
|
+
saveChain = run.catch(() => undefined);
|
|
228
|
+
return run;
|
|
229
|
+
}
|
|
230
|
+
async function load() {
|
|
231
|
+
setStatus("loading");
|
|
232
|
+
try {
|
|
233
|
+
const raw = await backend.read(dataKey(currentSlot));
|
|
234
|
+
let value;
|
|
235
|
+
try {
|
|
236
|
+
value = raw === null ? initial : decode(raw);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
value = initial;
|
|
240
|
+
}
|
|
241
|
+
current = value;
|
|
242
|
+
dirty = false;
|
|
243
|
+
firstDirtyAt = null;
|
|
244
|
+
setStatus("idle");
|
|
245
|
+
emit();
|
|
246
|
+
void rememberSlot(currentSlot);
|
|
247
|
+
return current;
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
setStatus("error");
|
|
251
|
+
reportError(error);
|
|
252
|
+
return current;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
value: () => current,
|
|
257
|
+
status: () => status,
|
|
258
|
+
slot: () => currentSlot,
|
|
259
|
+
revision: () => revision,
|
|
260
|
+
load,
|
|
261
|
+
set(value) {
|
|
262
|
+
current = value;
|
|
263
|
+
emit();
|
|
264
|
+
markDirty();
|
|
265
|
+
},
|
|
266
|
+
patch(mutate) {
|
|
267
|
+
current = mutate(current);
|
|
268
|
+
emit();
|
|
269
|
+
markDirty();
|
|
270
|
+
return current;
|
|
271
|
+
},
|
|
272
|
+
save,
|
|
273
|
+
async clear() {
|
|
274
|
+
clearTimer();
|
|
275
|
+
const slot = currentSlot;
|
|
276
|
+
setStatus("saving");
|
|
277
|
+
try {
|
|
278
|
+
await backend.remove(dataKey(slot));
|
|
279
|
+
await forgetSlot(slot);
|
|
280
|
+
current = initial;
|
|
281
|
+
dirty = false;
|
|
282
|
+
firstDirtyAt = null;
|
|
283
|
+
setStatus("idle");
|
|
284
|
+
emit();
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
setStatus("error");
|
|
288
|
+
reportError(error);
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
async switchSlot(slot) {
|
|
292
|
+
if (dirty)
|
|
293
|
+
await save();
|
|
294
|
+
clearTimer();
|
|
295
|
+
currentSlot = slot;
|
|
296
|
+
current = initial;
|
|
297
|
+
dirty = false;
|
|
298
|
+
firstDirtyAt = null;
|
|
299
|
+
return load();
|
|
300
|
+
},
|
|
301
|
+
slots: readSlots,
|
|
302
|
+
subscribe(listener) {
|
|
303
|
+
listeners.add(listener);
|
|
304
|
+
return () => listeners.delete(listener);
|
|
305
|
+
},
|
|
306
|
+
dispose() {
|
|
307
|
+
disposed = true;
|
|
308
|
+
clearTimer();
|
|
309
|
+
listeners.clear();
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Bounded past/future snapshot stacks — a serializable undo/redo record for any state `T`. */
|
|
2
|
+
export interface HistoryStacks<T> {
|
|
3
|
+
/** Prior states, oldest first; the last entry is the step an undo restores. */
|
|
4
|
+
readonly past: readonly T[];
|
|
5
|
+
/** Undone states awaiting redo, oldest first; the last entry is the step a redo restores. */
|
|
6
|
+
readonly future: readonly T[];
|
|
7
|
+
}
|
|
8
|
+
/** The snapshot an undo/redo restores plus the advanced stacks. */
|
|
9
|
+
export interface HistoryStep<T> {
|
|
10
|
+
/** State to apply as the new present. */
|
|
11
|
+
snapshot: T;
|
|
12
|
+
/** Stacks after the step. */
|
|
13
|
+
stacks: HistoryStacks<T>;
|
|
14
|
+
}
|
|
15
|
+
/** Empty history stacks for state `T`.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare function emptyHistory<T>(): HistoryStacks<T>;
|
|
19
|
+
/** True when there is a prior state to undo to.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export declare function canUndo<T>(stacks: HistoryStacks<T>): boolean;
|
|
23
|
+
/** True when there is an undone state to redo.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare function canRedo<T>(stacks: HistoryStacks<T>): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Record `present` as the newest undo step and clear the redo future (a fresh action forks history).
|
|
29
|
+
* The oldest past entries beyond `limit` are dropped so the stack stays bounded for save/transport.
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export declare function recordSnapshot<T>(stacks: HistoryStacks<T>, present: T, limit?: number): HistoryStacks<T>;
|
|
33
|
+
/**
|
|
34
|
+
* Step back: pop the newest past snapshot to apply as the new present, and push the given `present`
|
|
35
|
+
* onto the future for a later redo. Returns `null` when there is nothing to undo.
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export declare function undoSnapshot<T>(stacks: HistoryStacks<T>, present: T): HistoryStep<T> | null;
|
|
39
|
+
/**
|
|
40
|
+
* Step forward: pop the newest future snapshot to apply as the new present, and push the given
|
|
41
|
+
* `present` back onto the past. Returns `null` when there is nothing to redo.
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export declare function redoSnapshot<T>(stacks: HistoryStacks<T>, present: T): HistoryStep<T> | null;
|
|
45
|
+
/** Stateful undo/redo handle over {@link HistoryStacks}, holding the stacks in a closure. */
|
|
46
|
+
export interface SnapshotHistory<T> {
|
|
47
|
+
/** Record `present` as a new undo step and clear the redo future. */
|
|
48
|
+
record(present: T): void;
|
|
49
|
+
/** Undo, returning the restored snapshot or `null` if there is nothing to undo. */
|
|
50
|
+
undo(present: T): T | null;
|
|
51
|
+
/** Redo, returning the restored snapshot or `null` if there is nothing to redo. */
|
|
52
|
+
redo(present: T): T | null;
|
|
53
|
+
/** True when an undo is available. */
|
|
54
|
+
canUndo(): boolean;
|
|
55
|
+
/** True when a redo is available. */
|
|
56
|
+
canRedo(): boolean;
|
|
57
|
+
/** Drop all history. */
|
|
58
|
+
clear(): void;
|
|
59
|
+
/** Current immutable stacks (for serialization). */
|
|
60
|
+
stacks(): HistoryStacks<T>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Stateful undo/redo handle wrapping the pure snapshot functions. Call `record(state)` before each
|
|
64
|
+
* mutation; `undo`/`redo` return the state to apply. `limit` bounds the past stack.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export declare function createSnapshotHistory<T>(limit?: number): SnapshotHistory<T>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/** Empty history stacks for state `T`.
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
4
|
+
export function emptyHistory() {
|
|
5
|
+
return { past: [], future: [] };
|
|
6
|
+
}
|
|
7
|
+
/** True when there is a prior state to undo to.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export function canUndo(stacks) {
|
|
11
|
+
return stacks.past.length > 0;
|
|
12
|
+
}
|
|
13
|
+
/** True when there is an undone state to redo.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function canRedo(stacks) {
|
|
17
|
+
return stacks.future.length > 0;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Record `present` as the newest undo step and clear the redo future (a fresh action forks history).
|
|
21
|
+
* The oldest past entries beyond `limit` are dropped so the stack stays bounded for save/transport.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export function recordSnapshot(stacks, present, limit = 100) {
|
|
25
|
+
const past = [...stacks.past, present];
|
|
26
|
+
const trimmed = limit > 0 && past.length > limit ? past.slice(past.length - limit) : past;
|
|
27
|
+
return { past: trimmed, future: [] };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Step back: pop the newest past snapshot to apply as the new present, and push the given `present`
|
|
31
|
+
* onto the future for a later redo. Returns `null` when there is nothing to undo.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export function undoSnapshot(stacks, present) {
|
|
35
|
+
if (stacks.past.length === 0)
|
|
36
|
+
return null;
|
|
37
|
+
const snapshot = stacks.past[stacks.past.length - 1];
|
|
38
|
+
return {
|
|
39
|
+
snapshot,
|
|
40
|
+
stacks: { past: stacks.past.slice(0, -1), future: [...stacks.future, present] },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Step forward: pop the newest future snapshot to apply as the new present, and push the given
|
|
45
|
+
* `present` back onto the past. Returns `null` when there is nothing to redo.
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export function redoSnapshot(stacks, present) {
|
|
49
|
+
if (stacks.future.length === 0)
|
|
50
|
+
return null;
|
|
51
|
+
const snapshot = stacks.future[stacks.future.length - 1];
|
|
52
|
+
return {
|
|
53
|
+
snapshot,
|
|
54
|
+
stacks: { past: [...stacks.past, present], future: stacks.future.slice(0, -1) },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stateful undo/redo handle wrapping the pure snapshot functions. Call `record(state)` before each
|
|
59
|
+
* mutation; `undo`/`redo` return the state to apply. `limit` bounds the past stack.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export function createSnapshotHistory(limit = 100) {
|
|
63
|
+
let stacks = emptyHistory();
|
|
64
|
+
return {
|
|
65
|
+
record(present) {
|
|
66
|
+
stacks = recordSnapshot(stacks, present, limit);
|
|
67
|
+
},
|
|
68
|
+
undo(present) {
|
|
69
|
+
const step = undoSnapshot(stacks, present);
|
|
70
|
+
if (step === null)
|
|
71
|
+
return null;
|
|
72
|
+
stacks = step.stacks;
|
|
73
|
+
return step.snapshot;
|
|
74
|
+
},
|
|
75
|
+
redo(present) {
|
|
76
|
+
const step = redoSnapshot(stacks, present);
|
|
77
|
+
if (step === null)
|
|
78
|
+
return null;
|
|
79
|
+
stacks = step.stacks;
|
|
80
|
+
return step.snapshot;
|
|
81
|
+
},
|
|
82
|
+
canUndo() {
|
|
83
|
+
return canUndo(stacks);
|
|
84
|
+
},
|
|
85
|
+
canRedo() {
|
|
86
|
+
return canRedo(stacks);
|
|
87
|
+
},
|
|
88
|
+
clear() {
|
|
89
|
+
stacks = emptyHistory();
|
|
90
|
+
},
|
|
91
|
+
stacks() {
|
|
92
|
+
return stacks;
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
package/dist/game/social.d.ts
CHANGED
|
@@ -135,6 +135,36 @@ export interface WorldInvites {
|
|
|
135
135
|
decline(userId: string, inviteId: string): void;
|
|
136
136
|
listFor(userId: string): WorldInvite[];
|
|
137
137
|
}
|
|
138
|
+
/** One party's replicated membership — id, current leader, and ordered member ids. */
|
|
139
|
+
export interface SocialPartySnapshot {
|
|
140
|
+
id: string;
|
|
141
|
+
leader: string;
|
|
142
|
+
members: string[];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Full friends/party/world-invite state as one serializable baseline — the host→client replication
|
|
146
|
+
* payload behind the `social` snapshot module. Presence and emotes are derived from live deps, not stored.
|
|
147
|
+
*/
|
|
148
|
+
export interface SocialSnapshot {
|
|
149
|
+
friendships: Record<string, string[]>;
|
|
150
|
+
blocked: Record<string, string[]>;
|
|
151
|
+
friendRequests: Record<string, {
|
|
152
|
+
from: string;
|
|
153
|
+
to: string;
|
|
154
|
+
}>;
|
|
155
|
+
requestCounter: number;
|
|
156
|
+
partyConfig: PartyConfig | null;
|
|
157
|
+
parties: SocialPartySnapshot[];
|
|
158
|
+
partyInvites: Record<string, {
|
|
159
|
+
from: string;
|
|
160
|
+
to: string;
|
|
161
|
+
createdAt: number;
|
|
162
|
+
}>;
|
|
163
|
+
partyCounter: number;
|
|
164
|
+
inviteCounter: number;
|
|
165
|
+
worldInvites: WorldInvite[];
|
|
166
|
+
worldInviteCounter: number;
|
|
167
|
+
}
|
|
138
168
|
export interface Social {
|
|
139
169
|
friends: Friends;
|
|
140
170
|
party: Party;
|
|
@@ -143,5 +173,12 @@ export interface Social {
|
|
|
143
173
|
};
|
|
144
174
|
emotes: Emotes;
|
|
145
175
|
worldInvites: WorldInvites;
|
|
146
|
-
|
|
176
|
+
snapshot(): SocialSnapshot;
|
|
177
|
+
hydrate(data: SocialSnapshot): void;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Emotes and lightweight social interactions between nearby players.
|
|
181
|
+
*
|
|
182
|
+
* @capability social-emotes emotes and social interactions between nearby players
|
|
183
|
+
*/
|
|
147
184
|
export declare function createSocial(deps: SocialDeps): Social;
|
package/dist/game/social.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export const DEFAULT_EMOTE_RADIUS = 20;
|
|
2
2
|
const DEFAULT_INVITE_TTL_MS = 60_000;
|
|
3
|
+
/**
|
|
4
|
+
* Emotes and lightweight social interactions between nearby players.
|
|
5
|
+
*
|
|
6
|
+
* @capability social-emotes emotes and social interactions between nearby players
|
|
7
|
+
*/
|
|
3
8
|
export function createSocial(deps) {
|
|
4
9
|
const now = deps.now ?? Date.now;
|
|
5
10
|
const events = deps.events;
|
|
@@ -351,6 +356,70 @@ export function createSocial(deps) {
|
|
|
351
356
|
return result;
|
|
352
357
|
},
|
|
353
358
|
};
|
|
359
|
+
function snapshot() {
|
|
360
|
+
const friendshipsOut = {};
|
|
361
|
+
for (const [userId, set] of friendships)
|
|
362
|
+
friendshipsOut[userId] = Array.from(set);
|
|
363
|
+
const blockedOut = {};
|
|
364
|
+
for (const [userId, set] of blocked)
|
|
365
|
+
blockedOut[userId] = Array.from(set);
|
|
366
|
+
const friendRequestsOut = {};
|
|
367
|
+
for (const [id, request] of friendRequests)
|
|
368
|
+
friendRequestsOut[id] = { from: request.from, to: request.to };
|
|
369
|
+
const partyInvitesOut = {};
|
|
370
|
+
for (const [id, invite] of partyInvites) {
|
|
371
|
+
partyInvitesOut[id] = { from: invite.from, to: invite.to, createdAt: invite.createdAt };
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
friendships: friendshipsOut,
|
|
375
|
+
blocked: blockedOut,
|
|
376
|
+
friendRequests: friendRequestsOut,
|
|
377
|
+
requestCounter,
|
|
378
|
+
partyConfig,
|
|
379
|
+
parties: Array.from(parties.values(), (state) => ({
|
|
380
|
+
id: state.id,
|
|
381
|
+
leader: state.leader,
|
|
382
|
+
members: state.members.slice(),
|
|
383
|
+
})),
|
|
384
|
+
partyInvites: partyInvitesOut,
|
|
385
|
+
partyCounter,
|
|
386
|
+
inviteCounter,
|
|
387
|
+
worldInvites: Array.from(worldInviteEntries.values(), (entry) => ({ ...entry })),
|
|
388
|
+
worldInviteCounter,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function hydrate(data) {
|
|
392
|
+
friendships.clear();
|
|
393
|
+
for (const [userId, list] of Object.entries(data.friendships))
|
|
394
|
+
friendships.set(userId, new Set(list));
|
|
395
|
+
blocked.clear();
|
|
396
|
+
for (const [userId, list] of Object.entries(data.blocked))
|
|
397
|
+
blocked.set(userId, new Set(list));
|
|
398
|
+
friendRequests.clear();
|
|
399
|
+
for (const [id, request] of Object.entries(data.friendRequests)) {
|
|
400
|
+
friendRequests.set(id, { from: request.from, to: request.to });
|
|
401
|
+
}
|
|
402
|
+
requestCounter = data.requestCounter;
|
|
403
|
+
partyConfig = data.partyConfig;
|
|
404
|
+
parties.clear();
|
|
405
|
+
memberToParty.clear();
|
|
406
|
+
for (const state of data.parties) {
|
|
407
|
+
const restored = { id: state.id, leader: state.leader, members: state.members.slice() };
|
|
408
|
+
parties.set(restored.id, restored);
|
|
409
|
+
for (const member of restored.members)
|
|
410
|
+
memberToParty.set(member, restored.id);
|
|
411
|
+
}
|
|
412
|
+
partyInvites.clear();
|
|
413
|
+
for (const [id, invite] of Object.entries(data.partyInvites)) {
|
|
414
|
+
partyInvites.set(id, { from: invite.from, to: invite.to, createdAt: invite.createdAt });
|
|
415
|
+
}
|
|
416
|
+
partyCounter = data.partyCounter;
|
|
417
|
+
inviteCounter = data.inviteCounter;
|
|
418
|
+
worldInviteEntries.clear();
|
|
419
|
+
for (const entry of data.worldInvites)
|
|
420
|
+
worldInviteEntries.set(entry.id, { ...entry });
|
|
421
|
+
worldInviteCounter = data.worldInviteCounter;
|
|
422
|
+
}
|
|
354
423
|
return {
|
|
355
424
|
friends,
|
|
356
425
|
party,
|
|
@@ -361,5 +430,7 @@ export function createSocial(deps) {
|
|
|
361
430
|
},
|
|
362
431
|
emotes,
|
|
363
432
|
worldInvites,
|
|
433
|
+
snapshot,
|
|
434
|
+
hydrate,
|
|
364
435
|
};
|
|
365
436
|
}
|
|
@@ -16,4 +16,9 @@ export interface SpawnPoints {
|
|
|
16
16
|
})[];
|
|
17
17
|
respawn(entities: RespawnTarget, entityId: string, spawnId: string): boolean;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Register spawn locations and choose where entities spawn or respawn.
|
|
21
|
+
*
|
|
22
|
+
* @capability spawn-points register spawn locations and pick where entities respawn
|
|
23
|
+
*/
|
|
19
24
|
export declare function createSpawnPoints(): SpawnPoints;
|
package/dist/game/spawnPoints.js
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { GameLoop } from "./defineGame.js";
|
|
2
|
+
import type { SystemDefinition } from "./defineSystem.js";
|
|
3
|
+
import { type CompiledSystemSchedule, type CompileSystemScheduleOptions } from "./systemSchedule.js";
|
|
4
|
+
import type { GameContext } from "../runtime/gameContext.js";
|
|
5
|
+
import type { SnapshotModule } from "../runtime/worldSnapshot.js";
|
|
6
|
+
/** @internal */
|
|
7
|
+
export interface SystemModuleRegistration {
|
|
8
|
+
registerSave(module: SnapshotModule): void;
|
|
9
|
+
registerReplicate(module: SnapshotModule): void;
|
|
10
|
+
}
|
|
11
|
+
/** @internal */
|
|
12
|
+
export interface InstalledSystems {
|
|
13
|
+
readonly schedule: CompiledSystemSchedule;
|
|
14
|
+
/** Advance fixed/frame/interval systems for one game-time step of `dt` seconds. */
|
|
15
|
+
tick(ctx: GameContext, dt: number): void;
|
|
16
|
+
/** Invoke every system's `reset` (scenario/run wipe). */
|
|
17
|
+
reset(ctx: GameContext): void;
|
|
18
|
+
/** Invoke every system's `dispose` in reverse install order. */
|
|
19
|
+
dispose(ctx: GameContext): void;
|
|
20
|
+
/** Run one manual system by id (no-op if missing or not manual). */
|
|
21
|
+
runManual(ctx: GameContext, id: string, dt?: number): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Install systems on a live context: `create` → bind events → register save/replicate → `start`.
|
|
25
|
+
* Call once per world boot (from the composed loop's `onInit`).
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare function installSystems(ctx: GameContext, systems: readonly SystemDefinition[], options?: CompileSystemScheduleOptions & {
|
|
29
|
+
modules?: SystemModuleRegistration;
|
|
30
|
+
}): InstalledSystems;
|
|
31
|
+
/**
|
|
32
|
+
* Look up systems installed on `ctx` (if any). Used by hosts that need `reset`/`dispose` after boot.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export declare function systemsOf(ctx: GameContext): InstalledSystems | undefined;
|
|
36
|
+
/** @internal */
|
|
37
|
+
export interface ComposeGameLoopOptions extends CompileSystemScheduleOptions {
|
|
38
|
+
/**
|
|
39
|
+
* When true, the user loop's `onTick` runs before system ticks (default: systems first, then
|
|
40
|
+
* residual loop work — the incremental-migration path).
|
|
41
|
+
*/
|
|
42
|
+
loopBeforeSystems?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Merge a system list with an optional classic `GameLoop` into one loop the shell/runners drive.
|
|
46
|
+
* Systems install on first `onInit`; classic hooks still run for incremental migration.
|
|
47
|
+
*
|
|
48
|
+
* @capability compose-game-loop fold composable systems into the game loop without a manual tick fan-out
|
|
49
|
+
*/
|
|
50
|
+
export declare function composeGameLoop(systems: readonly SystemDefinition[] | undefined, loop: GameLoop<GameContext> | undefined, options?: ComposeGameLoopOptions): GameLoop<GameContext>;
|