@jgengine/core 0.10.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 +13 -2
- 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 +7 -2
- package/dist/ai/spawnDirector.js +18 -15
- package/dist/ai/spawnPoint.d.ts +3 -1
- package/dist/ai/spawnPoint.js +3 -1
- 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/authoring.d.ts +1 -0
- package/dist/authoring.js +1 -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 +5 -1
- package/dist/combat/dotField.js +5 -1
- 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 +5 -0
- package/dist/combat/projectiles.js +32 -14
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +5 -1
- package/dist/combat/regenShield.js +5 -1
- 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 +18 -1
- package/dist/combat/shotOrigin.js +39 -0
- 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 +190 -7
- package/dist/editor/commands.js +727 -55
- package/dist/editor/document.d.ts +159 -13
- package/dist/editor/document.js +750 -19
- 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 +73 -6
- package/dist/editor/index.js +6 -2
- 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 +107 -1
- 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 +6 -4
- package/dist/game/connectedPlayers.js +2 -2
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +100 -2
- package/dist/game/defineGame.js +39 -2
- 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 +35 -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/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- 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 +19 -2
- package/dist/game/lootTable.js +15 -5
- 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 +92 -7
- 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 +3 -1
- 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 -14
- package/dist/index.js +5 -14
- package/dist/input/actionBindings.d.ts +23 -6
- package/dist/input/actionBindings.js +23 -6
- package/dist/input/axisInput.d.ts +7 -2
- package/dist/input/axisInput.js +7 -2
- 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/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +2 -0
- package/dist/interaction/proximityPrompt.js +2 -0
- 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 +16 -2
- 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 +35 -8
- package/dist/movement/movementModel.js +42 -14
- package/dist/movement/playerMovement.js +65 -10
- 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 +22 -0
- package/dist/random/rng.js +28 -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 +20 -0
- package/dist/render/postProcessing.js +21 -1
- 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 +42 -3
- package/dist/runtime/adapter.js +44 -1
- 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 +114 -13
- package/dist/runtime/gameContext.js +303 -395
- 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 +8 -3
- package/dist/runtime/hostedGameRunner.js +26 -3
- package/dist/runtime/hostedWorldSession.d.ts +12 -4
- package/dist/runtime/hostedWorldSession.js +11 -4
- package/dist/runtime/inputSnapshot.d.ts +8 -3
- package/dist/runtime/inputSnapshot.js +6 -2
- package/dist/runtime/motionIntents.d.ts +11 -2
- package/dist/runtime/motionIntents.js +16 -2
- 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 +7 -3
- package/dist/runtime/worldChannel.js +51 -6
- package/dist/runtime/worldMirror.d.ts +14 -2
- package/dist/runtime/worldMirror.js +15 -2
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +30 -7
- package/dist/runtime/worldReplication.js +41 -9
- package/dist/runtime/worldSnapshot.d.ts +30 -3
- package/dist/runtime/worldSnapshot.js +20 -5
- package/dist/scene/assetCatalog.d.ts +21 -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 +13 -1
- package/dist/scene/colliders.js +37 -1
- package/dist/scene/entityStats.d.ts +11 -2
- package/dist/scene/entityStats.js +11 -2
- package/dist/scene/entityStore.d.ts +12 -1
- package/dist/scene/entityStore.js +15 -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 +5 -0
- package/dist/store/observableKeyedStore.js +34 -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 +4 -2
- package/dist/tactics/fallingGrid.js +4 -2
- 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 +30 -11
- package/dist/ui/gameLayout.js +30 -11
- 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/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -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/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/features.d.ts +115 -7
- package/dist/world/features.js +56 -5
- 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 +8 -0
- package/dist/world/roads.js +38 -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/terraform.d.ts +213 -1
- package/dist/world/terraform.js +655 -20
- package/dist/world/terrain.d.ts +119 -20
- package/dist/world/terrain.js +247 -41
- 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 -5389
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { EntityRole, EntityUpdatePatch, SpawnPositionInput } from "./entityStore.js";
|
|
2
|
+
/**
|
|
3
|
+
* One sim body's per-tick pose, as the game's simulation computed it — the shape a game already builds
|
|
4
|
+
* to hand to `setPose`, just declared instead of imperatively pushed. `kind` is the entity catalog name
|
|
5
|
+
* used only the first time `id` is seen (a respawn/despawn never re-reads it).
|
|
6
|
+
*/
|
|
7
|
+
export interface BodySnapshot {
|
|
8
|
+
id: string;
|
|
9
|
+
kind: string;
|
|
10
|
+
position: SpawnPositionInput;
|
|
11
|
+
rotationY?: number;
|
|
12
|
+
rotationX?: number;
|
|
13
|
+
rotationZ?: number;
|
|
14
|
+
role?: EntityRole;
|
|
15
|
+
meta?: unknown;
|
|
16
|
+
}
|
|
17
|
+
/** The options a {@link BodyBindDeps.spawn} call receives for an id seen for the first time. */
|
|
18
|
+
export interface BodyBindSpawnInput {
|
|
19
|
+
id: string;
|
|
20
|
+
position: SpawnPositionInput;
|
|
21
|
+
rotationY?: number;
|
|
22
|
+
rotationX?: number;
|
|
23
|
+
rotationZ?: number;
|
|
24
|
+
role?: EntityRole;
|
|
25
|
+
meta?: unknown;
|
|
26
|
+
}
|
|
27
|
+
/** The pose a {@link BodyBindDeps.setPose} call receives for an id already bound. */
|
|
28
|
+
export interface BodyBindPose {
|
|
29
|
+
position: SpawnPositionInput;
|
|
30
|
+
rotationY?: number;
|
|
31
|
+
rotationX?: number;
|
|
32
|
+
rotationZ?: number;
|
|
33
|
+
dt?: number;
|
|
34
|
+
}
|
|
35
|
+
/** Structural entity-store seam a {@link BodyBind} mirrors onto — satisfied by `ctx.scene.entity` itself. */
|
|
36
|
+
export interface BodyBindDeps {
|
|
37
|
+
has(id: string): boolean;
|
|
38
|
+
spawn(kind: string, options: BodyBindSpawnInput): string;
|
|
39
|
+
despawn(id: string): boolean;
|
|
40
|
+
setPose(id: string, pose: BodyBindPose): boolean;
|
|
41
|
+
update(id: string, patch: EntityUpdatePatch): boolean;
|
|
42
|
+
}
|
|
43
|
+
/** The lazily-keyed handle `ctx.scene.entity.bind(key)` returns. */
|
|
44
|
+
export interface BodyBind {
|
|
45
|
+
/**
|
|
46
|
+
* Mirror this tick's `bodies` onto scene entities: spawns an id seen for the first time (catalog
|
|
47
|
+
* `kind` from its snapshot), poses one already bound, despawns one this bind previously spawned that
|
|
48
|
+
* is now absent from `bodies`. `dt` (when given) derives `velocity` the same as a direct `setPose`.
|
|
49
|
+
*/
|
|
50
|
+
sync(bodies: Iterable<BodySnapshot>, dt?: number): void;
|
|
51
|
+
/** Ids this bind currently considers itself responsible for (spawned by, and not yet despawned by, `sync`). */
|
|
52
|
+
boundIds(): ReadonlySet<string>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
|
|
56
|
+
* despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
|
|
57
|
+
*
|
|
58
|
+
* @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
|
|
59
|
+
*/
|
|
60
|
+
export declare function createBodyBind(deps: BodyBindDeps): BodyBind;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
|
|
3
|
+
* despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
|
|
4
|
+
*
|
|
5
|
+
* @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
|
|
6
|
+
*/
|
|
7
|
+
export function createBodyBind(deps) {
|
|
8
|
+
const bound = new Set();
|
|
9
|
+
return {
|
|
10
|
+
sync(bodies, dt) {
|
|
11
|
+
const seen = new Set();
|
|
12
|
+
for (const body of bodies) {
|
|
13
|
+
seen.add(body.id);
|
|
14
|
+
const alreadyBound = bound.has(body.id);
|
|
15
|
+
if (!alreadyBound && !deps.has(body.id)) {
|
|
16
|
+
deps.spawn(body.kind, {
|
|
17
|
+
id: body.id,
|
|
18
|
+
position: body.position,
|
|
19
|
+
rotationY: body.rotationY,
|
|
20
|
+
rotationX: body.rotationX,
|
|
21
|
+
rotationZ: body.rotationZ,
|
|
22
|
+
role: body.role,
|
|
23
|
+
meta: body.meta,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
deps.setPose(body.id, {
|
|
28
|
+
position: body.position,
|
|
29
|
+
rotationY: body.rotationY,
|
|
30
|
+
rotationX: body.rotationX,
|
|
31
|
+
rotationZ: body.rotationZ,
|
|
32
|
+
...(dt === undefined ? {} : { dt }),
|
|
33
|
+
});
|
|
34
|
+
if (body.role !== undefined || body.meta !== undefined) {
|
|
35
|
+
deps.update(body.id, { role: body.role, meta: body.meta });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
bound.add(body.id);
|
|
39
|
+
}
|
|
40
|
+
for (const id of bound) {
|
|
41
|
+
if (seen.has(id))
|
|
42
|
+
continue;
|
|
43
|
+
deps.despawn(id);
|
|
44
|
+
bound.delete(id);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
boundIds() {
|
|
48
|
+
return bound;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ParamSchema } from "./sceneKinds.js";
|
|
2
|
+
/** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
|
|
3
|
+
export declare const SCATTER_SCHEMA: ParamSchema;
|
|
4
|
+
/** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
|
|
5
|
+
export declare function registerBuiltinSceneKinds(): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers the engine's built-in *environment* scene kinds against the {@link registerSceneKind}
|
|
3
|
+
* seam: `scatter` (the proof adopter — its inspector, `+ Add` entry, and parse now come from the
|
|
4
|
+
* registry), `water` (a reusable parametric water surface), `grass_field` (GPU vertex-wind grass), and
|
|
5
|
+
* `soil` (crack/moss ground-variation patch). These are genre-agnostic engine primitives, like terrain.
|
|
6
|
+
* Domain studios (poles, bookcases, …) are NOT built in — they register themselves from example/game
|
|
7
|
+
* code via the same public seam, needing zero engine edits (see `examples/studios`). Call
|
|
8
|
+
* {@link registerBuiltinSceneKinds} once at startup (idempotent).
|
|
9
|
+
*/
|
|
10
|
+
import { SCATTER_PATH_KIND } from "../world/scatterRegion.js";
|
|
11
|
+
import { registerWaterKind } from "../world/waterKind.js";
|
|
12
|
+
import { registerGrassKind } from "../world/grassKind.js";
|
|
13
|
+
import { registerSoilKind } from "../world/soilKind.js";
|
|
14
|
+
import { registerBuildingGenerator } from "../world/buildingGenerator.js";
|
|
15
|
+
import { registerSceneKind } from "./sceneKinds.js";
|
|
16
|
+
/** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
|
|
17
|
+
export const SCATTER_SCHEMA = {
|
|
18
|
+
fields: [
|
|
19
|
+
{ type: "range", key: "density", label: "density", min: 0, max: 2, step: 0.01, default: 0.15, unit: "/m²" },
|
|
20
|
+
{ type: "number", key: "minSpacing", label: "spacing", step: 0.25, default: 1.5, min: 0 },
|
|
21
|
+
{ type: "number", key: "minScale", label: "min scale", step: 0.05, default: 0.8, min: 0 },
|
|
22
|
+
{ type: "number", key: "maxScale", label: "max scale", step: 0.05, default: 1.3, min: 0 },
|
|
23
|
+
{ type: "number", key: "maxSlope", label: "max slope", step: 0.05, default: 0, min: 0 },
|
|
24
|
+
{ type: "number", key: "edgeFalloff", label: "edge fade", step: 0.5, default: 0, min: 0 },
|
|
25
|
+
{ type: "bool", key: "alignToNormal", label: "align to slope", default: false },
|
|
26
|
+
{ type: "bool", key: "autoAvoid", label: "auto-avoid gameplay spots", default: true },
|
|
27
|
+
{ type: "weightedList", key: "palette", label: "species (weighted)", itemLabel: "grass / tree id", default: [{ item: "grass", weight: 1 }] },
|
|
28
|
+
{ type: "seed", key: "seed", label: "seed", default: "" },
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
let registered = false;
|
|
32
|
+
/** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
|
|
33
|
+
export function registerBuiltinSceneKinds() {
|
|
34
|
+
if (registered)
|
|
35
|
+
return;
|
|
36
|
+
registered = true;
|
|
37
|
+
registerSceneKind({
|
|
38
|
+
kind: SCATTER_PATH_KIND,
|
|
39
|
+
target: "path",
|
|
40
|
+
label: "Foliage / scatter",
|
|
41
|
+
pathShape: "area",
|
|
42
|
+
addCategory: "Studios",
|
|
43
|
+
accent: "#34d399",
|
|
44
|
+
schema: SCATTER_SCHEMA,
|
|
45
|
+
note: (object, params) => {
|
|
46
|
+
const points = object.points ?? [];
|
|
47
|
+
if (points.length < 3)
|
|
48
|
+
return "Draw at least 3 points to close the region.";
|
|
49
|
+
let area = 0;
|
|
50
|
+
for (let i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
|
|
51
|
+
area += points[j].x * points[i].z - points[i].x * points[j].z;
|
|
52
|
+
}
|
|
53
|
+
area = Math.abs(area) / 2;
|
|
54
|
+
const density = typeof params["density"] === "number" ? params["density"] : 0;
|
|
55
|
+
return `≈ ${Math.floor(area * density).toLocaleString()} placements over ${Math.round(area).toLocaleString()} m²`;
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
registerWaterKind();
|
|
59
|
+
registerGrassKind();
|
|
60
|
+
registerSoilKind();
|
|
61
|
+
registerBuildingGenerator();
|
|
62
|
+
}
|
|
@@ -37,13 +37,25 @@ export declare const DEFAULT_OBJECT_HALF_EXTENTS: EntityPosition;
|
|
|
37
37
|
export declare const DEFAULT_ENTITY_BODY_HALF_EXTENTS: EntityPosition;
|
|
38
38
|
/** Entity-local center of the default body hitbox (half its height above the feet). */
|
|
39
39
|
export declare const DEFAULT_ENTITY_BODY_OFFSET: EntityPosition;
|
|
40
|
+
/** @internal */
|
|
40
41
|
export declare function defaultEntityColliders(): EntityColliderSet;
|
|
42
|
+
/** Humanoid damage box uniformly scaled to match a visually scaled mesh, kept grounded (offset stays half its height). At scale 1 this equals `defaultEntityColliders()`.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export declare function scaledEntityColliders(scale: number): EntityColliderSet;
|
|
46
|
+
/** @internal */
|
|
41
47
|
export declare function defaultObjectColliders(halfExtents?: EntityPosition): EntityColliderSet;
|
|
42
|
-
/** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
|
|
48
|
+
/** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
43
51
|
export declare function scaledObjectColliders(scale: readonly [number, number, number]): EntityColliderSet;
|
|
52
|
+
/** @internal */
|
|
44
53
|
export declare function resolveColliders(set: EntityColliderSet | null | undefined): ResolvedCollider[];
|
|
54
|
+
/** @internal */
|
|
45
55
|
export declare function worldOffset(local: EntityPosition | undefined, position: EntityPosition, rotationY: number): EntityPosition;
|
|
56
|
+
/** @internal */
|
|
46
57
|
export declare function colliderWorldCenter(collider: ResolvedCollider, position: EntityPosition, rotationY: number): EntityPosition;
|
|
58
|
+
/** @internal */
|
|
47
59
|
export declare function colliderBounds(collider: ResolvedCollider, position: EntityPosition, rotationY: number): {
|
|
48
60
|
min: EntityPosition;
|
|
49
61
|
max: EntityPosition;
|
package/dist/scene/colliders.js
CHANGED
|
@@ -4,6 +4,7 @@ export const DEFAULT_OBJECT_HALF_EXTENTS = [0.5, 0.5, 0.5];
|
|
|
4
4
|
export const DEFAULT_ENTITY_BODY_HALF_EXTENTS = [0.35, 0.9, 0.35];
|
|
5
5
|
/** Entity-local center of the default body hitbox (half its height above the feet). */
|
|
6
6
|
export const DEFAULT_ENTITY_BODY_OFFSET = [0, 0.9, 0];
|
|
7
|
+
/** @internal */
|
|
7
8
|
export function defaultEntityColliders() {
|
|
8
9
|
return {
|
|
9
10
|
hitboxes: [
|
|
@@ -21,6 +22,35 @@ export function defaultEntityColliders() {
|
|
|
21
22
|
],
|
|
22
23
|
};
|
|
23
24
|
}
|
|
25
|
+
/** Humanoid damage box uniformly scaled to match a visually scaled mesh, kept grounded (offset stays half its height). At scale 1 this equals `defaultEntityColliders()`.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export function scaledEntityColliders(scale) {
|
|
29
|
+
return {
|
|
30
|
+
hitboxes: [
|
|
31
|
+
{
|
|
32
|
+
name: "body",
|
|
33
|
+
purpose: "damage",
|
|
34
|
+
shape: {
|
|
35
|
+
kind: "aabb",
|
|
36
|
+
halfExtents: [
|
|
37
|
+
DEFAULT_ENTITY_BODY_HALF_EXTENTS[0] * scale,
|
|
38
|
+
DEFAULT_ENTITY_BODY_HALF_EXTENTS[1] * scale,
|
|
39
|
+
DEFAULT_ENTITY_BODY_HALF_EXTENTS[2] * scale,
|
|
40
|
+
],
|
|
41
|
+
offset: [
|
|
42
|
+
DEFAULT_ENTITY_BODY_OFFSET[0] * scale,
|
|
43
|
+
DEFAULT_ENTITY_BODY_OFFSET[1] * scale,
|
|
44
|
+
DEFAULT_ENTITY_BODY_OFFSET[2] * scale,
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
damageEligible: true,
|
|
48
|
+
blocks: false,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** @internal */
|
|
24
54
|
export function defaultObjectColliders(halfExtents = DEFAULT_OBJECT_HALF_EXTENTS) {
|
|
25
55
|
return {
|
|
26
56
|
body: {
|
|
@@ -32,7 +62,9 @@ export function defaultObjectColliders(halfExtents = DEFAULT_OBJECT_HALF_EXTENTS
|
|
|
32
62
|
},
|
|
33
63
|
};
|
|
34
64
|
}
|
|
35
|
-
/** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
|
|
65
|
+
/** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
36
68
|
export function scaledObjectColliders(scale) {
|
|
37
69
|
return {
|
|
38
70
|
body: {
|
|
@@ -48,6 +80,7 @@ export function scaledObjectColliders(scale) {
|
|
|
48
80
|
},
|
|
49
81
|
};
|
|
50
82
|
}
|
|
83
|
+
/** @internal */
|
|
51
84
|
export function resolveColliders(set) {
|
|
52
85
|
if (set === null || set === undefined)
|
|
53
86
|
return [];
|
|
@@ -71,6 +104,7 @@ function resolveOne(def) {
|
|
|
71
104
|
blocks,
|
|
72
105
|
};
|
|
73
106
|
}
|
|
107
|
+
/** @internal */
|
|
74
108
|
export function worldOffset(local, position, rotationY) {
|
|
75
109
|
if (local === undefined)
|
|
76
110
|
return position;
|
|
@@ -81,9 +115,11 @@ export function worldOffset(local, position, rotationY) {
|
|
|
81
115
|
const lz = local[2];
|
|
82
116
|
return [position[0] + lx * cos + lz * sin, position[1] + ly, position[2] - lx * sin + lz * cos];
|
|
83
117
|
}
|
|
118
|
+
/** @internal */
|
|
84
119
|
export function colliderWorldCenter(collider, position, rotationY) {
|
|
85
120
|
return worldOffset(collider.shape.offset, position, rotationY);
|
|
86
121
|
}
|
|
122
|
+
/** @internal */
|
|
87
123
|
export function colliderBounds(collider, position, rotationY) {
|
|
88
124
|
const center = colliderWorldCenter(collider, position, rotationY);
|
|
89
125
|
if (collider.shape.kind === "sphere") {
|
|
@@ -24,13 +24,21 @@ export type PoolDeltaResult = {
|
|
|
24
24
|
status: "rejected";
|
|
25
25
|
reason: string;
|
|
26
26
|
};
|
|
27
|
+
/** @internal */
|
|
27
28
|
export declare function getStatValue(map: StatValueMap, statId: string): StatValue | null;
|
|
29
|
+
/** @internal */
|
|
28
30
|
export declare function setStatValue(map: StatValueMap, statId: string, patch: StatValuePatch): StatValueMap;
|
|
31
|
+
/** @internal */
|
|
29
32
|
export declare function applyPoolDelta(map: StatValueMap, statId: string, amount: number): PoolDeltaResult;
|
|
33
|
+
/** @internal */
|
|
30
34
|
export declare function seedStatValues(catalogStats: StatCatalog): StatValueMap;
|
|
31
|
-
/** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
|
|
35
|
+
/** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
32
38
|
export declare function snapshotEntityStats(store: ReadonlyMap<string, StatValueMap>): Record<string, StatValueMap>;
|
|
33
|
-
/** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
|
|
39
|
+
/** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
34
42
|
export declare function hydrateEntityStats(store: Map<string, StatValueMap>, data: Record<string, StatValueMap>): void;
|
|
35
43
|
export interface EntityStatsApi {
|
|
36
44
|
get(instanceId: string, statId: string): StatValue | null;
|
|
@@ -39,4 +47,5 @@ export interface EntityStatsApi {
|
|
|
39
47
|
reason: string;
|
|
40
48
|
};
|
|
41
49
|
}
|
|
50
|
+
/** @internal */
|
|
42
51
|
export declare function createEntityStatsApi(resolve: (instanceId: string) => StatValueMap | undefined): EntityStatsApi;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
function clamp(value, min, max) {
|
|
2
2
|
return Math.min(max, Math.max(min, value));
|
|
3
3
|
}
|
|
4
|
+
/** @internal */
|
|
4
5
|
export function getStatValue(map, statId) {
|
|
5
6
|
return map[statId] ?? null;
|
|
6
7
|
}
|
|
8
|
+
/** @internal */
|
|
7
9
|
export function setStatValue(map, statId, patch) {
|
|
8
10
|
const existing = map[statId];
|
|
9
11
|
const max = patch.max ?? existing?.max ?? 0;
|
|
@@ -11,6 +13,7 @@ export function setStatValue(map, statId, patch) {
|
|
|
11
13
|
const current = clamp(patch.current ?? existing?.current ?? max, min, max);
|
|
12
14
|
return { ...map, [statId]: { current, max, min } };
|
|
13
15
|
}
|
|
16
|
+
/** @internal */
|
|
14
17
|
export function applyPoolDelta(map, statId, amount) {
|
|
15
18
|
const existing = map[statId];
|
|
16
19
|
if (existing === undefined) {
|
|
@@ -26,6 +29,7 @@ export function applyPoolDelta(map, statId, amount) {
|
|
|
26
29
|
hitMax: current === existing.max,
|
|
27
30
|
};
|
|
28
31
|
}
|
|
32
|
+
/** @internal */
|
|
29
33
|
export function seedStatValues(catalogStats) {
|
|
30
34
|
const map = {};
|
|
31
35
|
for (const [statId, declaration] of Object.entries(catalogStats)) {
|
|
@@ -35,7 +39,9 @@ export function seedStatValues(catalogStats) {
|
|
|
35
39
|
}
|
|
36
40
|
return map;
|
|
37
41
|
}
|
|
38
|
-
/** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
|
|
42
|
+
/** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
39
45
|
export function snapshotEntityStats(store) {
|
|
40
46
|
const out = {};
|
|
41
47
|
for (const [instanceId, map] of store) {
|
|
@@ -46,7 +52,9 @@ export function snapshotEntityStats(store) {
|
|
|
46
52
|
}
|
|
47
53
|
return out;
|
|
48
54
|
}
|
|
49
|
-
/** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
|
|
55
|
+
/** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
50
58
|
export function hydrateEntityStats(store, data) {
|
|
51
59
|
store.clear();
|
|
52
60
|
for (const [instanceId, map] of Object.entries(data)) {
|
|
@@ -56,6 +64,7 @@ export function hydrateEntityStats(store, data) {
|
|
|
56
64
|
store.set(instanceId, copy);
|
|
57
65
|
}
|
|
58
66
|
}
|
|
67
|
+
/** @internal */
|
|
59
68
|
export function createEntityStatsApi(resolve) {
|
|
60
69
|
return {
|
|
61
70
|
get(instanceId, statId) {
|
|
@@ -22,9 +22,16 @@ export interface SceneEntity<TMeta = unknown> {
|
|
|
22
22
|
role: EntityRole;
|
|
23
23
|
movement: EntityMovement;
|
|
24
24
|
behaviors: readonly BehaviorDescriptor[];
|
|
25
|
-
/** Game-defined per-instance data set at `spawn`/`update` and carried to `renderEntity`/queries — narrow with
|
|
25
|
+
/** Game-defined per-instance data set at `spawn`/`update` and carried to `renderEntity`/queries — narrow with {@link entityMetaOf} (or a type guard) on read (#286.1); never encode state in the id/name string. */
|
|
26
26
|
meta: TMeta;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null`
|
|
30
|
+
* instead of lying to the type checker.
|
|
31
|
+
*
|
|
32
|
+
* @capability entity-meta cast-free narrow of SceneEntity.meta via a type guard
|
|
33
|
+
*/
|
|
34
|
+
export declare function entityMetaOf<T>(entity: SceneEntity<unknown>, isMeta: (value: unknown) => value is T): T | null;
|
|
28
35
|
/** Ground speed (horizontal magnitude of velocity) in world units per second. Scale to km/h or mph in game code. */
|
|
29
36
|
export declare function groundSpeed(entity: SceneEntity<unknown>): number;
|
|
30
37
|
export declare function movedWhileFrozen(entity: SceneEntity<unknown>, threshold?: number): boolean;
|
|
@@ -96,8 +103,12 @@ export interface EntityStore<TMeta = unknown> {
|
|
|
96
103
|
setPoseConstraint(id: string, constraint: PoseConstraint | null): void;
|
|
97
104
|
get(id: string): SceneEntity<TMeta> | null;
|
|
98
105
|
list(): readonly SceneEntity<TMeta>[];
|
|
106
|
+
/** Stable-identity list of live entity ids; identity changes only on spawn/despawn/hydrate, not on pose writes. Pair with {@link subscribeMembership} for membership-only React subscriptions that skip per-frame pose churn (#625). */
|
|
107
|
+
ids(): readonly string[];
|
|
99
108
|
clear(): void;
|
|
100
109
|
subscribe(listener: () => void): () => void;
|
|
110
|
+
/** Notified only when the entity set changes (spawn/despawn/hydrate), never on a pose or field update — the render tree re-reconciles on membership, individual markers read live poses imperatively. */
|
|
111
|
+
subscribeMembership(listener: () => void): () => void;
|
|
101
112
|
snapshot(): readonly SceneEntity<TMeta>[];
|
|
102
113
|
/**
|
|
103
114
|
* Apply a `snapshot()` (e.g. from an authoritative host) to this store — the counterpart of `snapshot()`
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { createObservableKeyedStore } from "../store/observableKeyedStore.js";
|
|
2
|
+
/**
|
|
3
|
+
* Narrow `entity.meta` with a type guard — prefer this over `entity.meta as T` so failed shapes return `null`
|
|
4
|
+
* instead of lying to the type checker.
|
|
5
|
+
*
|
|
6
|
+
* @capability entity-meta cast-free narrow of SceneEntity.meta via a type guard
|
|
7
|
+
*/
|
|
8
|
+
export function entityMetaOf(entity, isMeta) {
|
|
9
|
+
return isMeta(entity.meta) ? entity.meta : null;
|
|
10
|
+
}
|
|
2
11
|
/** Ground speed (horizontal magnitude of velocity) in world units per second. Scale to km/h or mph in game code. */
|
|
3
12
|
export function groundSpeed(entity) {
|
|
4
13
|
return Math.hypot(entity.velocity[0], entity.velocity[2]);
|
|
@@ -167,6 +176,9 @@ export function createEntityStore() {
|
|
|
167
176
|
list() {
|
|
168
177
|
return store.arraySnapshot();
|
|
169
178
|
},
|
|
179
|
+
ids() {
|
|
180
|
+
return store.keysSnapshot();
|
|
181
|
+
},
|
|
170
182
|
clear() {
|
|
171
183
|
for (const entity of store.arraySnapshot()) {
|
|
172
184
|
store.delete(entity.id);
|
|
@@ -177,6 +189,9 @@ export function createEntityStore() {
|
|
|
177
189
|
subscribe(listener) {
|
|
178
190
|
return store.subscribe(listener);
|
|
179
191
|
},
|
|
192
|
+
subscribeMembership(listener) {
|
|
193
|
+
return store.subscribeMembership(listener);
|
|
194
|
+
},
|
|
180
195
|
snapshot() {
|
|
181
196
|
return store.arraySnapshot();
|
|
182
197
|
},
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The forward-axis convention: a generator or scene kind declares which way its "front" faces (a
|
|
3
|
+
* bookcase's open/book face, a building's entrance) once, as data, instead of leaving every placement
|
|
4
|
+
* to hand-tuned `rotationY` trial-and-error. `StudioStage`'s `faceCamera` (`@jgengine/shell/scene/
|
|
5
|
+
* StudioStage`) reads the declared axis to auto-orient a product shot; a placement tool can read the
|
|
6
|
+
* same field to face a freshly dropped asset toward the camera/path by default. `DEFAULT_FORWARD`
|
|
7
|
+
* (+Z) is what a generator/scene-kind gets when it omits `forward` — build your front toward it.
|
|
8
|
+
* @capability forward-axis declared front convention for parametric assets — auto-orient product shots
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_FORWARD: readonly [number, number, number];
|
|
11
|
+
/**
|
|
12
|
+
* The yaw (radians, around Y) that rotates `forward` so it points from `origin` toward `target`, both
|
|
13
|
+
* XZ points. Pure — no three.js — so `StudioStage.faceCamera` and any future placement tool share one
|
|
14
|
+
* tested formula instead of re-deriving atan2 math per call site. Only `forward`'s X/Z components
|
|
15
|
+
* matter (yaw is a rotation about Y); returns 0 when `origin` and `target` coincide.
|
|
16
|
+
* @internal — consumed through `StudioStage`'s `faceCamera` prop, not called directly by game code.
|
|
17
|
+
*/
|
|
18
|
+
export declare function yawToFace(forward: readonly [number, number, number], origin: readonly [number, number], target: readonly [number, number]): number;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The forward-axis convention: a generator or scene kind declares which way its "front" faces (a
|
|
3
|
+
* bookcase's open/book face, a building's entrance) once, as data, instead of leaving every placement
|
|
4
|
+
* to hand-tuned `rotationY` trial-and-error. `StudioStage`'s `faceCamera` (`@jgengine/shell/scene/
|
|
5
|
+
* StudioStage`) reads the declared axis to auto-orient a product shot; a placement tool can read the
|
|
6
|
+
* same field to face a freshly dropped asset toward the camera/path by default. `DEFAULT_FORWARD`
|
|
7
|
+
* (+Z) is what a generator/scene-kind gets when it omits `forward` — build your front toward it.
|
|
8
|
+
* @capability forward-axis declared front convention for parametric assets — auto-orient product shots
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_FORWARD = [0, 0, 1];
|
|
11
|
+
/**
|
|
12
|
+
* The yaw (radians, around Y) that rotates `forward` so it points from `origin` toward `target`, both
|
|
13
|
+
* XZ points. Pure — no three.js — so `StudioStage.faceCamera` and any future placement tool share one
|
|
14
|
+
* tested formula instead of re-deriving atan2 math per call site. Only `forward`'s X/Z components
|
|
15
|
+
* matter (yaw is a rotation about Y); returns 0 when `origin` and `target` coincide.
|
|
16
|
+
* @internal — consumed through `StudioStage`'s `faceCamera` prop, not called directly by game code.
|
|
17
|
+
*/
|
|
18
|
+
export function yawToFace(forward, origin, target) {
|
|
19
|
+
const dx = target[0] - origin[0];
|
|
20
|
+
const dz = target[1] - origin[1];
|
|
21
|
+
if (dx === 0 && dz === 0)
|
|
22
|
+
return 0;
|
|
23
|
+
const angleToTarget = Math.atan2(dx, dz);
|
|
24
|
+
const angleForward = Math.atan2(forward[0], forward[2]);
|
|
25
|
+
return angleToTarget - angleForward;
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic named-socket reader for loaded 3D models. Walks a node tree (any object with `.name`,
|
|
3
|
+
* `.position`, and `.children` — structurally satisfied by `THREE.Object3D`) and collects the local
|
|
4
|
+
* offsets of nodes whose name marks an attachment point. Genre-agnostic: wire anchors on a pylon,
|
|
5
|
+
* muzzle/hand mounts on a character, hardpoints on a ship, seat/decal slots on furniture — anything
|
|
6
|
+
* an artist tags with an empty in the GLB. Pure data (no three.js import), so it lives in core.
|
|
7
|
+
*
|
|
8
|
+
* @capability model-sockets named attachment points read from a model
|
|
9
|
+
*/
|
|
10
|
+
/** Minimal shape of a model node this reader walks — structurally satisfied by `THREE.Object3D`. */
|
|
11
|
+
export interface ModelNode {
|
|
12
|
+
name: string;
|
|
13
|
+
position: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
z: number;
|
|
17
|
+
};
|
|
18
|
+
children?: readonly ModelNode[];
|
|
19
|
+
}
|
|
20
|
+
/** One resolved socket: its node name and local-space offset from the model origin. */
|
|
21
|
+
export interface ModelSocket {
|
|
22
|
+
name: string;
|
|
23
|
+
offset: readonly [number, number, number];
|
|
24
|
+
}
|
|
25
|
+
/** Default socket-name matcher: "socket", "wire", "attach", "anchor", "mount", "hardpoint" (any case). */
|
|
26
|
+
export declare const SOCKET_PATTERN: RegExp;
|
|
27
|
+
/**
|
|
28
|
+
* Depth-first collect every socket-named node's local offset, sorted by descending Y then ascending X
|
|
29
|
+
* so socket indices are stable across loads (top first, left-to-right). Empty when the model tags
|
|
30
|
+
* none — callers then fall back to computed offsets. Pass a custom `pattern` for a bespoke naming
|
|
31
|
+
* convention.
|
|
32
|
+
*/
|
|
33
|
+
export declare function readNamedSockets(root: ModelNode, pattern?: RegExp): ModelSocket[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic named-socket reader for loaded 3D models. Walks a node tree (any object with `.name`,
|
|
3
|
+
* `.position`, and `.children` — structurally satisfied by `THREE.Object3D`) and collects the local
|
|
4
|
+
* offsets of nodes whose name marks an attachment point. Genre-agnostic: wire anchors on a pylon,
|
|
5
|
+
* muzzle/hand mounts on a character, hardpoints on a ship, seat/decal slots on furniture — anything
|
|
6
|
+
* an artist tags with an empty in the GLB. Pure data (no three.js import), so it lives in core.
|
|
7
|
+
*
|
|
8
|
+
* @capability model-sockets named attachment points read from a model
|
|
9
|
+
*/
|
|
10
|
+
/** Default socket-name matcher: "socket", "wire", "attach", "anchor", "mount", "hardpoint" (any case). */
|
|
11
|
+
export const SOCKET_PATTERN = /socket|wire|attach|anchor|mount|hardpoint/i;
|
|
12
|
+
/**
|
|
13
|
+
* Depth-first collect every socket-named node's local offset, sorted by descending Y then ascending X
|
|
14
|
+
* so socket indices are stable across loads (top first, left-to-right). Empty when the model tags
|
|
15
|
+
* none — callers then fall back to computed offsets. Pass a custom `pattern` for a bespoke naming
|
|
16
|
+
* convention.
|
|
17
|
+
*/
|
|
18
|
+
export function readNamedSockets(root, pattern = SOCKET_PATTERN) {
|
|
19
|
+
const found = [];
|
|
20
|
+
const walk = (node) => {
|
|
21
|
+
if (pattern.test(node.name))
|
|
22
|
+
found.push({ name: node.name, offset: [node.position.x, node.position.y, node.position.z] });
|
|
23
|
+
for (const child of node.children ?? [])
|
|
24
|
+
walk(child);
|
|
25
|
+
};
|
|
26
|
+
walk(root);
|
|
27
|
+
found.sort((a, b) => b.offset[1] - a.offset[1] || a.offset[0] - b.offset[0]);
|
|
28
|
+
return found;
|
|
29
|
+
}
|
|
@@ -24,6 +24,8 @@ declare function intersectAabb(origin: EntityPosition, direction: EntityPosition
|
|
|
24
24
|
distance: number;
|
|
25
25
|
normal: EntityPosition;
|
|
26
26
|
} | null;
|
|
27
|
+
/** @internal */
|
|
27
28
|
export declare function raycastObjects(source: ObjectRaycastSource, input: ObjectRaycastInput): ObjectRaycastHit | null;
|
|
29
|
+
/** @internal */
|
|
28
30
|
export declare function raycastObjectsAll(source: ObjectRaycastSource, input: ObjectRaycastInput): ObjectRaycastHit[];
|
|
29
31
|
export { intersectAabb, normalize as normalizeDirection };
|
|
@@ -102,6 +102,7 @@ function resolveCandidates(source, origin, direction, maxDistance, halfExtents)
|
|
|
102
102
|
const bounds = raySegmentBounds(origin, direction, maxDistance, halfExtents);
|
|
103
103
|
return source.inBox(bounds.min, bounds.max);
|
|
104
104
|
}
|
|
105
|
+
/** @internal */
|
|
105
106
|
export function raycastObjects(source, input) {
|
|
106
107
|
const direction = normalize(input.direction);
|
|
107
108
|
if (direction[0] === 0 && direction[1] === 0 && direction[2] === 0)
|
|
@@ -120,6 +121,7 @@ export function raycastObjects(source, input) {
|
|
|
120
121
|
}
|
|
121
122
|
return nearest;
|
|
122
123
|
}
|
|
124
|
+
/** @internal */
|
|
123
125
|
export function raycastObjectsAll(source, input) {
|
|
124
126
|
const direction = normalize(input.direction);
|
|
125
127
|
if (direction[0] === 0 && direction[1] === 0 && direction[2] === 0)
|
|
@@ -31,10 +31,14 @@ export interface ObjectStore {
|
|
|
31
31
|
setVisual(instanceId: string, visual: ObjectVisual | undefined): boolean;
|
|
32
32
|
get(instanceId: string): SceneObject | null;
|
|
33
33
|
list(filter?: ObjectListFilter): readonly SceneObject[];
|
|
34
|
+
/** Stable-identity list of all placed object ids; identity changes only on place/remove, not on move/rotate/setVisual. Pair with {@link subscribeMembership} for membership-only React subscriptions (#625). */
|
|
35
|
+
ids(): readonly string[];
|
|
34
36
|
at(x: number, y: number, z: number, tolerance?: number): SceneObject[];
|
|
35
37
|
inBox(min: EntityPosition, max: EntityPosition): readonly SceneObject[];
|
|
36
38
|
clear(): void;
|
|
37
39
|
subscribe(listener: () => void): () => void;
|
|
40
|
+
/** Notified only when the object set changes (place/remove), never on move/rotate/setVisual — markers read live poses imperatively. */
|
|
41
|
+
subscribeMembership(listener: () => void): () => void;
|
|
38
42
|
snapshot(): readonly SceneObject[];
|
|
39
43
|
}
|
|
40
44
|
export declare function createObjectStore(): ObjectStore;
|
|
@@ -112,6 +112,9 @@ export function createObjectStore() {
|
|
|
112
112
|
return all;
|
|
113
113
|
return all.filter((object) => object.parentSpace === filter.parentSpace);
|
|
114
114
|
},
|
|
115
|
+
ids() {
|
|
116
|
+
return store.keysSnapshot();
|
|
117
|
+
},
|
|
115
118
|
at(x, y, z, tolerance = 0) {
|
|
116
119
|
const minCx = cellIndexOf(x - tolerance);
|
|
117
120
|
const maxCx = cellIndexOf(x + tolerance);
|
|
@@ -180,6 +183,9 @@ export function createObjectStore() {
|
|
|
180
183
|
subscribe(listener) {
|
|
181
184
|
return store.subscribe(listener);
|
|
182
185
|
},
|
|
186
|
+
subscribeMembership(listener) {
|
|
187
|
+
return store.subscribeMembership(listener);
|
|
188
|
+
},
|
|
183
189
|
snapshot() {
|
|
184
190
|
return store.arraySnapshot();
|
|
185
191
|
},
|
|
@@ -17,6 +17,10 @@ export interface PossessionDeps {
|
|
|
17
17
|
entities: PossessionEntities;
|
|
18
18
|
events?: PossessionEvents;
|
|
19
19
|
}
|
|
20
|
+
export interface PossessionSnapshot {
|
|
21
|
+
owned: Record<string, readonly string[]>;
|
|
22
|
+
active: Record<string, string>;
|
|
23
|
+
}
|
|
20
24
|
export interface Possession {
|
|
21
25
|
own(userId: string, entityId: string): void;
|
|
22
26
|
disown(userId: string, entityId: string): void;
|
|
@@ -26,5 +30,9 @@ export interface Possession {
|
|
|
26
30
|
possess(userId: string, entityId: string): {
|
|
27
31
|
reason: string;
|
|
28
32
|
} | null;
|
|
33
|
+
/** Snapshot every user's owned entities and active pawn for a whole-world save. */
|
|
34
|
+
snapshotAll(): PossessionSnapshot;
|
|
35
|
+
/** Restore every user's owned entities and active pawn from a {@link snapshotAll} payload. Entity roles are restored by the entity snapshot, not re-applied here. */
|
|
36
|
+
hydrateAll(state: PossessionSnapshot): void;
|
|
29
37
|
}
|
|
30
38
|
export declare function createPossession(deps: PossessionDeps): Possession;
|