@jgengine/core 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -3
- package/LICENSE +203 -661
- package/README.md +1 -1
- package/dist/ai/crowd.d.ts +55 -0
- package/dist/ai/crowd.js +114 -0
- package/dist/ai/flock.d.ts +5 -2
- package/dist/ai/flock.js +5 -2
- package/dist/ai/groupAssist.d.ts +1 -0
- package/dist/ai/groupAssist.js +1 -0
- package/dist/ai/heatSystem.d.ts +76 -0
- package/dist/ai/heatSystem.js +97 -0
- package/dist/ai/interestScheduler.d.ts +107 -0
- package/dist/ai/interestScheduler.js +118 -0
- package/dist/ai/jobBoard.d.ts +1 -0
- package/dist/ai/jobBoard.js +1 -0
- package/dist/ai/laneSelect.d.ts +5 -2
- package/dist/ai/laneSelect.js +5 -2
- package/dist/ai/mobBrain.d.ts +1 -0
- package/dist/ai/mobBrain.js +1 -0
- package/dist/ai/spawnDirector.d.ts +19 -1
- package/dist/ai/spawnDirector.js +53 -26
- package/dist/ai/spawnPoint.d.ts +7 -0
- package/dist/ai/spawnPoint.js +7 -0
- package/dist/ai/targetAcquisition.d.ts +84 -0
- package/dist/ai/targetAcquisition.js +92 -0
- package/dist/anim/easing.d.ts +19 -0
- package/dist/anim/easing.js +19 -0
- package/dist/anim/oscillator.d.ts +12 -0
- package/dist/anim/oscillator.js +25 -0
- package/dist/area/areaEffectField.d.ts +127 -0
- package/dist/area/areaEffectField.js +175 -0
- package/dist/area/stackPolicy.d.ts +47 -0
- package/dist/area/stackPolicy.js +99 -0
- package/dist/audio/audioFalloff.d.ts +5 -2
- package/dist/audio/music.d.ts +53 -0
- package/dist/audio/music.js +34 -0
- package/dist/audio/synth.d.ts +60 -0
- package/dist/audio/synth.js +8 -0
- package/dist/authoring.d.ts +15 -0
- package/dist/authoring.js +15 -0
- package/dist/board/laneBoard.d.ts +13 -0
- package/dist/board/laneBoard.js +13 -0
- package/dist/board/timelineBoard.d.ts +10 -0
- package/dist/board/timelineBoard.js +10 -0
- package/dist/combat/abilityKit.d.ts +18 -0
- package/dist/combat/abilityKit.js +24 -9
- package/dist/combat/animationState.d.ts +5 -0
- package/dist/combat/animationState.js +5 -0
- package/dist/combat/breakMeters.d.ts +10 -0
- package/dist/combat/breakMeters.js +10 -0
- package/dist/combat/castRunner.d.ts +5 -0
- package/dist/combat/castRunner.js +5 -0
- package/dist/combat/comboPoints.d.ts +5 -0
- package/dist/combat/comboPoints.js +5 -0
- package/dist/combat/comboString.d.ts +5 -0
- package/dist/combat/comboString.js +5 -0
- package/dist/combat/damageInterceptors.d.ts +192 -0
- package/dist/combat/damageInterceptors.js +251 -0
- package/dist/combat/damageMatchup.d.ts +68 -0
- package/dist/combat/damageMatchup.js +42 -0
- package/dist/combat/damageResolution.d.ts +63 -0
- package/dist/combat/damageResolution.js +50 -0
- package/dist/combat/death.d.ts +7 -1
- package/dist/combat/death.js +5 -0
- package/dist/combat/deathReason.d.ts +14 -0
- package/dist/combat/deathReason.js +1 -0
- package/dist/combat/defensiveWindow.d.ts +5 -0
- package/dist/combat/defensiveWindow.js +5 -0
- package/dist/combat/dotField.d.ts +47 -0
- package/dist/combat/dotField.js +52 -0
- package/dist/combat/downed.d.ts +5 -0
- package/dist/combat/downed.js +5 -0
- package/dist/combat/effects.d.ts +5 -0
- package/dist/combat/effects.js +5 -0
- package/dist/combat/encounterSequence.d.ts +258 -0
- package/dist/combat/encounterSequence.js +426 -0
- package/dist/combat/hitReaction.d.ts +57 -1
- package/dist/combat/hitReaction.js +45 -5
- package/dist/combat/magazine.d.ts +54 -0
- package/dist/combat/magazine.js +96 -0
- package/dist/combat/projectiles.d.ts +7 -2
- package/dist/combat/projectiles.js +48 -17
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +39 -0
- package/dist/combat/regenShield.js +49 -0
- package/dist/combat/renderCues.d.ts +51 -0
- package/dist/combat/renderCues.js +44 -0
- package/dist/combat/resourcePool.d.ts +5 -0
- package/dist/combat/resourcePool.js +5 -0
- package/dist/combat/rewardAllocation.d.ts +121 -0
- package/dist/combat/rewardAllocation.js +251 -0
- package/dist/combat/shotOrigin.d.ts +30 -1
- package/dist/combat/shotOrigin.js +70 -2
- package/dist/combat/statusApplication.d.ts +96 -0
- package/dist/combat/statusApplication.js +81 -0
- package/dist/combat/telegraph.d.ts +11 -2
- package/dist/combat/telegraph.js +11 -2
- package/dist/combat/thresholdCrossings.d.ts +85 -0
- package/dist/combat/thresholdCrossings.js +116 -0
- package/dist/combat.d.ts +34 -0
- package/dist/combat.js +34 -0
- package/dist/commands/commandRegistry.d.ts +11 -0
- package/dist/commands/commandRegistry.js +9 -2
- package/dist/crafting/crop.d.ts +18 -0
- package/dist/crafting/crop.js +18 -0
- package/dist/crafting/production.d.ts +5 -0
- package/dist/crafting/production.js +5 -0
- package/dist/devtools/rewriteTunables.d.ts +17 -0
- package/dist/devtools/rewriteTunables.js +276 -0
- package/dist/devtools/saveEndpoint.d.ts +46 -0
- package/dist/devtools/saveEndpoint.js +48 -0
- package/dist/devtools/transformTunables.d.ts +3 -0
- package/dist/devtools/transformTunables.js +3 -0
- package/dist/devtools/tunableSchema.d.ts +31 -0
- package/dist/devtools/tunableSchema.js +31 -0
- package/dist/economy/currency.d.ts +12 -1
- package/dist/economy/currency.js +12 -1
- package/dist/economy/listingBook.d.ts +91 -0
- package/dist/economy/listingBook.js +144 -0
- package/dist/economy/resourceLedger.d.ts +222 -0
- package/dist/economy/resourceLedger.js +353 -0
- package/dist/economy/sharedWallet.d.ts +14 -0
- package/dist/economy/sharedWallet.js +14 -0
- package/dist/economy/techTree.d.ts +12 -0
- package/dist/economy/techTree.js +12 -0
- package/dist/economy/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commands.d.ts +248 -0
- package/dist/editor/commands.js +865 -0
- package/dist/editor/document.d.ts +186 -0
- package/dist/editor/document.js +884 -0
- package/dist/editor/grid.d.ts +229 -0
- package/dist/editor/grid.js +366 -0
- package/dist/editor/gridAdapters.d.ts +80 -0
- package/dist/editor/gridAdapters.js +134 -0
- package/dist/editor/index.d.ts +97 -0
- package/dist/editor/index.js +10 -0
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/types.d.ts +175 -0
- package/dist/editor/types.js +29 -0
- package/dist/faction/reputation.d.ts +5 -0
- package/dist/faction/reputation.js +5 -0
- package/dist/format/distance.d.ts +17 -0
- package/dist/format/distance.js +18 -0
- package/dist/format/duration.d.ts +27 -0
- package/dist/format/duration.js +45 -0
- package/dist/format/speed.d.ts +17 -0
- package/dist/format/speed.js +25 -0
- package/dist/game/connectedPlayers.d.ts +30 -0
- package/dist/game/connectedPlayers.js +21 -0
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +141 -2
- package/dist/game/defineGame.js +39 -1
- package/dist/game/defineSystem.d.ts +88 -0
- package/dist/game/defineSystem.js +45 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +50 -13
- package/dist/game/events.js +5 -0
- package/dist/game/feed.d.ts +33 -0
- package/dist/game/feed.js +35 -2
- package/dist/game/gamePhase.d.ts +11 -0
- package/dist/game/gamePhase.js +16 -0
- package/dist/game/keyValueStore.d.ts +25 -0
- package/dist/game/keyValueStore.js +61 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/levelSequence.d.ts +24 -2
- package/dist/game/levelSequence.js +51 -2
- package/dist/game/loadout.d.ts +5 -0
- package/dist/game/loadout.js +5 -0
- package/dist/game/lootFilter.d.ts +2 -0
- package/dist/game/lootFilter.js +2 -0
- package/dist/game/lootPipeline.d.ts +164 -0
- package/dist/game/lootPipeline.js +216 -0
- package/dist/game/lootTable.d.ts +21 -0
- package/dist/game/lootTable.js +15 -4
- package/dist/game/modelAnimation.d.ts +8 -0
- package/dist/game/modelAnimation.js +18 -0
- package/dist/game/objectives.d.ts +43 -0
- package/dist/game/objectives.js +36 -0
- package/dist/game/paramLayers.d.ts +148 -0
- package/dist/game/paramLayers.js +185 -0
- package/dist/game/ping.d.ts +5 -0
- package/dist/game/ping.js +5 -0
- package/dist/game/playableGame.d.ts +160 -12
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +29 -0
- package/dist/game/race.d.ts +141 -0
- package/dist/game/race.js +169 -0
- package/dist/game/recordBook.d.ts +5 -5
- package/dist/game/recordBook.js +4 -1
- package/dist/game/ruleSelection.d.ts +75 -0
- package/dist/game/ruleSelection.js +127 -0
- package/dist/game/runDraft.d.ts +5 -0
- package/dist/game/runDraft.js +5 -0
- package/dist/game/saveStore.d.ts +111 -0
- package/dist/game/saveStore.js +312 -0
- package/dist/game/snapshotHistory.d.ts +67 -0
- package/dist/game/snapshotHistory.js +95 -0
- package/dist/game/social.d.ts +38 -1
- package/dist/game/social.js +71 -0
- package/dist/game/spawnPoints.d.ts +5 -0
- package/dist/game/spawnPoints.js +5 -0
- package/dist/game/systemRuntime.d.ts +50 -0
- package/dist/game/systemRuntime.js +157 -0
- package/dist/game/systemSchedule.d.ts +72 -0
- package/dist/game/systemSchedule.js +242 -0
- package/dist/game/toasts.d.ts +43 -0
- package/dist/game/toasts.js +44 -0
- package/dist/game/trade.d.ts +10 -0
- package/dist/game/trade.js +10 -0
- package/dist/game/unlocks.d.ts +8 -0
- package/dist/game/unlocks.js +16 -0
- package/dist/game/vfxInstance.d.ts +138 -0
- package/dist/game/vfxInstance.js +96 -0
- package/dist/game/worldItem.d.ts +17 -4
- package/dist/game/worldItem.js +17 -4
- package/dist/gameplay.d.ts +91 -0
- package/dist/gameplay.js +91 -0
- package/dist/index.d.ts +5 -7
- package/dist/index.js +5 -7
- package/dist/input/actionBindings.d.ts +24 -5
- package/dist/input/actionBindings.js +23 -5
- package/dist/input/axisInput.d.ts +13 -1
- package/dist/input/axisInput.js +22 -1
- package/dist/input/controlGroups.d.ts +67 -0
- package/dist/input/controlGroups.js +41 -0
- package/dist/input/touchScheme.d.ts +82 -6
- package/dist/input/touchScheme.js +123 -10
- package/dist/interaction/contextMenu.d.ts +1 -0
- package/dist/interaction/contextMenu.js +1 -0
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +5 -1
- package/dist/interaction/proximityPrompt.js +5 -3
- package/dist/interaction/qte.d.ts +5 -0
- package/dist/interaction/qte.js +5 -0
- package/dist/interaction/skillCheck.d.ts +5 -0
- package/dist/interaction/skillCheck.js +5 -0
- package/dist/inventory/inventoryModel.d.ts +12 -0
- package/dist/inventory/inventoryModel.js +12 -0
- package/dist/inventory/shapedGrid.d.ts +16 -0
- package/dist/inventory/shapedGrid.js +16 -0
- package/dist/inventory/slotModel.d.ts +10 -0
- package/dist/inventory/slotModel.js +10 -0
- package/dist/item/durability.d.ts +5 -0
- package/dist/item/durability.js +5 -0
- package/dist/item/itemIdentity.d.ts +171 -0
- package/dist/item/itemIdentity.js +138 -0
- package/dist/item/itemInstanceRegistry.d.ts +32 -0
- package/dist/item/itemInstanceRegistry.js +34 -0
- package/dist/item/itemgen.d.ts +163 -0
- package/dist/item/itemgen.js +151 -0
- package/dist/item/modularItem.d.ts +5 -0
- package/dist/item/modularItem.js +5 -0
- package/dist/item/use.d.ts +5 -0
- package/dist/item/use.js +5 -0
- package/dist/item/useBehavior.d.ts +142 -0
- package/dist/item/useBehavior.js +105 -0
- package/dist/item/weapon.d.ts +5 -0
- package/dist/item/weapon.js +5 -0
- package/dist/math/scalar.d.ts +25 -0
- package/dist/math/scalar.js +47 -0
- package/dist/meta/changelog.d.ts +4 -1
- package/dist/meta/changelog.js +36 -1
- package/dist/movement/avoidance.d.ts +45 -0
- package/dist/movement/avoidance.js +123 -0
- package/dist/movement/cameraRig.d.ts +8 -0
- package/dist/movement/cameraRig.js +8 -0
- package/dist/movement/dash.d.ts +11 -0
- package/dist/movement/dash.js +11 -0
- package/dist/movement/formation.d.ts +135 -0
- package/dist/movement/formation.js +194 -0
- package/dist/movement/glideModel.d.ts +5 -0
- package/dist/movement/glideModel.js +5 -0
- package/dist/movement/grappleSwing.d.ts +5 -0
- package/dist/movement/grappleSwing.js +5 -0
- package/dist/movement/leaderTrail.d.ts +5 -0
- package/dist/movement/leaderTrail.js +5 -0
- package/dist/movement/movementModel.d.ts +38 -7
- package/dist/movement/movementModel.js +54 -13
- package/dist/movement/playerMovement.d.ts +41 -0
- package/dist/movement/playerMovement.js +236 -0
- package/dist/movement/poseState.d.ts +13 -0
- package/dist/movement/poseState.js +16 -0
- package/dist/movement/steering.d.ts +8 -0
- package/dist/movement/steering.js +18 -0
- package/dist/multiplayer/combatSnapshot.d.ts +3 -0
- package/dist/multiplayer/combatSnapshot.js +3 -0
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +9 -1
- package/dist/multiplayer/presenceModel.js +9 -1
- package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
- package/dist/multiplayer/simultaneousCommit.js +3 -0
- package/dist/multiplayer.d.ts +11 -0
- package/dist/multiplayer.js +11 -0
- package/dist/nav/pathFollow.d.ts +57 -0
- package/dist/nav/pathFollow.js +109 -0
- package/dist/orders/orderKinds.d.ts +156 -0
- package/dist/orders/orderKinds.js +197 -0
- package/dist/orders/orderQueue.d.ts +208 -0
- package/dist/orders/orderQueue.js +211 -0
- package/dist/physics/drivableVehicle.d.ts +29 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/kinematicVehicle.d.ts +21 -1
- package/dist/physics/kinematicVehicle.js +23 -8
- package/dist/physics/physicsWorld.d.ts +24 -12
- package/dist/physics/physicsWorld.js +11 -5
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -0
- package/dist/procedural.d.ts +3 -0
- package/dist/procedural.js +3 -0
- package/dist/progression/statGraph.d.ts +116 -0
- package/dist/progression/statGraph.js +318 -0
- package/dist/puzzle/cellGrid.d.ts +9 -0
- package/dist/puzzle/cellGrid.js +9 -0
- package/dist/puzzle/fallingPiece.d.ts +9 -0
- package/dist/puzzle/fallingPiece.js +9 -0
- package/dist/puzzle/nonogram.d.ts +39 -0
- package/dist/puzzle/nonogram.js +136 -0
- package/dist/random/nameGen.d.ts +5 -0
- package/dist/random/nameGen.js +5 -0
- package/dist/random/pick.d.ts +8 -0
- package/dist/random/pick.js +31 -0
- package/dist/random/rng.d.ts +24 -0
- package/dist/random/rng.js +30 -8
- package/dist/random/seedLink.d.ts +4 -0
- package/dist/random/seedLink.js +4 -0
- package/dist/relation/keyedValues.d.ts +54 -0
- package/dist/relation/keyedValues.js +115 -0
- package/dist/relation/thresholds.d.ts +62 -0
- package/dist/relation/thresholds.js +62 -0
- package/dist/render/color.d.ts +12 -0
- package/dist/render/color.js +26 -0
- package/dist/render/lookPreset.d.ts +41 -0
- package/dist/render/lookPreset.js +29 -0
- package/dist/render/postProcessing.d.ts +76 -0
- package/dist/render/postProcessing.js +21 -0
- package/dist/rules/predicate.d.ts +53 -0
- package/dist/rules/predicate.js +64 -0
- package/dist/rules/ruleEffects.d.ts +38 -0
- package/dist/rules/ruleEffects.js +37 -0
- package/dist/rules/triggeredRules.d.ts +160 -0
- package/dist/rules/triggeredRules.js +241 -0
- package/dist/runtime/adapter.d.ts +58 -0
- package/dist/runtime/adapter.js +54 -5
- package/dist/runtime/cameraDirector.d.ts +1 -0
- package/dist/runtime/cameraDirector.js +1 -0
- package/dist/runtime/commandRunner.d.ts +1 -0
- package/dist/runtime/commandRunner.js +1 -0
- package/dist/runtime/context/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -0
- package/dist/runtime/context/worldItems.d.ts +21 -0
- package/dist/runtime/context/worldItems.js +37 -0
- package/dist/runtime/descriptors/baseline.d.ts +48 -0
- package/dist/runtime/descriptors/baseline.js +134 -0
- package/dist/runtime/descriptors/features.d.ts +74 -0
- package/dist/runtime/descriptors/features.js +281 -0
- package/dist/runtime/gameContext.d.ts +163 -19
- package/dist/runtime/gameContext.js +385 -339
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +60 -0
- package/dist/runtime/headlessRunner.js +44 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostedGameRunner.d.ts +54 -0
- package/dist/runtime/hostedGameRunner.js +85 -0
- package/dist/runtime/hostedWorldSession.d.ts +73 -0
- package/dist/runtime/hostedWorldSession.js +64 -0
- package/dist/runtime/inputSnapshot.d.ts +21 -3
- package/dist/runtime/inputSnapshot.js +8 -2
- package/dist/runtime/motionIntents.d.ts +12 -1
- package/dist/runtime/motionIntents.js +26 -1
- package/dist/runtime/perContext.d.ts +15 -0
- package/dist/runtime/perContext.js +21 -0
- package/dist/runtime/runtimeSave.d.ts +79 -0
- package/dist/runtime/runtimeSave.js +105 -0
- package/dist/runtime/save.d.ts +4 -0
- package/dist/runtime/save.js +4 -0
- package/dist/runtime/snapshot.d.ts +7 -0
- package/dist/runtime/snapshot.js +7 -0
- package/dist/runtime/visibility.d.ts +2 -1
- package/dist/runtime/visibility.js +2 -1
- package/dist/runtime/worldChannel.d.ts +62 -0
- package/dist/runtime/worldChannel.js +114 -0
- package/dist/runtime/worldMirror.d.ts +36 -0
- package/dist/runtime/worldMirror.js +44 -0
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +69 -0
- package/dist/runtime/worldReplication.js +217 -0
- package/dist/runtime/worldSnapshot.d.ts +44 -0
- package/dist/runtime/worldSnapshot.js +30 -0
- package/dist/scene/assetCatalog.d.ts +22 -0
- package/dist/scene/assetCatalog.js +4 -0
- package/dist/scene/assetDiagnostics.d.ts +69 -0
- package/dist/scene/assetDiagnostics.js +110 -0
- package/dist/scene/assetGenerator.d.ts +65 -0
- package/dist/scene/assetGenerator.js +64 -0
- package/dist/scene/assetSpace.d.ts +137 -0
- package/dist/scene/assetSpace.js +259 -0
- package/dist/scene/authoredTriggers.d.ts +169 -0
- package/dist/scene/authoredTriggers.js +340 -0
- package/dist/scene/behaviorRuntime.d.ts +75 -0
- package/dist/scene/behaviorRuntime.js +217 -0
- package/dist/scene/behaviors.d.ts +14 -2
- package/dist/scene/behaviors.js +7 -2
- package/dist/scene/bodyBind.d.ts +60 -0
- package/dist/scene/bodyBind.js +51 -0
- package/dist/scene/builtinSceneKinds.d.ts +5 -0
- package/dist/scene/builtinSceneKinds.js +62 -0
- package/dist/scene/colliders.d.ts +18 -0
- package/dist/scene/colliders.js +61 -1
- package/dist/scene/entityStats.d.ts +13 -0
- package/dist/scene/entityStats.js +30 -0
- package/dist/scene/entityStore.d.ts +41 -1
- package/dist/scene/entityStore.js +75 -0
- package/dist/scene/facing.d.ts +18 -0
- package/dist/scene/facing.js +26 -0
- package/dist/scene/modelSockets.d.ts +33 -0
- package/dist/scene/modelSockets.js +29 -0
- package/dist/scene/objectQuery.d.ts +2 -0
- package/dist/scene/objectQuery.js +2 -0
- package/dist/scene/objectStore.d.ts +4 -0
- package/dist/scene/objectStore.js +6 -0
- package/dist/scene/possession.d.ts +8 -0
- package/dist/scene/possession.js +14 -0
- package/dist/scene/roster.d.ts +3 -0
- package/dist/scene/roster.js +12 -0
- package/dist/scene/sceneKinds.d.ts +240 -0
- package/dist/scene/sceneKinds.js +214 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -0
- package/dist/scene/selectionBookmarks.d.ts +93 -0
- package/dist/scene/selectionBookmarks.js +122 -0
- package/dist/scene/vehicleSeat.d.ts +68 -0
- package/dist/scene/vehicleSeat.js +59 -0
- package/dist/sensor/concealment.d.ts +3 -0
- package/dist/sensor/concealment.js +3 -0
- package/dist/sensor/freezeMonitor.d.ts +1 -0
- package/dist/sensor/freezeMonitor.js +1 -0
- package/dist/sensor/frustumSensor.d.ts +7 -3
- package/dist/sensor/frustumSensor.js +7 -3
- package/dist/sensor/hiddenStateProbe.d.ts +5 -2
- package/dist/sensor/hiddenStateProbe.js +5 -2
- package/dist/sensor/recordingBuffer.d.ts +2 -1
- package/dist/sensor/recordingBuffer.js +2 -1
- package/dist/sensor/replayLoop.d.ts +6 -2
- package/dist/sensor/replayLoop.js +6 -2
- package/dist/sensor/revealQuery.d.ts +2 -1
- package/dist/sensor/revealQuery.js +2 -1
- package/dist/sensor/visionCone.d.ts +10 -3
- package/dist/sensor/visionCone.js +10 -3
- package/dist/session/contestedChannel.d.ts +1 -0
- package/dist/session/contestedChannel.js +1 -0
- package/dist/session/extraction.d.ts +1 -0
- package/dist/session/extraction.js +1 -0
- package/dist/session/roles.d.ts +6 -0
- package/dist/session/roles.js +6 -0
- package/dist/session/roundState.d.ts +8 -0
- package/dist/session/roundState.js +2 -0
- package/dist/settings/settingsModel.d.ts +1 -0
- package/dist/settings/settingsModel.js +1 -0
- package/dist/stats/accumulatorMeter.d.ts +6 -0
- package/dist/stats/accumulatorMeter.js +6 -0
- package/dist/stats/eventMeter.d.ts +5 -0
- package/dist/stats/eventMeter.js +5 -0
- package/dist/stats/rollCheck.d.ts +5 -0
- package/dist/stats/rollCheck.js +5 -0
- package/dist/stats/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -0
- package/dist/store/defineKeyedStore.d.ts +38 -0
- package/dist/store/defineKeyedStore.js +42 -0
- package/dist/store/defineStore.d.ts +33 -0
- package/dist/store/defineStore.js +35 -0
- package/dist/store/observableKeyedStore.d.ts +9 -0
- package/dist/store/observableKeyedStore.js +43 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -55
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +5 -0
- package/dist/tactics/fallingGrid.d.ts +6 -4
- package/dist/tactics/fallingGrid.js +6 -4
- package/dist/tactics/predictiveQuery.d.ts +3 -0
- package/dist/tactics/predictiveQuery.js +3 -0
- package/dist/tactics/snapshot.d.ts +2 -0
- package/dist/tactics/snapshot.js +2 -0
- package/dist/tactics/surface.d.ts +1 -0
- package/dist/tactics/surface.js +1 -0
- package/dist/tactics/tacticalGrid.d.ts +1 -0
- package/dist/tactics/tacticalGrid.js +1 -0
- package/dist/time/beatClock.d.ts +14 -4
- package/dist/time/beatClock.js +14 -4
- package/dist/time/calendarClock.d.ts +3 -0
- package/dist/time/calendarClock.js +3 -0
- package/dist/time/idleProgress.d.ts +4 -0
- package/dist/time/idleProgress.js +4 -0
- package/dist/time/simClock.d.ts +2 -0
- package/dist/time/simClock.js +20 -5
- package/dist/ui/actionModel.d.ts +110 -0
- package/dist/ui/actionModel.js +159 -0
- package/dist/ui/gameLayout.d.ts +144 -0
- package/dist/ui/gameLayout.js +148 -0
- package/dist/ui/hudDocument.d.ts +114 -0
- package/dist/ui/hudDocument.js +220 -0
- package/dist/ui/hudLayout.d.ts +33 -1
- package/dist/ui/hudLayout.js +204 -17
- package/dist/ui/orientation.d.ts +39 -0
- package/dist/ui/orientation.js +49 -0
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/swingTimer.d.ts +42 -0
- package/dist/ui/swingTimer.js +38 -0
- package/dist/ui/tooltipModel.d.ts +63 -0
- package/dist/ui/tooltipModel.js +82 -0
- package/dist/ui.d.ts +15 -0
- package/dist/ui.js +15 -0
- package/dist/visibility/bounds.d.ts +8 -1
- package/dist/visibility/bounds.js +8 -1
- package/dist/visibility/frustum.d.ts +12 -3
- package/dist/visibility/frustum.js +12 -3
- package/dist/visibility/spatialIndex.js +34 -20
- package/dist/work/jobQueue.d.ts +201 -0
- package/dist/work/jobQueue.js +253 -0
- package/dist/work/unitTraining.d.ts +58 -0
- package/dist/work/unitTraining.js +52 -0
- package/dist/world/authoredObjects.d.ts +58 -0
- package/dist/world/authoredObjects.js +69 -0
- package/dist/world/buildingGenerator.d.ts +18 -0
- package/dist/world/buildingGenerator.js +62 -0
- package/dist/world/buildings.d.ts +5 -0
- package/dist/world/buildings.js +5 -0
- package/dist/world/catenary.d.ts +22 -0
- package/dist/world/catenary.js +69 -0
- package/dist/world/environmentSummary.d.ts +11 -2
- package/dist/world/environmentSummary.js +11 -1
- package/dist/world/features.d.ts +244 -7
- package/dist/world/features.js +92 -4
- package/dist/world/footprintGrid.d.ts +59 -0
- package/dist/world/footprintGrid.js +141 -0
- package/dist/world/geometry.d.ts +64 -0
- package/dist/world/geometry.js +94 -0
- package/dist/world/grassKind.d.ts +51 -0
- package/dist/world/grassKind.js +101 -0
- package/dist/world/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +77 -0
- package/dist/world/placement.d.ts +4 -0
- package/dist/world/placement.js +4 -0
- package/dist/world/placementController.d.ts +6 -0
- package/dist/world/placementController.js +6 -0
- package/dist/world/polyline.d.ts +34 -0
- package/dist/world/polyline.js +81 -0
- package/dist/world/roads.d.ts +55 -0
- package/dist/world/roads.js +184 -0
- package/dist/world/scatterRegion.d.ts +164 -0
- package/dist/world/scatterRegion.js +409 -0
- package/dist/world/sceneShapes.d.ts +43 -0
- package/dist/world/sceneShapes.js +1 -0
- package/dist/world/segment.d.ts +27 -0
- package/dist/world/segment.js +43 -0
- package/dist/world/soilKind.d.ts +48 -0
- package/dist/world/soilKind.js +92 -0
- package/dist/world/spatialSample.d.ts +241 -0
- package/dist/world/spatialSample.js +465 -0
- package/dist/world/streets.d.ts +80 -0
- package/dist/world/streets.js +144 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +655 -20
- package/dist/world/terrain.d.ts +138 -12
- package/dist/world/terrain.js +346 -28
- package/dist/world/terrainGuides.d.ts +182 -0
- package/dist/world/terrainGuides.js +343 -0
- package/dist/world/vec2.d.ts +81 -0
- package/dist/world/vec2.js +128 -0
- package/dist/world/vec3.d.ts +49 -0
- package/dist/world/vec3.js +76 -0
- package/dist/world/vegetation.d.ts +71 -0
- package/dist/world/vegetation.js +151 -0
- package/dist/world/visibilityField.d.ts +154 -0
- package/dist/world/visibilityField.js +271 -0
- package/dist/world/volumetricClouds.d.ts +52 -0
- package/dist/world/volumetricClouds.js +43 -0
- package/dist/world/walls.d.ts +9 -0
- package/dist/world/walls.js +9 -0
- package/dist/world/waterKind.d.ts +55 -0
- package/dist/world/waterKind.js +99 -0
- package/dist/world.d.ts +132 -0
- package/dist/world.js +132 -0
- package/package.json +32 -8
- package/skills/jgengine/SKILL.md +51 -0
- package/skills/jgengine/api.md +434 -0
- package/skills/jgengine/capabilities.md +29 -0
- package/skills/jgengine/reference-cartridge.md +72 -0
- package/skills/jgengine-combat/SKILL.md +34 -0
- package/skills/jgengine-combat/api.md +549 -0
- package/skills/jgengine-combat/capabilities.md +169 -0
- package/skills/jgengine-combat/reference.md +98 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1794 -0
- package/skills/jgengine-gameplay/capabilities.md +378 -0
- package/skills/jgengine-gameplay/reference-systems.md +60 -0
- package/skills/jgengine-world/SKILL.md +38 -0
- package/skills/jgengine-world/api.md +2652 -0
- package/skills/jgengine-world/capabilities.md +370 -0
- package/skills/jgengine-world/reference.md +222 -0
- package/dist/cartridge/runtime.d.ts +0 -15
- package/dist/cartridge/runtime.js +0 -556
- package/dist/cartridge/spec.d.ts +0 -188
- package/dist/cartridge/spec.js +0 -19
- package/dist/cartridge/validate.d.ts +0 -2
- package/dist/cartridge/validate.js +0 -78
- package/dist/store/engineStore.d.ts +0 -22
- package/dist/store/engineStore.js +0 -50
- package/dist/store/features.d.ts +0 -10
- package/dist/store/features.js +0 -23
- package/llms.txt +0 -4983
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export function createMotionIntents() {
|
|
2
3
|
let impulses = [];
|
|
3
4
|
let horizontalImpulses = [];
|
|
@@ -27,9 +28,33 @@ export function createMotionIntents() {
|
|
|
27
28
|
y = null;
|
|
28
29
|
return batch;
|
|
29
30
|
},
|
|
31
|
+
snapshot() {
|
|
32
|
+
return { impulses: [...impulses], horizontalImpulses: [...horizontalImpulses], verticalVelocity, y };
|
|
33
|
+
},
|
|
34
|
+
hydrate(batch) {
|
|
35
|
+
impulses = [...batch.impulses];
|
|
36
|
+
horizontalImpulses = batch.horizontalImpulses.map(([x, z]) => [x, z]);
|
|
37
|
+
verticalVelocity = batch.verticalVelocity;
|
|
38
|
+
y = batch.y;
|
|
39
|
+
},
|
|
30
40
|
};
|
|
31
41
|
}
|
|
32
|
-
/** Fold a batch's
|
|
42
|
+
/** Fold a batch's vertical impulses into a controller's velocity, then apply an outright `setVerticalVelocity` override — the vertical counterpart of {@link applyHorizontalImpulses}.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export function applyMotionImpulses(currentVelocity, batch) {
|
|
46
|
+
if (batch === null)
|
|
47
|
+
return currentVelocity;
|
|
48
|
+
let velocity = currentVelocity;
|
|
49
|
+
for (const impulse of batch.impulses)
|
|
50
|
+
velocity += impulse;
|
|
51
|
+
if (batch.verticalVelocity !== null)
|
|
52
|
+
velocity = batch.verticalVelocity;
|
|
53
|
+
return velocity;
|
|
54
|
+
}
|
|
55
|
+
/** Fold a batch's horizontal pushes into a controller's velocity pair — shared by the walk and voxel drivers.
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
33
58
|
export function applyHorizontalImpulses(velocityX, velocityZ, batch) {
|
|
34
59
|
if (batch === null || batch.horizontalImpulses.length === 0)
|
|
35
60
|
return [velocityX, velocityZ];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GameContext } from "./gameContext.js";
|
|
2
|
+
/**
|
|
3
|
+
* Per-`GameContext` lazy state, keyed by context identity through a `WeakMap` so it is reclaimed when
|
|
4
|
+
* the context is — the seam a game uses instead of a module-global `Map`, which is process-global and
|
|
5
|
+
* bleeds across worlds when one host serves several `serverId`s (#632). `init` runs once per distinct
|
|
6
|
+
* context on first access; the same context always resolves to the same value. This mirrors the engine's
|
|
7
|
+
* built-in per-ctx pattern (`ctx.player.motion`, `stepPlayerMovement`).
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const heroRuntimes = perContext(() => new Map<string, HeroRuntime>());
|
|
11
|
+
* // per world:
|
|
12
|
+
* heroRuntimes(ctx).set(userId, runtime);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare function perContext<T>(init: (ctx: GameContext) => T): (ctx: GameContext) => T;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-`GameContext` lazy state, keyed by context identity through a `WeakMap` so it is reclaimed when
|
|
3
|
+
* the context is — the seam a game uses instead of a module-global `Map`, which is process-global and
|
|
4
|
+
* bleeds across worlds when one host serves several `serverId`s (#632). `init` runs once per distinct
|
|
5
|
+
* context on first access; the same context always resolves to the same value. This mirrors the engine's
|
|
6
|
+
* built-in per-ctx pattern (`ctx.player.motion`, `stepPlayerMovement`).
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const heroRuntimes = perContext(() => new Map<string, HeroRuntime>());
|
|
10
|
+
* // per world:
|
|
11
|
+
* heroRuntimes(ctx).set(userId, runtime);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function perContext(init) {
|
|
15
|
+
const byContext = new WeakMap();
|
|
16
|
+
return (ctx) => {
|
|
17
|
+
if (!byContext.has(ctx))
|
|
18
|
+
byContext.set(ctx, init(ctx));
|
|
19
|
+
return byContext.get(ctx);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type SaveBackend, type SaveStatus, type SaveTimers } from "../game/saveStore.js";
|
|
2
|
+
import type { WorldSnapshot } from "./worldSnapshot.js";
|
|
3
|
+
/**
|
|
4
|
+
* The narrow slice of a live `GameContext` a runtime save reads and writes — a
|
|
5
|
+
* `GameContext` satisfies it directly (`ctx.snapshot`/`ctx.hydrate`/`ctx.subscribe`).
|
|
6
|
+
* Depending on this instead of the full context keeps the save controller a deep,
|
|
7
|
+
* decoupled module: it captures and restores the *whole* opted-in world without
|
|
8
|
+
* knowing any subsystem.
|
|
9
|
+
*/
|
|
10
|
+
export interface RuntimeSaveTarget {
|
|
11
|
+
snapshot(): WorldSnapshot;
|
|
12
|
+
hydrate(snapshot: WorldSnapshot): void;
|
|
13
|
+
subscribe(listener: () => void): () => void;
|
|
14
|
+
}
|
|
15
|
+
/** `"autosave"` writes a fresh capture on a debounce after any world change; `"manual"` writes only on an explicit `save()`/`checkpoint()` — the save-point / quest-trigger model. */
|
|
16
|
+
export type RuntimeSaveMode = "autosave" | "manual";
|
|
17
|
+
/** How {@link createRuntimeSave} is wired — the live world `target`, the `backend` it persists through, and optional mode/slot/versioning/cadence knobs. */
|
|
18
|
+
export interface RuntimeSaveConfig {
|
|
19
|
+
/** The live world to capture from and restore into — pass the `GameContext`. */
|
|
20
|
+
target: RuntimeSaveTarget;
|
|
21
|
+
/** Where the save lives — `localSaveBackend()` (offline) or a cloud/Convex backend; the only thing that changes between offline and cloud. */
|
|
22
|
+
backend: SaveBackend;
|
|
23
|
+
/** `"autosave"` (default) persists on world change; `"manual"` only when the game calls `save()`/`checkpoint()`. */
|
|
24
|
+
mode?: RuntimeSaveMode;
|
|
25
|
+
/** Storage namespace. Default `"runtime"`. */
|
|
26
|
+
key?: string;
|
|
27
|
+
/** Active save slot. Default `"default"`. */
|
|
28
|
+
slot?: string;
|
|
29
|
+
/** Save-format version; bump + pass {@link migrate} on a breaking world-shape change. */
|
|
30
|
+
version?: number;
|
|
31
|
+
migrate?: (data: unknown, fromVersion: number) => WorldSnapshot;
|
|
32
|
+
/** Debounce for `autosave` mode. Default `3000`. */
|
|
33
|
+
autosaveMs?: number;
|
|
34
|
+
now?: () => number;
|
|
35
|
+
timers?: SaveTimers;
|
|
36
|
+
onError?: (error: unknown) => void;
|
|
37
|
+
}
|
|
38
|
+
/** {@link RuntimeSaveConfig} without `target` — what a host (`createGameContext`) accepts to build `ctx.game.save` and bind it to the context itself. */
|
|
39
|
+
export type RuntimeSaveOptions = Omit<RuntimeSaveConfig, "target">;
|
|
40
|
+
/**
|
|
41
|
+
* Whole-world save/load bound to a live world and a pluggable backend. `save()`
|
|
42
|
+
* captures `target.snapshot()` and writes it; `load()` reads it back and
|
|
43
|
+
* `target.hydrate()`s the whole world. In `autosave` mode it also writes on a
|
|
44
|
+
* debounce after any change. Named slots, versioned migration, and offline↔cloud
|
|
45
|
+
* (backend swap) all come for free from the underlying save store.
|
|
46
|
+
*/
|
|
47
|
+
export interface RuntimeSave {
|
|
48
|
+
status(): SaveStatus;
|
|
49
|
+
slot(): string;
|
|
50
|
+
/** Capture the live world and persist it now (serialized against any in-flight write). */
|
|
51
|
+
save(): Promise<void>;
|
|
52
|
+
/** Semantic alias for `save()` — call it from a save point, a quest-complete or area-enter handler. */
|
|
53
|
+
checkpoint(): Promise<void>;
|
|
54
|
+
/** Load the active slot and hydrate the whole world; resolves `true` when a real save was applied, `false` for an empty slot. */
|
|
55
|
+
load(): Promise<boolean>;
|
|
56
|
+
/** Whether the active slot holds a saved world — gate a title-screen "Continue" on it. */
|
|
57
|
+
hasSave(): Promise<boolean>;
|
|
58
|
+
/** Delete the active slot's save. */
|
|
59
|
+
clear(): Promise<void>;
|
|
60
|
+
/** Switch slot and load it, hydrating the world when that slot has a save. */
|
|
61
|
+
switchSlot(slot: string): Promise<boolean>;
|
|
62
|
+
/** The slots this game has written — back a load/save menu. */
|
|
63
|
+
slots(): Promise<string[]>;
|
|
64
|
+
subscribe(listener: () => void): () => void;
|
|
65
|
+
/** Stop autosave and release the world subscription. */
|
|
66
|
+
dispose(): void;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Bridge a live world to a pluggable save backend: whole-state capture/restore
|
|
70
|
+
* with autosave, save points, named slots, and versioned migration — the same
|
|
71
|
+
* call for offline (localStorage) and cloud (Convex), only the `backend`
|
|
72
|
+
* differs. The game keeps control of *when* it saves (the `mode` plus explicit
|
|
73
|
+
* `checkpoint()` calls from quests/areas) and *when* it restores (`load()` on
|
|
74
|
+
* boot), so any save mechanic — continuous autosave, manual save points,
|
|
75
|
+
* checkpoint triggers — is expressible without new engine code.
|
|
76
|
+
*
|
|
77
|
+
* @capability runtime-save save/load the whole game world through a pluggable backend, autosave or save points
|
|
78
|
+
*/
|
|
79
|
+
export declare function createRuntimeSave(config: RuntimeSaveConfig): RuntimeSave;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { createSaveStore, } from "../game/saveStore.js";
|
|
2
|
+
function defaultTimers() {
|
|
3
|
+
return {
|
|
4
|
+
set: (handler, ms) => globalThis.setTimeout(handler, ms),
|
|
5
|
+
clear: (handle) => globalThis.clearTimeout(handle),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function hasContent(snapshot) {
|
|
9
|
+
for (const _key in snapshot)
|
|
10
|
+
return true;
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Bridge a live world to a pluggable save backend: whole-state capture/restore
|
|
15
|
+
* with autosave, save points, named slots, and versioned migration — the same
|
|
16
|
+
* call for offline (localStorage) and cloud (Convex), only the `backend`
|
|
17
|
+
* differs. The game keeps control of *when* it saves (the `mode` plus explicit
|
|
18
|
+
* `checkpoint()` calls from quests/areas) and *when* it restores (`load()` on
|
|
19
|
+
* boot), so any save mechanic — continuous autosave, manual save points,
|
|
20
|
+
* checkpoint triggers — is expressible without new engine code.
|
|
21
|
+
*
|
|
22
|
+
* @capability runtime-save save/load the whole game world through a pluggable backend, autosave or save points
|
|
23
|
+
*/
|
|
24
|
+
export function createRuntimeSave(config) {
|
|
25
|
+
const mode = config.mode ?? "autosave";
|
|
26
|
+
const autosaveMs = config.autosaveMs ?? 3000;
|
|
27
|
+
const timers = config.timers ?? defaultTimers();
|
|
28
|
+
const store = createSaveStore({
|
|
29
|
+
backend: config.backend,
|
|
30
|
+
initial: {},
|
|
31
|
+
key: config.key ?? "runtime",
|
|
32
|
+
slot: config.slot,
|
|
33
|
+
version: config.version,
|
|
34
|
+
migrate: config.migrate,
|
|
35
|
+
autosave: false,
|
|
36
|
+
now: config.now,
|
|
37
|
+
onError: config.onError,
|
|
38
|
+
});
|
|
39
|
+
let pendingTimer = null;
|
|
40
|
+
let unsubscribe = null;
|
|
41
|
+
let disposed = false;
|
|
42
|
+
let restoring = false;
|
|
43
|
+
function clearTimer() {
|
|
44
|
+
if (pendingTimer !== null) {
|
|
45
|
+
timers.clear(pendingTimer);
|
|
46
|
+
pendingTimer = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function persist() {
|
|
50
|
+
clearTimer();
|
|
51
|
+
store.set(config.target.snapshot());
|
|
52
|
+
return store.save();
|
|
53
|
+
}
|
|
54
|
+
function scheduleAutosave() {
|
|
55
|
+
if (disposed || restoring)
|
|
56
|
+
return;
|
|
57
|
+
clearTimer();
|
|
58
|
+
pendingTimer = timers.set(() => {
|
|
59
|
+
pendingTimer = null;
|
|
60
|
+
void persist();
|
|
61
|
+
}, autosaveMs);
|
|
62
|
+
}
|
|
63
|
+
if (mode === "autosave") {
|
|
64
|
+
unsubscribe = config.target.subscribe(scheduleAutosave);
|
|
65
|
+
}
|
|
66
|
+
function applyLoaded(snapshot) {
|
|
67
|
+
if (!hasContent(snapshot))
|
|
68
|
+
return false;
|
|
69
|
+
restoring = true;
|
|
70
|
+
try {
|
|
71
|
+
config.target.hydrate(snapshot);
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
restoring = false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
const save = () => persist();
|
|
79
|
+
return {
|
|
80
|
+
status: () => store.status(),
|
|
81
|
+
slot: () => store.slot(),
|
|
82
|
+
save,
|
|
83
|
+
checkpoint: save,
|
|
84
|
+
async load() {
|
|
85
|
+
return applyLoaded(await store.load());
|
|
86
|
+
},
|
|
87
|
+
async hasSave() {
|
|
88
|
+
return hasContent(await store.load());
|
|
89
|
+
},
|
|
90
|
+
clear: () => store.clear(),
|
|
91
|
+
async switchSlot(slot) {
|
|
92
|
+
clearTimer();
|
|
93
|
+
return applyLoaded(await store.switchSlot(slot));
|
|
94
|
+
},
|
|
95
|
+
slots: () => store.slots(),
|
|
96
|
+
subscribe: (listener) => store.subscribe(listener),
|
|
97
|
+
dispose() {
|
|
98
|
+
disposed = true;
|
|
99
|
+
clearTimer();
|
|
100
|
+
if (unsubscribe !== null)
|
|
101
|
+
unsubscribe();
|
|
102
|
+
store.dispose();
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
package/dist/runtime/save.d.ts
CHANGED
|
@@ -3,7 +3,11 @@ export type SaveConfig = "none" | {
|
|
|
3
3
|
auto: string;
|
|
4
4
|
scope: SaveScope;
|
|
5
5
|
};
|
|
6
|
+
/** @internal */
|
|
6
7
|
export declare function parseSaveAutoMs(auto: string): number;
|
|
8
|
+
/** @internal */
|
|
7
9
|
export declare function saveScopeIncludesPlayer(scope: SaveScope): boolean;
|
|
10
|
+
/** @internal */
|
|
8
11
|
export declare function saveScopeIncludesChunks(scope: SaveScope): boolean;
|
|
12
|
+
/** @internal */
|
|
9
13
|
export declare function isSaveEnabled(config: SaveConfig): config is Exclude<SaveConfig, "none">;
|
package/dist/runtime/save.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export function parseSaveAutoMs(auto) {
|
|
2
3
|
const match = /^(\d+(?:\.\d+)?)(ms|s|m|h)$/.exec(auto.trim());
|
|
3
4
|
if (!match) {
|
|
@@ -18,12 +19,15 @@ export function parseSaveAutoMs(auto) {
|
|
|
18
19
|
throw new Error(`Invalid save.auto unit: ${unit}`);
|
|
19
20
|
}
|
|
20
21
|
}
|
|
22
|
+
/** @internal */
|
|
21
23
|
export function saveScopeIncludesPlayer(scope) {
|
|
22
24
|
return scope === "player" || scope === "player+chunks";
|
|
23
25
|
}
|
|
26
|
+
/** @internal */
|
|
24
27
|
export function saveScopeIncludesChunks(scope) {
|
|
25
28
|
return scope === "chunks" || scope === "player+chunks";
|
|
26
29
|
}
|
|
30
|
+
/** @internal */
|
|
27
31
|
export function isSaveEnabled(config) {
|
|
28
32
|
return config !== "none";
|
|
29
33
|
}
|
|
@@ -69,8 +69,11 @@ export type GameRuntimeSnapshot = {
|
|
|
69
69
|
chunks: string[];
|
|
70
70
|
};
|
|
71
71
|
};
|
|
72
|
+
/** @internal */
|
|
72
73
|
export declare function createEmptyServerRow(): RuntimeServerRow;
|
|
74
|
+
/** @internal */
|
|
73
75
|
export declare function createEmptyPlayerRow(userId: string): RuntimePlayerRow;
|
|
76
|
+
/** @internal */
|
|
74
77
|
export declare function createRuntimeSnapshot(args: {
|
|
75
78
|
gameId: string;
|
|
76
79
|
serverId: string;
|
|
@@ -79,9 +82,13 @@ export declare function createRuntimeSnapshot(args: {
|
|
|
79
82
|
chunks?: Record<string, RuntimeChunkRow>;
|
|
80
83
|
revision?: number;
|
|
81
84
|
}): GameRuntimeSnapshot;
|
|
85
|
+
/** @internal */
|
|
82
86
|
export declare function markServerDirty(snapshot: GameRuntimeSnapshot): GameRuntimeSnapshot;
|
|
87
|
+
/** @internal */
|
|
83
88
|
export declare function markPlayerDirty(snapshot: GameRuntimeSnapshot, userId: string): GameRuntimeSnapshot;
|
|
89
|
+
/** @internal */
|
|
84
90
|
export declare function clearDirtyFlags(snapshot: GameRuntimeSnapshot): GameRuntimeSnapshot;
|
|
91
|
+
/** @internal */
|
|
85
92
|
export declare function splitProfilePlayer(player: RuntimePlayerRow): {
|
|
86
93
|
persistent: RuntimePlayerRow;
|
|
87
94
|
session: Record<string, unknown>;
|
package/dist/runtime/snapshot.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const RUNTIME_SNAPSHOT_VERSION = 1;
|
|
2
|
+
/** @internal */
|
|
2
3
|
export function createEmptyServerRow() {
|
|
3
4
|
return {
|
|
4
5
|
entities: [],
|
|
@@ -7,6 +8,7 @@ export function createEmptyServerRow() {
|
|
|
7
8
|
feeds: {},
|
|
8
9
|
};
|
|
9
10
|
}
|
|
11
|
+
/** @internal */
|
|
10
12
|
export function createEmptyPlayerRow(userId) {
|
|
11
13
|
return {
|
|
12
14
|
userId,
|
|
@@ -16,6 +18,7 @@ export function createEmptyPlayerRow(userId) {
|
|
|
16
18
|
session: {},
|
|
17
19
|
};
|
|
18
20
|
}
|
|
21
|
+
/** @internal */
|
|
19
22
|
export function createRuntimeSnapshot(args) {
|
|
20
23
|
return {
|
|
21
24
|
version: RUNTIME_SNAPSHOT_VERSION,
|
|
@@ -32,6 +35,7 @@ export function createRuntimeSnapshot(args) {
|
|
|
32
35
|
},
|
|
33
36
|
};
|
|
34
37
|
}
|
|
38
|
+
/** @internal */
|
|
35
39
|
export function markServerDirty(snapshot) {
|
|
36
40
|
return {
|
|
37
41
|
...snapshot,
|
|
@@ -39,6 +43,7 @@ export function markServerDirty(snapshot) {
|
|
|
39
43
|
dirty: { ...snapshot.dirty, server: true },
|
|
40
44
|
};
|
|
41
45
|
}
|
|
46
|
+
/** @internal */
|
|
42
47
|
export function markPlayerDirty(snapshot, userId) {
|
|
43
48
|
if (snapshot.dirty.players.includes(userId)) {
|
|
44
49
|
return markServerDirty(snapshot);
|
|
@@ -53,6 +58,7 @@ export function markPlayerDirty(snapshot, userId) {
|
|
|
53
58
|
},
|
|
54
59
|
};
|
|
55
60
|
}
|
|
61
|
+
/** @internal */
|
|
56
62
|
export function clearDirtyFlags(snapshot) {
|
|
57
63
|
return {
|
|
58
64
|
...snapshot,
|
|
@@ -63,6 +69,7 @@ export function clearDirtyFlags(snapshot) {
|
|
|
63
69
|
},
|
|
64
70
|
};
|
|
65
71
|
}
|
|
72
|
+
/** @internal */
|
|
66
73
|
export function splitProfilePlayer(player) {
|
|
67
74
|
const { session = {}, ...persistentFields } = player;
|
|
68
75
|
return {
|
|
@@ -62,7 +62,8 @@ export interface VisibilityDecision {
|
|
|
62
62
|
*
|
|
63
63
|
* Render culling and asset streaming are intentionally separate. This class never
|
|
64
64
|
* destroys entities or throttles simulation; adapters decide how to apply results.
|
|
65
|
-
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
66
67
|
export declare class VisibilitySystem {
|
|
67
68
|
#private;
|
|
68
69
|
readonly settings: VisibilityDefaults;
|
|
@@ -23,7 +23,8 @@ function intersectsRadius(camera, bounds, extraMargin) {
|
|
|
23
23
|
*
|
|
24
24
|
* Render culling and asset streaming are intentionally separate. This class never
|
|
25
25
|
* destroys entities or throttles simulation; adapters decide how to apply results.
|
|
26
|
-
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
27
28
|
export class VisibilitySystem {
|
|
28
29
|
settings;
|
|
29
30
|
#states = new Map();
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { GameContext } from "./gameContext.js";
|
|
2
|
+
import type { InputFrame } from "./hostedGameRunner.js";
|
|
3
|
+
import type { HostedWorldSession } from "./hostedWorldSession.js";
|
|
4
|
+
import { type WorldDiff } from "./worldReplication.js";
|
|
5
|
+
import type { WorldSnapshot } from "./worldSnapshot.js";
|
|
6
|
+
/** Host→client frame: the full baseline a joiner needs, then per-tick diffs. What a transport marshals downstream. */
|
|
7
|
+
export type WorldServerFrame = {
|
|
8
|
+
t: "baseline";
|
|
9
|
+
revision: number;
|
|
10
|
+
snapshot: WorldSnapshot;
|
|
11
|
+
} | {
|
|
12
|
+
t: "diff";
|
|
13
|
+
diff: WorldDiff;
|
|
14
|
+
};
|
|
15
|
+
/** Client→host frame: a player's session verbs. What a transport marshals upstream. */
|
|
16
|
+
export type WorldClientFrame = {
|
|
17
|
+
t: "join";
|
|
18
|
+
isNew: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
t: "leave";
|
|
21
|
+
} | {
|
|
22
|
+
t: "command";
|
|
23
|
+
name: string;
|
|
24
|
+
input: unknown;
|
|
25
|
+
} | {
|
|
26
|
+
t: "input";
|
|
27
|
+
frame: InputFrame;
|
|
28
|
+
};
|
|
29
|
+
/** One client's link on the host side: routes its upstream frames into the shared session, pushes it sync frames. */
|
|
30
|
+
export interface WorldHostConnection {
|
|
31
|
+
receive(frame: WorldClientFrame): void;
|
|
32
|
+
push(): void;
|
|
33
|
+
close(): void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The transport-agnostic host: fans one {@link HostedWorldSession} out to many connections, each tracking its own
|
|
37
|
+
* revision cursor so a joiner gets a baseline and everyone else gets diffs. A ws server, a Convex function, or an
|
|
38
|
+
* in-process loopback all drive the same shape — decode a frame → `connection.receive`; after `session.tick` →
|
|
39
|
+
* `broadcast`. No wire format is assumed; frames are plain data a transport serializes however it likes.
|
|
40
|
+
*/
|
|
41
|
+
export interface WorldHost {
|
|
42
|
+
connect(userId: string, send: (frame: WorldServerFrame) => void): WorldHostConnection;
|
|
43
|
+
broadcast(): void;
|
|
44
|
+
session(): HostedWorldSession;
|
|
45
|
+
}
|
|
46
|
+
/** Build a {@link WorldHost} fanning one {@link HostedWorldSession} out to many cursor-tracked connections.
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
export declare function createWorldHost(session: HostedWorldSession): WorldHost;
|
|
50
|
+
/** The client end of a {@link WorldHost} connection: applies server frames to a local `ctx`, sends session verbs upstream. */
|
|
51
|
+
export interface WorldClientLink {
|
|
52
|
+
receive(frame: WorldServerFrame): void;
|
|
53
|
+
join(isNew: boolean): void;
|
|
54
|
+
leave(): void;
|
|
55
|
+
command(name: string, input: unknown): void;
|
|
56
|
+
input(frame: InputFrame): void;
|
|
57
|
+
revision(): number;
|
|
58
|
+
}
|
|
59
|
+
/** Build a {@link WorldClientLink} — the client end that mirrors host frames into `ctx` and sends session verbs upstream.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export declare function createWorldClientLink(ctx: Pick<GameContext, "hydrate">, send: (frame: WorldClientFrame) => void): WorldClientLink;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createWorldMirror } from "./worldMirror.js";
|
|
2
|
+
import { diffSnapshots } from "./worldReplication.js";
|
|
3
|
+
/** Build a {@link WorldHost} fanning one {@link HostedWorldSession} out to many cursor-tracked connections.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export function createWorldHost(session) {
|
|
7
|
+
const connections = new Set();
|
|
8
|
+
const connectionsByUser = new Map();
|
|
9
|
+
const perViewer = session.projectsViewers();
|
|
10
|
+
function connect(userId, send) {
|
|
11
|
+
let cursor = 0;
|
|
12
|
+
let released = false;
|
|
13
|
+
let viewerSnapshot = null;
|
|
14
|
+
let viewerRevision = 0;
|
|
15
|
+
function release() {
|
|
16
|
+
if (released)
|
|
17
|
+
return;
|
|
18
|
+
released = true;
|
|
19
|
+
connections.delete(connection);
|
|
20
|
+
const peers = connectionsByUser.get(userId);
|
|
21
|
+
if (peers === undefined)
|
|
22
|
+
return;
|
|
23
|
+
peers.delete(connection);
|
|
24
|
+
if (peers.size === 0) {
|
|
25
|
+
connectionsByUser.delete(userId);
|
|
26
|
+
session.leave(userId);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const connection = {
|
|
30
|
+
receive(frame) {
|
|
31
|
+
switch (frame.t) {
|
|
32
|
+
case "join":
|
|
33
|
+
session.join(userId, frame.isNew);
|
|
34
|
+
break;
|
|
35
|
+
case "leave":
|
|
36
|
+
release();
|
|
37
|
+
break;
|
|
38
|
+
case "command":
|
|
39
|
+
session.command(userId, frame.name, frame.input);
|
|
40
|
+
break;
|
|
41
|
+
case "input":
|
|
42
|
+
session.input(userId, frame.frame);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
push() {
|
|
47
|
+
if (released)
|
|
48
|
+
return;
|
|
49
|
+
if (perViewer) {
|
|
50
|
+
const revision = session.revision();
|
|
51
|
+
if (viewerSnapshot !== null && revision === viewerRevision)
|
|
52
|
+
return;
|
|
53
|
+
const snapshot = session.snapshotFor({ userId });
|
|
54
|
+
if (viewerSnapshot === null) {
|
|
55
|
+
send({ t: "baseline", revision, snapshot });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
send({ t: "diff", diff: diffSnapshots(viewerSnapshot, snapshot, revision, viewerRevision) });
|
|
59
|
+
}
|
|
60
|
+
viewerSnapshot = snapshot;
|
|
61
|
+
viewerRevision = revision;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (cursor !== 0 && cursor === session.revision())
|
|
65
|
+
return;
|
|
66
|
+
const sync = session.sync(cursor === 0 ? null : cursor);
|
|
67
|
+
if (sync.kind === "baseline") {
|
|
68
|
+
cursor = sync.revision;
|
|
69
|
+
send({ t: "baseline", revision: sync.revision, snapshot: sync.snapshot });
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
cursor = sync.diff.revision;
|
|
73
|
+
send({ t: "diff", diff: sync.diff });
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
close: release,
|
|
77
|
+
};
|
|
78
|
+
connections.add(connection);
|
|
79
|
+
let peers = connectionsByUser.get(userId);
|
|
80
|
+
if (peers === undefined) {
|
|
81
|
+
peers = new Set();
|
|
82
|
+
connectionsByUser.set(userId, peers);
|
|
83
|
+
}
|
|
84
|
+
peers.add(connection);
|
|
85
|
+
return connection;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
connect,
|
|
89
|
+
broadcast() {
|
|
90
|
+
for (const connection of connections)
|
|
91
|
+
connection.push();
|
|
92
|
+
},
|
|
93
|
+
session: () => session,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Build a {@link WorldClientLink} — the client end that mirrors host frames into `ctx` and sends session verbs upstream.
|
|
97
|
+
* @internal
|
|
98
|
+
*/
|
|
99
|
+
export function createWorldClientLink(ctx, send) {
|
|
100
|
+
const mirror = createWorldMirror(ctx);
|
|
101
|
+
return {
|
|
102
|
+
receive(frame) {
|
|
103
|
+
if (frame.t === "baseline")
|
|
104
|
+
mirror.applyBaseline(frame.revision, frame.snapshot);
|
|
105
|
+
else
|
|
106
|
+
mirror.applyDiff(frame.diff);
|
|
107
|
+
},
|
|
108
|
+
join: (isNew) => send({ t: "join", isNew }),
|
|
109
|
+
leave: () => send({ t: "leave" }),
|
|
110
|
+
command: (name, input) => send({ t: "command", name, input }),
|
|
111
|
+
input: (frame) => send({ t: "input", frame }),
|
|
112
|
+
revision: () => mirror.revision(),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { GameContext } from "./gameContext.js";
|
|
2
|
+
import type { HostedWorldSession } from "./hostedWorldSession.js";
|
|
3
|
+
import { type WorldDiff } from "./worldReplication.js";
|
|
4
|
+
import type { WorldSnapshot } from "./worldSnapshot.js";
|
|
5
|
+
/**
|
|
6
|
+
* The client end of host-authoritative replication: folds a host's baseline + {@link WorldDiff} stream onto a
|
|
7
|
+
* local {@link GameContext}. It keeps the last full {@link WorldSnapshot}, advances it with each diff, and pushes
|
|
8
|
+
* the result through `ctx.hydrate` — so the client mirrors exactly the subsystems its own game opted into and
|
|
9
|
+
* silently ignores host modules it lacks. This is the inverse of a {@link HostedWorldSession}; the transport in
|
|
10
|
+
* between (loopback, ws, Convex) is irrelevant.
|
|
11
|
+
*/
|
|
12
|
+
export interface WorldMirror {
|
|
13
|
+
applyBaseline(revision: number, snapshot: WorldSnapshot): void;
|
|
14
|
+
/**
|
|
15
|
+
* Fold one {@link WorldDiff} onto the mirror. A diff whose `revision` doesn't advance past the mirror's own
|
|
16
|
+
* (stale or a duplicate resend) is ignored. A diff carrying `baseRevision` that doesn't match the mirror's
|
|
17
|
+
* current revision means frames were skipped in transit — the diff is ignored and {@link needsResync} flips
|
|
18
|
+
* true until the next {@link applyBaseline} instead of folding a gap onto local state. A diff without
|
|
19
|
+
* `baseRevision` (legacy producer) always applies, matching the pre-revision-checking behavior.
|
|
20
|
+
*/
|
|
21
|
+
applyDiff(diff: WorldDiff): void;
|
|
22
|
+
revision(): number;
|
|
23
|
+
/** True after `applyDiff` detected a skipped revision; the caller should fetch a fresh baseline instead of more diffs. */
|
|
24
|
+
needsResync(): boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Build a {@link WorldMirror} that replicates a host's baseline + diff stream onto `ctx` via `ctx.hydrate`.
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
export declare function createWorldMirror(ctx: Pick<GameContext, "hydrate">): WorldMirror;
|
|
30
|
+
/**
|
|
31
|
+
* Pull one replication step from a co-located {@link HostedWorldSession} into a {@link WorldMirror} — the
|
|
32
|
+
* no-network local path (host and client in one process). A fresh mirror pulls a baseline; thereafter it pulls
|
|
33
|
+
* a diff since its own revision. The same `sync(sinceRevision)` call is what a networked transport marshals.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export declare function pullWorld(session: HostedWorldSession, mirror: WorldMirror): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { applyWorldDiff } from "./worldReplication.js";
|
|
2
|
+
/** Build a {@link WorldMirror} that replicates a host's baseline + diff stream onto `ctx` via `ctx.hydrate`.
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export function createWorldMirror(ctx) {
|
|
6
|
+
let mirror = {};
|
|
7
|
+
let revision = 0;
|
|
8
|
+
let resyncNeeded = false;
|
|
9
|
+
return {
|
|
10
|
+
applyBaseline(nextRevision, snapshot) {
|
|
11
|
+
mirror = snapshot;
|
|
12
|
+
revision = nextRevision;
|
|
13
|
+
resyncNeeded = false;
|
|
14
|
+
ctx.hydrate(snapshot);
|
|
15
|
+
},
|
|
16
|
+
applyDiff(diff) {
|
|
17
|
+
if (diff.revision <= revision)
|
|
18
|
+
return;
|
|
19
|
+
if (diff.baseRevision !== undefined && diff.baseRevision !== revision) {
|
|
20
|
+
resyncNeeded = true;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
resyncNeeded = false;
|
|
24
|
+
mirror = applyWorldDiff(mirror, diff);
|
|
25
|
+
revision = diff.revision;
|
|
26
|
+
ctx.hydrate(mirror);
|
|
27
|
+
},
|
|
28
|
+
revision: () => revision,
|
|
29
|
+
needsResync: () => resyncNeeded,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Pull one replication step from a co-located {@link HostedWorldSession} into a {@link WorldMirror} — the
|
|
34
|
+
* no-network local path (host and client in one process). A fresh mirror pulls a baseline; thereafter it pulls
|
|
35
|
+
* a diff since its own revision. The same `sync(sinceRevision)` call is what a networked transport marshals.
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export function pullWorld(session, mirror) {
|
|
39
|
+
const sync = session.sync(mirror.revision() === 0 ? null : mirror.revision());
|
|
40
|
+
if (sync.kind === "baseline")
|
|
41
|
+
mirror.applyBaseline(sync.revision, sync.snapshot);
|
|
42
|
+
else
|
|
43
|
+
mirror.applyDiff(sync.diff);
|
|
44
|
+
}
|