@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,47 @@
|
|
|
1
|
+
import type { SceneEntity } from "../scene/entityStore.js";
|
|
2
|
+
import type { SnapshotViewer } from "./worldSnapshot.js";
|
|
3
|
+
/**
|
|
4
|
+
* Host-side interest/privacy policy — how the authoritative world projects to each viewer over the
|
|
5
|
+
* wire. Unset (the default) means every client receives the whole world, exactly as before. Enabling a
|
|
6
|
+
* field changes only what each client *sees*, never how the host simulates: the game plays identically.
|
|
7
|
+
* The core replication modules read this to attach a {@link SnapshotModule.project} without the engine
|
|
8
|
+
* growing a per-feature branch.
|
|
9
|
+
*/
|
|
10
|
+
export interface ReplicationPolicy {
|
|
11
|
+
/**
|
|
12
|
+
* Replicate each player's private per-user state (inventory) only to that player — other viewers
|
|
13
|
+
* receive none of it. Off by default so existing games keep broadcasting every player's state.
|
|
14
|
+
*/
|
|
15
|
+
privatePerUser?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Area-of-interest radius in world units: an entity replicates to a viewer only when within this
|
|
18
|
+
* distance of the viewer's own entity (the entity whose `id` equals the viewer's `userId`). A viewer
|
|
19
|
+
* always receives its own entity. Omit for no distance culling — every entity to every viewer.
|
|
20
|
+
*/
|
|
21
|
+
aoiRadius?: number;
|
|
22
|
+
}
|
|
23
|
+
/** True when at least one field of the policy would change the wire payload. A no-op policy needs no projection.
|
|
24
|
+
* @internal host projection plumbing — games set ReplicationPolicy; the runtime applies it.
|
|
25
|
+
*/
|
|
26
|
+
export declare function policyProjectsViewers(policy: ReplicationPolicy | undefined): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Cull an entity list to a viewer's area of interest: keep the viewer's own entity plus every entity
|
|
29
|
+
* within `radius` of it. When the viewer has no locatable entity the full list is returned (fail-open —
|
|
30
|
+
* a spectator or not-yet-spawned player still sees the world rather than an empty one).
|
|
31
|
+
* @internal host projection plumbing
|
|
32
|
+
*/
|
|
33
|
+
export declare function projectEntitiesForViewer(entities: readonly SceneEntity[], viewer: SnapshotViewer, radius: number): readonly SceneEntity[];
|
|
34
|
+
/** The set of entity ids a viewer can see under an area-of-interest radius — the visibility set entity-keyed modules cull against.
|
|
35
|
+
* @internal host projection plumbing
|
|
36
|
+
*/
|
|
37
|
+
export declare function visibleEntityIds(entities: readonly SceneEntity[], viewer: SnapshotViewer, radius: number): Set<string>;
|
|
38
|
+
/** Keep only the entries of an entity-id-keyed record whose id is in `visible` — the projection for entity stats under area-of-interest.
|
|
39
|
+
* @internal host projection plumbing
|
|
40
|
+
*/
|
|
41
|
+
export declare function projectByVisibleIds<T>(byId: Record<string, T>, visible: Set<string>): Record<string, T>;
|
|
42
|
+
/**
|
|
43
|
+
* Narrow a `userId → state` record to only the viewer's own entry — the projection for private
|
|
44
|
+
* per-user state (inventory, wallets) so one client never receives another player's private data.
|
|
45
|
+
* @internal host projection plumbing
|
|
46
|
+
*/
|
|
47
|
+
export declare function projectPerUserForViewer<T>(byUser: Record<string, T>, viewer: SnapshotViewer): Record<string, T>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** True when at least one field of the policy would change the wire payload. A no-op policy needs no projection.
|
|
2
|
+
* @internal host projection plumbing — games set ReplicationPolicy; the runtime applies it.
|
|
3
|
+
*/
|
|
4
|
+
export function policyProjectsViewers(policy) {
|
|
5
|
+
if (policy === undefined)
|
|
6
|
+
return false;
|
|
7
|
+
return policy.privatePerUser === true || policy.aoiRadius !== undefined;
|
|
8
|
+
}
|
|
9
|
+
function distanceSquared(a, b) {
|
|
10
|
+
const dx = a[0] - b[0];
|
|
11
|
+
const dy = a[1] - b[1];
|
|
12
|
+
const dz = a[2] - b[2];
|
|
13
|
+
return dx * dx + dy * dy + dz * dz;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Cull an entity list to a viewer's area of interest: keep the viewer's own entity plus every entity
|
|
17
|
+
* within `radius` of it. When the viewer has no locatable entity the full list is returned (fail-open —
|
|
18
|
+
* a spectator or not-yet-spawned player still sees the world rather than an empty one).
|
|
19
|
+
* @internal host projection plumbing
|
|
20
|
+
*/
|
|
21
|
+
export function projectEntitiesForViewer(entities, viewer, radius) {
|
|
22
|
+
const self = entities.find((entity) => entity.id === viewer.userId);
|
|
23
|
+
if (self === undefined)
|
|
24
|
+
return entities;
|
|
25
|
+
const radiusSquared = radius * radius;
|
|
26
|
+
return entities.filter((entity) => entity.id === viewer.userId || distanceSquared(entity.position, self.position) <= radiusSquared);
|
|
27
|
+
}
|
|
28
|
+
/** The set of entity ids a viewer can see under an area-of-interest radius — the visibility set entity-keyed modules cull against.
|
|
29
|
+
* @internal host projection plumbing
|
|
30
|
+
*/
|
|
31
|
+
export function visibleEntityIds(entities, viewer, radius) {
|
|
32
|
+
return new Set(projectEntitiesForViewer(entities, viewer, radius).map((entity) => entity.id));
|
|
33
|
+
}
|
|
34
|
+
/** Keep only the entries of an entity-id-keyed record whose id is in `visible` — the projection for entity stats under area-of-interest.
|
|
35
|
+
* @internal host projection plumbing
|
|
36
|
+
*/
|
|
37
|
+
export function projectByVisibleIds(byId, visible) {
|
|
38
|
+
const out = {};
|
|
39
|
+
for (const [id, value] of Object.entries(byId))
|
|
40
|
+
if (visible.has(id))
|
|
41
|
+
out[id] = value;
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Narrow a `userId → state` record to only the viewer's own entry — the projection for private
|
|
46
|
+
* per-user state (inventory, wallets) so one client never receives another player's private data.
|
|
47
|
+
* @internal host projection plumbing
|
|
48
|
+
*/
|
|
49
|
+
export function projectPerUserForViewer(byUser, viewer) {
|
|
50
|
+
const own = byUser[viewer.userId];
|
|
51
|
+
return own === undefined ? {} : { [viewer.userId]: own };
|
|
52
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { SceneEntity } from "../scene/entityStore.js";
|
|
2
|
+
import type { StatValueMap } from "../scene/entityStats.js";
|
|
3
|
+
import type { WorldSnapshot } from "./worldSnapshot.js";
|
|
4
|
+
/**
|
|
5
|
+
* A revision-stamped delta over a {@link WorldSnapshot}. The host sends one per tick to each client, carrying
|
|
6
|
+
* only what changed since that client's last acknowledged revision — entity/stat/store deltas plus whole
|
|
7
|
+
* snapshots of any other opted-in module (feed, leaderboard, chat, …) that changed. Fold it onto a prior
|
|
8
|
+
* baseline with {@link applyWorldDiff}.
|
|
9
|
+
*/
|
|
10
|
+
export interface WorldDiff {
|
|
11
|
+
revision: number;
|
|
12
|
+
/**
|
|
13
|
+
* The revision this diff was computed against — `sinceRevision` echoed back. A {@link WorldMirror} only applies
|
|
14
|
+
* a diff whose `baseRevision` matches its own current revision exactly; a mismatch means frames were skipped and
|
|
15
|
+
* the mirror must resync from a fresh baseline instead of silently drifting. Absent on a diff built by an older
|
|
16
|
+
* producer — treated as legacy and always applied, matching pre-revision-checking behavior.
|
|
17
|
+
*/
|
|
18
|
+
baseRevision?: number;
|
|
19
|
+
entities: readonly SceneEntity[];
|
|
20
|
+
removedEntities: readonly string[];
|
|
21
|
+
stats: Record<string, StatValueMap>;
|
|
22
|
+
removedStats: readonly string[];
|
|
23
|
+
store: readonly (readonly [string, unknown])[];
|
|
24
|
+
removedStore: readonly string[];
|
|
25
|
+
/** Changed whole-module snapshots keyed by module name — everything a client can't reconstruct from deltas. */
|
|
26
|
+
modules: WorldSnapshot;
|
|
27
|
+
/** Module keys present in a prior baseline that no longer exist — a client drops them wholesale on apply. */
|
|
28
|
+
removedModules: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Optional acceleration for {@link createWorldReplicator}: a monotone world-dirty counter (aggregated from
|
|
32
|
+
* each {@link SnapshotModule.version}). When it hasn't advanced since the last commit nothing mutated, so the
|
|
33
|
+
* replicator skips re-reading and re-serializing the whole world — the change-detection short-circuit item #28
|
|
34
|
+
* asks for. Omit it (or pass a snapshot-only source) to keep the original full-re-serialize-per-commit behavior.
|
|
35
|
+
*/
|
|
36
|
+
export interface WorldReplicatorOptions {
|
|
37
|
+
worldVersion?: () => number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Turns successive full {@link WorldSnapshot}s into per-client {@link WorldDiff}s. Each `commit()` re-reads the
|
|
41
|
+
* world, stamps every item that changed with the new revision, and remembers removals; `diff(sinceRevision)`
|
|
42
|
+
* then replays exactly the items stamped after that revision. Everything the tracker holds is JSON — the same
|
|
43
|
+
* shape that rides the wire — so a diff is inherently serializable. Change-detection is a full re-serialize per
|
|
44
|
+
* commit unless {@link WorldReplicatorOptions.worldVersion} lets an unchanged tick short-circuit before it.
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export declare function createWorldReplicator(takeSnapshot: () => WorldSnapshot, options?: WorldReplicatorOptions): {
|
|
48
|
+
commit: () => number;
|
|
49
|
+
diff: (sinceRevision: number) => WorldDiff;
|
|
50
|
+
revision: () => number;
|
|
51
|
+
};
|
|
52
|
+
/** The stateful diff tracker returned by {@link createWorldReplicator}: `commit()`, `diff(sinceRevision)`, `revision()`. */
|
|
53
|
+
export type WorldReplicator = ReturnType<typeof createWorldReplicator>;
|
|
54
|
+
/**
|
|
55
|
+
* Diff two full {@link WorldSnapshot}s directly, stamping the result at `revision` — the stateless counterpart of
|
|
56
|
+
* {@link createWorldReplicator} for hosts that persist snapshots rather than keep a live tracker (Convex reconstructs
|
|
57
|
+
* per invocation). `applyWorldDiff(prev, diffSnapshots(prev, next, r))` reproduces `next`. `baseRevision`, when the
|
|
58
|
+
* caller knows the revision `prev` was stamped at, lets a {@link WorldMirror} verify continuity the same way a
|
|
59
|
+
* `createWorldReplicator` diff does; omitted, the diff is legacy/always-apply.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export declare function diffSnapshots(prev: WorldSnapshot, next: WorldSnapshot, revision: number, baseRevision?: number): WorldDiff;
|
|
63
|
+
/**
|
|
64
|
+
* Fold a {@link WorldDiff} onto a prior {@link WorldSnapshot} baseline, returning the next full snapshot — the
|
|
65
|
+
* client-side inverse of {@link createWorldReplicator}. Pure data in, pure data out: upserts changed entities,
|
|
66
|
+
* stats and store keys, drops the removed ones, and replaces changed module snapshots wholesale.
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
export declare function applyWorldDiff(baseline: WorldSnapshot, diff: WorldDiff): WorldSnapshot;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
const CORE_KEYS = new Set(["entities", "stats", "store"]);
|
|
2
|
+
/**
|
|
3
|
+
* Turns successive full {@link WorldSnapshot}s into per-client {@link WorldDiff}s. Each `commit()` re-reads the
|
|
4
|
+
* world, stamps every item that changed with the new revision, and remembers removals; `diff(sinceRevision)`
|
|
5
|
+
* then replays exactly the items stamped after that revision. Everything the tracker holds is JSON — the same
|
|
6
|
+
* shape that rides the wire — so a diff is inherently serializable. Change-detection is a full re-serialize per
|
|
7
|
+
* commit unless {@link WorldReplicatorOptions.worldVersion} lets an unchanged tick short-circuit before it.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export function createWorldReplicator(takeSnapshot, options = {}) {
|
|
11
|
+
const worldVersion = options.worldVersion;
|
|
12
|
+
let committedVersion;
|
|
13
|
+
let revision = 0;
|
|
14
|
+
const entities = new Map();
|
|
15
|
+
const removedEntities = new Map();
|
|
16
|
+
const stats = new Map();
|
|
17
|
+
const removedStats = new Map();
|
|
18
|
+
const store = new Map();
|
|
19
|
+
const removedStore = new Map();
|
|
20
|
+
const modules = new Map();
|
|
21
|
+
const removedModules = new Map();
|
|
22
|
+
function diffMap(live, tracked, removed, nextRevision) {
|
|
23
|
+
let changed = false;
|
|
24
|
+
for (const [key, json] of live) {
|
|
25
|
+
const prev = tracked.get(key);
|
|
26
|
+
if (prev === undefined || prev.json !== json) {
|
|
27
|
+
tracked.set(key, { json, revision: nextRevision });
|
|
28
|
+
removed.delete(key);
|
|
29
|
+
changed = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
for (const key of tracked.keys()) {
|
|
33
|
+
if (!live.has(key)) {
|
|
34
|
+
tracked.delete(key);
|
|
35
|
+
removed.set(key, nextRevision);
|
|
36
|
+
changed = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return changed;
|
|
40
|
+
}
|
|
41
|
+
function commit() {
|
|
42
|
+
if (worldVersion !== undefined) {
|
|
43
|
+
const current = worldVersion();
|
|
44
|
+
if (committedVersion !== undefined && current === committedVersion)
|
|
45
|
+
return revision;
|
|
46
|
+
committedVersion = current;
|
|
47
|
+
}
|
|
48
|
+
const snapshot = takeSnapshot();
|
|
49
|
+
const nextRevision = revision + 1;
|
|
50
|
+
const liveEntities = new Map();
|
|
51
|
+
for (const entity of (snapshot["entities"] ?? [])) {
|
|
52
|
+
liveEntities.set(entity.id, JSON.stringify(entity));
|
|
53
|
+
}
|
|
54
|
+
const liveStats = new Map();
|
|
55
|
+
for (const [id, value] of Object.entries((snapshot["stats"] ?? {}))) {
|
|
56
|
+
liveStats.set(id, JSON.stringify(value));
|
|
57
|
+
}
|
|
58
|
+
const liveStore = new Map();
|
|
59
|
+
for (const [key, value] of (snapshot["store"] ?? [])) {
|
|
60
|
+
liveStore.set(key, JSON.stringify(value ?? null));
|
|
61
|
+
}
|
|
62
|
+
const liveModules = new Map();
|
|
63
|
+
for (const [key, value] of Object.entries(snapshot)) {
|
|
64
|
+
if (CORE_KEYS.has(key))
|
|
65
|
+
continue;
|
|
66
|
+
liveModules.set(key, JSON.stringify(value ?? null));
|
|
67
|
+
}
|
|
68
|
+
let changed = diffMap(liveEntities, entities, removedEntities, nextRevision);
|
|
69
|
+
changed = diffMap(liveStats, stats, removedStats, nextRevision) || changed;
|
|
70
|
+
changed = diffMap(liveStore, store, removedStore, nextRevision) || changed;
|
|
71
|
+
changed = diffMap(liveModules, modules, removedModules, nextRevision) || changed;
|
|
72
|
+
if (changed)
|
|
73
|
+
revision = nextRevision;
|
|
74
|
+
return revision;
|
|
75
|
+
}
|
|
76
|
+
function diff(sinceRevision) {
|
|
77
|
+
const changedEntities = [];
|
|
78
|
+
for (const [, tracked] of entities) {
|
|
79
|
+
if (tracked.revision > sinceRevision)
|
|
80
|
+
changedEntities.push(JSON.parse(tracked.json));
|
|
81
|
+
}
|
|
82
|
+
const changedStats = {};
|
|
83
|
+
for (const [id, tracked] of stats) {
|
|
84
|
+
if (tracked.revision > sinceRevision)
|
|
85
|
+
changedStats[id] = JSON.parse(tracked.json);
|
|
86
|
+
}
|
|
87
|
+
const changedStore = [];
|
|
88
|
+
for (const [key, tracked] of store) {
|
|
89
|
+
if (tracked.revision > sinceRevision)
|
|
90
|
+
changedStore.push([key, JSON.parse(tracked.json)]);
|
|
91
|
+
}
|
|
92
|
+
const changedModules = {};
|
|
93
|
+
for (const [key, tracked] of modules) {
|
|
94
|
+
if (tracked.revision > sinceRevision)
|
|
95
|
+
changedModules[key] = JSON.parse(tracked.json);
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
revision,
|
|
99
|
+
baseRevision: sinceRevision,
|
|
100
|
+
entities: changedEntities,
|
|
101
|
+
removedEntities: keysAfter(removedEntities, sinceRevision),
|
|
102
|
+
stats: changedStats,
|
|
103
|
+
removedStats: keysAfter(removedStats, sinceRevision),
|
|
104
|
+
store: changedStore,
|
|
105
|
+
removedStore: keysAfter(removedStore, sinceRevision),
|
|
106
|
+
modules: changedModules,
|
|
107
|
+
removedModules: keysAfter(removedModules, sinceRevision),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return { commit, diff, revision: () => revision };
|
|
111
|
+
}
|
|
112
|
+
function keysAfter(map, sinceRevision) {
|
|
113
|
+
const out = [];
|
|
114
|
+
for (const [key, revision] of map) {
|
|
115
|
+
if (revision > sinceRevision)
|
|
116
|
+
out.push(key);
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Diff two full {@link WorldSnapshot}s directly, stamping the result at `revision` — the stateless counterpart of
|
|
122
|
+
* {@link createWorldReplicator} for hosts that persist snapshots rather than keep a live tracker (Convex reconstructs
|
|
123
|
+
* per invocation). `applyWorldDiff(prev, diffSnapshots(prev, next, r))` reproduces `next`. `baseRevision`, when the
|
|
124
|
+
* caller knows the revision `prev` was stamped at, lets a {@link WorldMirror} verify continuity the same way a
|
|
125
|
+
* `createWorldReplicator` diff does; omitted, the diff is legacy/always-apply.
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
export function diffSnapshots(prev, next, revision, baseRevision) {
|
|
129
|
+
const prevEntities = new Map();
|
|
130
|
+
for (const entity of (prev["entities"] ?? [])) {
|
|
131
|
+
prevEntities.set(entity.id, JSON.stringify(entity));
|
|
132
|
+
}
|
|
133
|
+
const entities = [];
|
|
134
|
+
const nextEntityIds = new Set();
|
|
135
|
+
for (const entity of (next["entities"] ?? [])) {
|
|
136
|
+
nextEntityIds.add(entity.id);
|
|
137
|
+
const json = JSON.stringify(entity);
|
|
138
|
+
if (prevEntities.get(entity.id) !== json)
|
|
139
|
+
entities.push(JSON.parse(json));
|
|
140
|
+
}
|
|
141
|
+
const removedEntities = [...prevEntities.keys()].filter((id) => !nextEntityIds.has(id));
|
|
142
|
+
const prevStats = (prev["stats"] ?? {});
|
|
143
|
+
const nextStats = (next["stats"] ?? {});
|
|
144
|
+
const stats = {};
|
|
145
|
+
for (const [id, value] of Object.entries(nextStats)) {
|
|
146
|
+
const json = JSON.stringify(value);
|
|
147
|
+
if (JSON.stringify(prevStats[id]) !== json)
|
|
148
|
+
stats[id] = JSON.parse(json);
|
|
149
|
+
}
|
|
150
|
+
const removedStats = Object.keys(prevStats).filter((id) => !(id in nextStats));
|
|
151
|
+
const prevStore = new Map((prev["store"] ?? []));
|
|
152
|
+
const nextStore = new Map((next["store"] ?? []));
|
|
153
|
+
const store = [];
|
|
154
|
+
for (const [key, value] of nextStore) {
|
|
155
|
+
const json = JSON.stringify(value ?? null);
|
|
156
|
+
if (JSON.stringify(prevStore.get(key) ?? null) !== json)
|
|
157
|
+
store.push([key, JSON.parse(json)]);
|
|
158
|
+
}
|
|
159
|
+
const removedStore = [...prevStore.keys()].filter((key) => !nextStore.has(key));
|
|
160
|
+
const modules = {};
|
|
161
|
+
const nextModuleKeys = new Set();
|
|
162
|
+
for (const [key, value] of Object.entries(next)) {
|
|
163
|
+
if (CORE_KEYS.has(key))
|
|
164
|
+
continue;
|
|
165
|
+
nextModuleKeys.add(key);
|
|
166
|
+
const json = JSON.stringify(value ?? null);
|
|
167
|
+
if (JSON.stringify(prev[key] ?? null) !== json)
|
|
168
|
+
modules[key] = JSON.parse(json);
|
|
169
|
+
}
|
|
170
|
+
const removedModules = Object.keys(prev).filter((key) => !CORE_KEYS.has(key) && !nextModuleKeys.has(key));
|
|
171
|
+
return {
|
|
172
|
+
revision,
|
|
173
|
+
...(baseRevision === undefined ? {} : { baseRevision }),
|
|
174
|
+
entities,
|
|
175
|
+
removedEntities,
|
|
176
|
+
stats,
|
|
177
|
+
removedStats,
|
|
178
|
+
store,
|
|
179
|
+
removedStore,
|
|
180
|
+
modules,
|
|
181
|
+
removedModules,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Fold a {@link WorldDiff} onto a prior {@link WorldSnapshot} baseline, returning the next full snapshot — the
|
|
186
|
+
* client-side inverse of {@link createWorldReplicator}. Pure data in, pure data out: upserts changed entities,
|
|
187
|
+
* stats and store keys, drops the removed ones, and replaces changed module snapshots wholesale.
|
|
188
|
+
* @internal
|
|
189
|
+
*/
|
|
190
|
+
export function applyWorldDiff(baseline, diff) {
|
|
191
|
+
const next = { ...baseline };
|
|
192
|
+
const entityById = new Map();
|
|
193
|
+
for (const entity of (baseline["entities"] ?? []))
|
|
194
|
+
entityById.set(entity.id, entity);
|
|
195
|
+
for (const entity of diff.entities)
|
|
196
|
+
entityById.set(entity.id, entity);
|
|
197
|
+
for (const id of diff.removedEntities)
|
|
198
|
+
entityById.delete(id);
|
|
199
|
+
next["entities"] = Array.from(entityById.values());
|
|
200
|
+
const statsById = { ...(baseline["stats"] ?? {}) };
|
|
201
|
+
for (const [id, value] of Object.entries(diff.stats))
|
|
202
|
+
statsById[id] = value;
|
|
203
|
+
for (const id of diff.removedStats)
|
|
204
|
+
delete statsById[id];
|
|
205
|
+
next["stats"] = statsById;
|
|
206
|
+
const storeByKey = new Map((baseline["store"] ?? []));
|
|
207
|
+
for (const [key, value] of diff.store)
|
|
208
|
+
storeByKey.set(key, value);
|
|
209
|
+
for (const key of diff.removedStore)
|
|
210
|
+
storeByKey.delete(key);
|
|
211
|
+
next["store"] = Array.from(storeByKey.entries());
|
|
212
|
+
for (const [key, value] of Object.entries(diff.modules))
|
|
213
|
+
next[key] = value;
|
|
214
|
+
for (const key of diff.removedModules)
|
|
215
|
+
delete next[key];
|
|
216
|
+
return next;
|
|
217
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Who a host→client snapshot is being projected for — the identity a {@link SnapshotModule.project} filters against. */
|
|
2
|
+
export interface SnapshotViewer {
|
|
3
|
+
readonly userId: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The replication seam for host-authoritative shared worlds: the opt-in feature manifest *is* the
|
|
7
|
+
* replication schema. Each live subsystem a game opts into registers a {@link SnapshotModule} keyed
|
|
8
|
+
* by name; the host serializes exactly the registered set into a {@link WorldSnapshot} and a client
|
|
9
|
+
* hydrates the same keys back. Adding a replicated subsystem is a registration, never a new branch.
|
|
10
|
+
*
|
|
11
|
+
* Two optional members carry per-viewer projection and change detection *through the same contract*,
|
|
12
|
+
* so a feature opts into either without the engine growing a per-feature branch:
|
|
13
|
+
* - {@link project} narrows this module's snapshot to what one viewer may see (private state, area of
|
|
14
|
+
* interest). Absent → the module is world-public and every client receives it verbatim (the default).
|
|
15
|
+
* - {@link version} is a monotone counter the host reads to skip re-serializing an unchanged module.
|
|
16
|
+
*/
|
|
17
|
+
export interface SnapshotModule<T = unknown> {
|
|
18
|
+
readonly key: string;
|
|
19
|
+
snapshot(): T;
|
|
20
|
+
hydrate(data: T): void;
|
|
21
|
+
/**
|
|
22
|
+
* Narrow this module's full snapshot to what `viewer` is allowed to see — return the same shape
|
|
23
|
+
* carrying only the visible subset (drop other players' private state, cull entities outside the
|
|
24
|
+
* viewer's area of interest). `world` is the whole unprojected baseline, so a module can cross-
|
|
25
|
+
* reference another (e.g. drop stats for entities the viewer can't see). Absent → world-public: the
|
|
26
|
+
* full value is sent to every viewer.
|
|
27
|
+
*/
|
|
28
|
+
project?(data: T, viewer: SnapshotViewer, world: WorldSnapshot): T;
|
|
29
|
+
/** Monotone change counter; unchanged between host commits means this module didn't mutate and need not re-serialize. */
|
|
30
|
+
version?(): number;
|
|
31
|
+
}
|
|
32
|
+
/** Full world baseline keyed by {@link SnapshotModule.key} — one entry per opted-in subsystem. */
|
|
33
|
+
export type WorldSnapshot = Record<string, unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Serialize every registered module into one keyed baseline — the host→client full-world send. When a
|
|
36
|
+
* `viewer` is supplied, each module that implements {@link SnapshotModule.project} narrows its value to
|
|
37
|
+
* what that viewer may see; modules without a projector are sent verbatim.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export declare function composeWorldSnapshot(modules: readonly SnapshotModule[], viewer?: SnapshotViewer): WorldSnapshot;
|
|
41
|
+
/** Hydrate every registered module whose key is present in `snapshot`; keys absent from it are left untouched.
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyWorldSnapshot(modules: readonly SnapshotModule[], snapshot: WorldSnapshot): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize every registered module into one keyed baseline — the host→client full-world send. When a
|
|
3
|
+
* `viewer` is supplied, each module that implements {@link SnapshotModule.project} narrows its value to
|
|
4
|
+
* what that viewer may see; modules without a projector are sent verbatim.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function composeWorldSnapshot(modules, viewer) {
|
|
8
|
+
const raw = {};
|
|
9
|
+
for (const module of modules)
|
|
10
|
+
raw[module.key] = module.snapshot();
|
|
11
|
+
if (viewer === undefined)
|
|
12
|
+
return raw;
|
|
13
|
+
const snapshot = {};
|
|
14
|
+
for (const module of modules) {
|
|
15
|
+
const value = raw[module.key];
|
|
16
|
+
snapshot[module.key] =
|
|
17
|
+
module.project !== undefined ? module.project(value, viewer, raw) : value;
|
|
18
|
+
}
|
|
19
|
+
return snapshot;
|
|
20
|
+
}
|
|
21
|
+
/** Hydrate every registered module whose key is present in `snapshot`; keys absent from it are left untouched.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export function applyWorldSnapshot(modules, snapshot) {
|
|
25
|
+
for (const module of modules) {
|
|
26
|
+
if (Object.prototype.hasOwnProperty.call(snapshot, module.key)) {
|
|
27
|
+
module.hydrate(snapshot[module.key]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { AssetSpace } from "./assetSpace.js";
|
|
2
|
+
/** Measured horizontal footprint, footprint center, and lowest Y of a model in model space. */
|
|
1
3
|
export interface ModelDims {
|
|
2
4
|
footprint: {
|
|
3
5
|
w: number;
|
|
@@ -13,7 +15,27 @@ export interface ModelAssetRef {
|
|
|
13
15
|
url: string;
|
|
14
16
|
/** Measured at asset reindex: horizontal footprint, footprint center, and lowest Y in model space (pre-scale). Lets the shell auto-center and ground-snap corner-pivot kit models. */
|
|
15
17
|
dims?: ModelDims;
|
|
18
|
+
/** Authored asset-space metadata — canonical facing (degrees), source-unit scale, footprint, anchor, bounds, and rotation policy. The upstream owner of placement corrections; see {@link "scene/assetSpace".AssetSpace}. */
|
|
19
|
+
space?: AssetSpace;
|
|
16
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* A catalog entry backed by a registered {@link registerAssetGenerator} instead of a GLB URL — a
|
|
23
|
+
* slider-driven parametric prop (bookcase, building). `defaults` seeds a fresh placement's params.
|
|
24
|
+
* Placed instances persist `{ assetId, params, seed }` in the scene and re-resolve at runtime.
|
|
25
|
+
*/
|
|
26
|
+
export interface GeneratorAssetRef {
|
|
27
|
+
kind: "generator";
|
|
28
|
+
/** Id of the registered generator this asset resolves through. */
|
|
29
|
+
generatorId: string;
|
|
30
|
+
/** Default params stamped onto a fresh placement's meta. */
|
|
31
|
+
defaults?: Record<string, unknown>;
|
|
32
|
+
/** Authored asset-space metadata — canonical facing (degrees), footprint, anchor, bounds, and rotation policy; see {@link "scene/assetSpace".AssetSpace}. */
|
|
33
|
+
space?: AssetSpace;
|
|
34
|
+
}
|
|
35
|
+
/** A catalog entry: a static GLB model, or a parametric generator. */
|
|
36
|
+
export type AssetRef = ModelAssetRef | GeneratorAssetRef;
|
|
37
|
+
/** True when a catalog entry is a parametric generator rather than a static GLB. @internal */
|
|
38
|
+
export declare function isGeneratorAsset(ref: AssetRef): ref is GeneratorAssetRef;
|
|
17
39
|
export interface AssetCatalog<TMeta extends ModelAssetRef = ModelAssetRef> {
|
|
18
40
|
register(id: string, asset: TMeta): void;
|
|
19
41
|
resolve(id: string): TMeta | null;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, zero-dependency classification of a model-asset fetch before it reaches
|
|
3
|
+
* a GLTF parser. Runtime loaders hand the raw response (status, content type,
|
|
4
|
+
* and the first bytes) to {@link classifyAssetResponse} so a missing or
|
|
5
|
+
* mis-served file surfaces as an actionable diagnostic naming the broken asset
|
|
6
|
+
* contract, instead of the opaque "Unexpected token < in JSON" parse error a
|
|
7
|
+
* dev-server HTML fallback otherwise produces. No `fetch`, DOM, or three.js
|
|
8
|
+
* dependency lives here — callers supply the already-read bytes.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* How a model-asset fetch resolved. `ok` means the bytes are a parseable GLB or
|
|
12
|
+
* glTF-JSON; every other kind is a distinct failure a loader should report
|
|
13
|
+
* rather than parse: `missing` (HTTP error / no bytes), `html` (a dev-server
|
|
14
|
+
* fallback page served in place of the file), `corrupt` (bytes present but not a
|
|
15
|
+
* recognizable model), `unsupported` (a recognizable but non-model format).
|
|
16
|
+
*/
|
|
17
|
+
export type AssetLoadKind = "ok" | "missing" | "html" | "corrupt" | "unsupported";
|
|
18
|
+
/** The signature read from a response's leading bytes, independent of HTTP metadata. @internal */
|
|
19
|
+
export type AssetByteSignature = "glb" | "gltf-json" | "html" | "png" | "jpeg" | "zip" | "unknown" | "empty";
|
|
20
|
+
/**
|
|
21
|
+
* A probe of a model-asset fetch: the URL, an optional logical asset id for the
|
|
22
|
+
* diagnostic, and whatever the caller managed to read. Any field may be absent
|
|
23
|
+
* (e.g. a network error yields no `status` or `bytes`); the classifier degrades
|
|
24
|
+
* gracefully.
|
|
25
|
+
*/
|
|
26
|
+
export interface AssetResponseProbe {
|
|
27
|
+
url: string;
|
|
28
|
+
/** Logical catalog id / alias behind the URL, surfaced in the diagnostic message when known. */
|
|
29
|
+
logicalId?: string;
|
|
30
|
+
/** HTTP status code; `0` or `>= 400` is treated as missing. Omit when the fetch never completed. */
|
|
31
|
+
status?: number;
|
|
32
|
+
statusText?: string;
|
|
33
|
+
/** `Content-Type` response header, lower-cased or not — matched case-insensitively. */
|
|
34
|
+
contentType?: string;
|
|
35
|
+
/** The leading bytes of the body (a few hundred is plenty); their signature decides GLB vs HTML vs corrupt. */
|
|
36
|
+
bytes?: Uint8Array;
|
|
37
|
+
}
|
|
38
|
+
/** The verdict for one model-asset fetch: its {@link AssetLoadKind} plus a ready-to-log message. */
|
|
39
|
+
export interface AssetLoadDiagnosis {
|
|
40
|
+
kind: AssetLoadKind;
|
|
41
|
+
/** True only for `kind: "ok"` — safe to hand the bytes to a GLTF parser. */
|
|
42
|
+
ok: boolean;
|
|
43
|
+
url: string;
|
|
44
|
+
logicalId?: string;
|
|
45
|
+
byteSignature: AssetByteSignature;
|
|
46
|
+
/** Human-readable, actionable one-liner naming the asset, the URL, and the likely fix. */
|
|
47
|
+
message: string;
|
|
48
|
+
}
|
|
49
|
+
/** GLB little-endian magic — the ASCII "glTF" at byte 0 of a binary glTF container. @internal */
|
|
50
|
+
export declare const GLB_MAGIC_ASCII = "glTF";
|
|
51
|
+
/**
|
|
52
|
+
* Classify the leading bytes of a response body by their format signature, with
|
|
53
|
+
* no HTTP context. Recognizes GLB (`glTF` magic), glTF-JSON (a leading `{`), an
|
|
54
|
+
* HTML fallback page (`<!doctype`, `<html`, or a bare `<`), and a few common
|
|
55
|
+
* non-model binaries (PNG, JPEG, ZIP) so they can be reported as unsupported
|
|
56
|
+
* rather than corrupt.
|
|
57
|
+
*/
|
|
58
|
+
export declare function readByteSignature(bytes: Uint8Array): AssetByteSignature;
|
|
59
|
+
/**
|
|
60
|
+
* Turn a {@link AssetResponseProbe} into an {@link AssetLoadDiagnosis}. HTTP
|
|
61
|
+
* status is checked first (a `>= 400` or `0` status is `missing`), then the
|
|
62
|
+
* `Content-Type` and byte signature decide between an HTML fallback, a
|
|
63
|
+
* parseable model (`ok`), an unsupported-but-recognizable format, and otherwise
|
|
64
|
+
* corrupt bytes. The returned `message` always names the asset and URL and, for
|
|
65
|
+
* failures, points at the likely fix (provision the pack, check the serving path).
|
|
66
|
+
*
|
|
67
|
+
* @capability asset-load-diagnostics classify a model fetch (missing / HTML fallback / corrupt / unsupported) before parsing
|
|
68
|
+
*/
|
|
69
|
+
export declare function classifyAssetResponse(probe: AssetResponseProbe): AssetLoadDiagnosis;
|