@jgengine/core 0.10.0 → 0.12.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 +39 -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/populationDirector.d.ts +103 -0
- package/dist/ai/populationDirector.js +190 -0
- package/dist/ai/pursuit.d.ts +56 -0
- package/dist/ai/pursuit.js +53 -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 +2 -1
- package/dist/authoring.js +2 -1
- 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 +35 -0
- package/dist/combat.js +35 -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/controls.d.ts +38 -0
- package/dist/devtools/controls.js +181 -0
- package/dist/devtools/devtools.d.ts +5 -197
- package/dist/devtools/devtools.js +38 -774
- package/dist/devtools/discover.d.ts +32 -0
- package/dist/devtools/discover.js +240 -0
- package/dist/devtools/fallbackSeams.d.ts +50 -0
- package/dist/devtools/fallbackSeams.js +111 -0
- package/dist/devtools/frame.d.ts +15 -0
- package/dist/devtools/frame.js +247 -0
- package/dist/devtools/logs.d.ts +15 -0
- package/dist/devtools/logs.js +86 -0
- package/dist/devtools/overrides.d.ts +16 -0
- package/dist/devtools/overrides.js +66 -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/devtools/types.d.ts +212 -0
- package/dist/devtools/types.js +1 -0
- package/dist/economy/auctionBook.d.ts +122 -0
- package/dist/economy/auctionBook.js +213 -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/priceHistory.d.ts +44 -0
- package/dist/economy/priceHistory.js +89 -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/unlockPoints.d.ts +92 -0
- package/dist/economy/unlockPoints.js +103 -0
- package/dist/economy/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commandApply.d.ts +5 -0
- package/dist/editor/commandApply.js +755 -0
- package/dist/editor/commands.d.ts +235 -7
- package/dist/editor/commands.js +82 -124
- package/dist/editor/directives.d.ts +94 -0
- package/dist/editor/directives.js +206 -0
- package/dist/editor/document.d.ts +194 -13
- package/dist/editor/document.js +1166 -19
- package/dist/editor/entityCatalog.d.ts +42 -0
- package/dist/editor/entityCatalog.js +101 -0
- package/dist/editor/environment.d.ts +74 -0
- package/dist/editor/environment.js +169 -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 +98 -6
- package/dist/editor/index.js +13 -2
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/minimap.d.ts +31 -0
- package/dist/editor/minimap.js +73 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/streamer.d.ts +66 -0
- package/dist/editor/streamer.js +68 -0
- package/dist/editor/types.d.ts +250 -1
- package/dist/editor/world.d.ts +136 -0
- package/dist/editor/world.js +303 -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/breeding.d.ts +161 -0
- package/dist/game/breeding.js +181 -0
- package/dist/game/cameraConfig.d.ts +451 -0
- package/dist/game/cameraConfig.js +1 -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 +110 -5
- package/dist/game/defineGame.js +49 -4
- package/dist/game/defineSystem.d.ts +90 -0
- package/dist/game/defineSystem.js +47 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +63 -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 +116 -432
- package/dist/game/playableGame.js +1 -1
- package/dist/game/progression.d.ts +35 -0
- package/dist/game/progression.js +19 -0
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +30 -3
- 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/tribe.d.ts +184 -0
- package/dist/game/tribe.js +432 -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 +93 -0
- package/dist/gameplay.js +93 -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/encumbrance.d.ts +69 -0
- package/dist/inventory/encumbrance.js +68 -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 +6 -3
- 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 +39 -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 +50 -9
- package/dist/movement/movementModel.js +75 -29
- package/dist/movement/playerMovement.js +167 -12
- 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 +16 -8
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +11 -1
- package/dist/multiplayer/presenceModel.js +17 -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 +31 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/flightDynamics.d.ts +82 -0
- package/dist/physics/flightDynamics.js +165 -0
- package/dist/physics/gravityField.d.ts +25 -0
- package/dist/physics/gravityField.js +41 -0
- package/dist/physics/kinematicVehicle.d.ts +108 -1
- package/dist/physics/kinematicVehicle.js +212 -15
- package/dist/physics/physicsWorld.d.ts +50 -12
- package/dist/physics/physicsWorld.js +120 -122
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -0
- package/dist/physics/vehicleObstacles.d.ts +44 -0
- package/dist/physics/vehicleObstacles.js +115 -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 +26 -1
- package/dist/random/rng.js +32 -9
- 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 +55 -3
- package/dist/runtime/adapter.js +57 -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/combat.d.ts +51 -0
- package/dist/runtime/context/combat.js +130 -0
- package/dist/runtime/context/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/deathLoot.d.ts +30 -0
- package/dist/runtime/context/deathLoot.js +39 -0
- package/dist/runtime/context/player.d.ts +48 -0
- package/dist/runtime/context/player.js +125 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -0
- package/dist/runtime/context/scene.d.ts +59 -0
- package/dist/runtime/context/scene.js +291 -0
- package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
- package/dist/runtime/context/snapshotCodecs.js +26 -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 +157 -0
- package/dist/runtime/descriptors/features.d.ts +79 -0
- package/dist/runtime/descriptors/features.js +299 -0
- package/dist/runtime/gameContext.d.ts +2 -327
- package/dist/runtime/gameContext.js +273 -778
- package/dist/runtime/gameContextTypes.d.ts +467 -0
- package/dist/runtime/gameContextTypes.js +1 -0
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +62 -0
- package/dist/runtime/headlessRunner.js +45 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostPolicy.d.ts +51 -0
- package/dist/runtime/hostPolicy.js +68 -0
- package/dist/runtime/hostedGameRunner.d.ts +11 -4
- package/dist/runtime/hostedGameRunner.js +27 -3
- package/dist/runtime/hostedWorldSession.d.ts +15 -5
- package/dist/runtime/hostedWorldSession.js +12 -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 +42 -3
- package/dist/runtime/worldSnapshot.js +34 -7
- package/dist/scene/assetCatalog.d.ts +26 -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 +257 -0
- package/dist/scene/authoredTriggers.d.ts +219 -0
- package/dist/scene/authoredTriggers.js +454 -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 +67 -0
- package/dist/scene/colliders.d.ts +71 -1
- package/dist/scene/colliders.js +145 -1
- package/dist/scene/collisionMesh.d.ts +94 -0
- package/dist/scene/collisionMesh.js +699 -0
- package/dist/scene/companion.d.ts +147 -0
- package/dist/scene/companion.js +193 -0
- package/dist/scene/entityStats.d.ts +18 -11
- package/dist/scene/entityStats.js +21 -16
- 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 +256 -0
- package/dist/scene/sceneKinds.js +218 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -0
- package/dist/scene/sceneRaycast.js +15 -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/spawnLevelStats.d.ts +110 -0
- package/dist/stats/spawnLevelStats.js +140 -0
- package/dist/stats/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -0
- package/dist/stats/statPool.d.ts +70 -0
- package/dist/stats/statPool.js +59 -0
- package/dist/store/changeSignal.d.ts +3 -0
- package/dist/store/changeSignal.js +2 -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 +7 -0
- package/dist/store/observableKeyedStore.js +35 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -57
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +6 -3
- 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 +38 -1
- package/dist/ui/hudLayout.js +220 -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/authoredEntities.d.ts +29 -0
- package/dist/world/authoredEntities.js +29 -0
- package/dist/world/authoredObjects.d.ts +72 -0
- package/dist/world/authoredObjects.js +81 -0
- package/dist/world/authoredSpawn.d.ts +39 -0
- package/dist/world/authoredSpawn.js +37 -0
- package/dist/world/buildSockets.d.ts +152 -0
- package/dist/world/buildSockets.js +188 -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/cityBlocks.d.ts +152 -0
- package/dist/world/cityBlocks.js +670 -0
- package/dist/world/cityContent.d.ts +77 -0
- package/dist/world/cityContent.js +261 -0
- package/dist/world/cityGeometry.d.ts +114 -0
- package/dist/world/cityGeometry.js +573 -0
- package/dist/world/cityKind.d.ts +314 -0
- package/dist/world/cityKind.js +1578 -0
- package/dist/world/features.d.ts +133 -10
- package/dist/world/features.js +66 -6
- 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/markers.d.ts +50 -4
- package/dist/world/markers.js +49 -0
- package/dist/world/massing.js +1 -1
- package/dist/world/minimapBake.d.ts +78 -0
- package/dist/world/minimapBake.js +208 -0
- package/dist/world/minimapTrack.d.ts +17 -0
- package/dist/world/minimapTrack.js +22 -0
- package/dist/world/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathNetwork.d.ts +159 -0
- package/dist/world/pathNetwork.js +684 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/place.d.ts +166 -0
- package/dist/world/place.js +96 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +79 -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/poleLineKind.d.ts +40 -0
- package/dist/world/poleLineKind.js +97 -0
- package/dist/world/polyline.d.ts +34 -0
- package/dist/world/polyline.js +88 -0
- package/dist/world/resourceNode.d.ts +109 -0
- package/dist/world/resourceNode.js +140 -0
- package/dist/world/roads.d.ts +8 -0
- package/dist/world/roads.js +38 -0
- package/dist/world/scatter.js +2 -20
- 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 +29 -0
- package/dist/world/streets.js +55 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +627 -22
- package/dist/world/terrain.d.ts +164 -20
- package/dist/world/terrain.js +325 -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 +141 -0
- package/dist/world.js +141 -0
- package/package.json +32 -8
- package/skills/game-design/SKILL.md +28 -0
- package/skills/game-design/agents/openai.yaml +4 -0
- package/skills/game-design/references/application-playbook.md +170 -0
- package/skills/game-design/references/field-guide.md +288 -0
- package/skills/jgengine/SKILL.md +54 -0
- package/skills/jgengine/api.md +527 -0
- package/skills/jgengine/capabilities.md +131 -0
- package/skills/jgengine/recipes/minimal-game.md +88 -0
- package/skills/jgengine-combat/SKILL.md +38 -0
- package/skills/jgengine-combat/api.md +585 -0
- package/skills/jgengine-combat/capabilities.md +213 -0
- package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
- package/skills/jgengine-combat/reference.md +108 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1920 -0
- package/skills/jgengine-gameplay/capabilities.md +454 -0
- package/skills/jgengine-gameplay/reference-systems.md +56 -0
- package/skills/jgengine-world/SKILL.md +51 -0
- package/skills/jgengine-world/api.md +3056 -0
- package/skills/jgengine-world/capabilities.md +476 -0
- package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
- package/skills/jgengine-world/reference.md +261 -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,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-stat growth definition for one species. `base` is the level-1 value of the stat; `growth`
|
|
3
|
+
* is how much a single distributed point adds, expressed as a fraction of `base` — so a point on a
|
|
4
|
+
* `growth: 0.1` stat is worth +10% of base. The resolved value is `base * (1 + points * growth)`.
|
|
5
|
+
*/
|
|
6
|
+
export interface SpawnStatDef {
|
|
7
|
+
base: number;
|
|
8
|
+
growth: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A species' stat table: every stat the creature owns keyed to its {@link SpawnStatDef}. The key
|
|
12
|
+
* order is the deterministic order random points are distributed over, so a serialized species
|
|
13
|
+
* definition reproduces the same rolls under the same rng sequence.
|
|
14
|
+
*/
|
|
15
|
+
export type SpawnSpeciesDef<TStat extends string> = Record<TStat, SpawnStatDef>;
|
|
16
|
+
/**
|
|
17
|
+
* A single creature's serializable stat record — a reference to its species (`speciesId`), the
|
|
18
|
+
* current `level`, the per-stat count of distributed points, and how many post-capture domestic
|
|
19
|
+
* levels have been spent. Plain data: round-trips through JSON, save/load, and multiplayer sync.
|
|
20
|
+
* Resolve display values with {@link resolveSpawnStats}.
|
|
21
|
+
*/
|
|
22
|
+
export interface CreatureStatInstance<TStat extends string> {
|
|
23
|
+
speciesId: string;
|
|
24
|
+
level: number;
|
|
25
|
+
points: Record<TStat, number>;
|
|
26
|
+
domesticLevels: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Outcome of {@link applyCaptureEffectiveness}: the granted `bonusLevels`, the `tamedLevel`
|
|
30
|
+
* (wild level plus bonus levels), and the post-capture {@link CreatureStatInstance}.
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export interface CaptureResult<TStat extends string> {
|
|
34
|
+
bonusLevels: number;
|
|
35
|
+
tamedLevel: number;
|
|
36
|
+
instance: CreatureStatInstance<TStat>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Options for {@link spendDomesticLevel}. `maxDomesticLevels` caps how many post-capture levels a
|
|
40
|
+
* creature may spend; once reached, further spends are refused.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export interface SpendLevelOptions {
|
|
44
|
+
maxDomesticLevels?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Result of {@link spendDomesticLevel}: the resulting instance and whether the level was applied
|
|
48
|
+
* (`spent: false` when the domestic-level cap blocked it, leaving the instance untouched).
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export interface SpendLevelResult<TStat extends string> {
|
|
52
|
+
instance: CreatureStatInstance<TStat>;
|
|
53
|
+
spent: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Roll a fresh wild creature at `level`: distribute `(level - 1)` points randomly across the
|
|
57
|
+
* species' stats using the injected rng and return a serializable {@link CreatureStatInstance}.
|
|
58
|
+
* Deterministic — the same rng sequence yields the same point spread. Levels below 1 clamp to 1
|
|
59
|
+
* (no points). Use `seededRng` from `../random/rng` for a persisted, reproducible stream.
|
|
60
|
+
*
|
|
61
|
+
* @capability spawn-level-roll distribute a wild creature's spawn level into random per-stat points
|
|
62
|
+
*/
|
|
63
|
+
export declare function rollSpawnInstance<TStat extends string>(speciesId: string, species: SpawnSpeciesDef<TStat>, level: number, rng: () => number): CreatureStatInstance<TStat>;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve an instance's live stat values from its distributed points:
|
|
66
|
+
* `value = base * (1 + points * growth)` per stat. Stats with zero points return their base.
|
|
67
|
+
*
|
|
68
|
+
* @capability spawn-stat-values resolve a creature's per-stat values from its distributed points
|
|
69
|
+
*/
|
|
70
|
+
export declare function resolveSpawnStats<TStat extends string>(species: SpawnSpeciesDef<TStat>, instance: CreatureStatInstance<TStat>): Record<TStat, number>;
|
|
71
|
+
/**
|
|
72
|
+
* Bonus levels granted by a capture at the given effectiveness:
|
|
73
|
+
* `floor(level * clamp01(effectiveness) / 2)`. A perfect (1.0) capture grants half the wild
|
|
74
|
+
* level; a botched (0) capture grants none. Effectiveness outside `[0,1]` clamps.
|
|
75
|
+
*
|
|
76
|
+
* @capability capture-bonus-levels convert wild level and capture effectiveness into bonus levels
|
|
77
|
+
*/
|
|
78
|
+
export declare function captureBonusLevels(level: number, effectiveness: number): number;
|
|
79
|
+
/**
|
|
80
|
+
* Apply a capture at the given effectiveness: compute bonus levels via {@link captureBonusLevels},
|
|
81
|
+
* distribute those extra points randomly with the injected rng, and return the post-capture
|
|
82
|
+
* instance (level raised to the tamed total) alongside the granted bonus levels and tamed level.
|
|
83
|
+
* The input instance is not mutated.
|
|
84
|
+
*
|
|
85
|
+
* @capability capture-effectiveness-tame apply capture effectiveness to grant and distribute bonus levels
|
|
86
|
+
*/
|
|
87
|
+
export declare function applyCaptureEffectiveness<TStat extends string>(species: SpawnSpeciesDef<TStat>, instance: CreatureStatInstance<TStat>, effectiveness: number, rng: () => number): CaptureResult<TStat>;
|
|
88
|
+
/**
|
|
89
|
+
* Spend one earned post-capture level into `stat`, adding a single growth increment (one point)
|
|
90
|
+
* and raising both `level` and `domesticLevels`. When `maxDomesticLevels` is set and already
|
|
91
|
+
* reached, the spend is refused (`spent: false`) and the instance is returned untouched. Pure:
|
|
92
|
+
* returns a new instance rather than mutating the input.
|
|
93
|
+
*
|
|
94
|
+
* @capability domestic-level-spend spend an earned post-capture level into a chosen stat under a cap
|
|
95
|
+
*/
|
|
96
|
+
export declare function spendDomesticLevel<TStat extends string>(instance: CreatureStatInstance<TStat>, stat: TStat, options?: SpendLevelOptions): SpendLevelResult<TStat>;
|
|
97
|
+
/**
|
|
98
|
+
* Deep-copy an instance into a detached, serializable record — the transport/save counterpart of
|
|
99
|
+
* {@link restoreSpawnInstance}. Copies the points map so later edits don't leak into the snapshot.
|
|
100
|
+
*
|
|
101
|
+
* @capability spawn-instance-snapshot deep-copy a creature stat instance into a serializable record
|
|
102
|
+
*/
|
|
103
|
+
export declare function snapshotSpawnInstance<TStat extends string>(instance: CreatureStatInstance<TStat>): CreatureStatInstance<TStat>;
|
|
104
|
+
/**
|
|
105
|
+
* Rehydrate a creature stat instance from decoded data (e.g. `JSON.parse` output), returning a
|
|
106
|
+
* fresh deep copy the caller owns. Inverse of {@link snapshotSpawnInstance}.
|
|
107
|
+
*
|
|
108
|
+
* @capability spawn-instance-restore rehydrate a creature stat instance from decoded snapshot data
|
|
109
|
+
*/
|
|
110
|
+
export declare function restoreSpawnInstance<TStat extends string>(data: CreatureStatInstance<TStat>): CreatureStatInstance<TStat>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
function clamp01(value) {
|
|
2
|
+
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
3
|
+
}
|
|
4
|
+
function normalizeLevel(level) {
|
|
5
|
+
const floored = Math.floor(level);
|
|
6
|
+
return floored < 1 ? 1 : floored;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Scatter `count` points one at a time across `statIds`, choosing each target uniformly from the
|
|
10
|
+
* injected rng. Mutates `into` in place; bounded by `count`. The rng draws the sole source of
|
|
11
|
+
* randomness, so an identical rng sequence reproduces an identical distribution.
|
|
12
|
+
*/
|
|
13
|
+
function distributePoints(statIds, count, rng, into) {
|
|
14
|
+
const n = statIds.length;
|
|
15
|
+
if (n === 0 || count <= 0)
|
|
16
|
+
return;
|
|
17
|
+
for (let i = 0; i < count; i++) {
|
|
18
|
+
let index = Math.floor(rng() * n);
|
|
19
|
+
if (index >= n)
|
|
20
|
+
index = n - 1;
|
|
21
|
+
if (index < 0)
|
|
22
|
+
index = 0;
|
|
23
|
+
const stat = statIds[index];
|
|
24
|
+
into[stat] = (into[stat] ?? 0) + 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function zeroedPoints(statIds) {
|
|
28
|
+
const points = {};
|
|
29
|
+
for (const stat of statIds)
|
|
30
|
+
points[stat] = 0;
|
|
31
|
+
return points;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Roll a fresh wild creature at `level`: distribute `(level - 1)` points randomly across the
|
|
35
|
+
* species' stats using the injected rng and return a serializable {@link CreatureStatInstance}.
|
|
36
|
+
* Deterministic — the same rng sequence yields the same point spread. Levels below 1 clamp to 1
|
|
37
|
+
* (no points). Use `seededRng` from `../random/rng` for a persisted, reproducible stream.
|
|
38
|
+
*
|
|
39
|
+
* @capability spawn-level-roll distribute a wild creature's spawn level into random per-stat points
|
|
40
|
+
*/
|
|
41
|
+
export function rollSpawnInstance(speciesId, species, level, rng) {
|
|
42
|
+
const statIds = Object.keys(species);
|
|
43
|
+
const points = zeroedPoints(statIds);
|
|
44
|
+
const normalized = normalizeLevel(level);
|
|
45
|
+
distributePoints(statIds, normalized - 1, rng, points);
|
|
46
|
+
return { speciesId, level: normalized, points, domesticLevels: 0 };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve an instance's live stat values from its distributed points:
|
|
50
|
+
* `value = base * (1 + points * growth)` per stat. Stats with zero points return their base.
|
|
51
|
+
*
|
|
52
|
+
* @capability spawn-stat-values resolve a creature's per-stat values from its distributed points
|
|
53
|
+
*/
|
|
54
|
+
export function resolveSpawnStats(species, instance) {
|
|
55
|
+
const out = {};
|
|
56
|
+
for (const stat of Object.keys(species)) {
|
|
57
|
+
const def = species[stat];
|
|
58
|
+
const pts = instance.points[stat] ?? 0;
|
|
59
|
+
out[stat] = def.base * (1 + pts * def.growth);
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Bonus levels granted by a capture at the given effectiveness:
|
|
65
|
+
* `floor(level * clamp01(effectiveness) / 2)`. A perfect (1.0) capture grants half the wild
|
|
66
|
+
* level; a botched (0) capture grants none. Effectiveness outside `[0,1]` clamps.
|
|
67
|
+
*
|
|
68
|
+
* @capability capture-bonus-levels convert wild level and capture effectiveness into bonus levels
|
|
69
|
+
*/
|
|
70
|
+
export function captureBonusLevels(level, effectiveness) {
|
|
71
|
+
return Math.floor((normalizeLevel(level) * clamp01(effectiveness)) / 2);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Apply a capture at the given effectiveness: compute bonus levels via {@link captureBonusLevels},
|
|
75
|
+
* distribute those extra points randomly with the injected rng, and return the post-capture
|
|
76
|
+
* instance (level raised to the tamed total) alongside the granted bonus levels and tamed level.
|
|
77
|
+
* The input instance is not mutated.
|
|
78
|
+
*
|
|
79
|
+
* @capability capture-effectiveness-tame apply capture effectiveness to grant and distribute bonus levels
|
|
80
|
+
*/
|
|
81
|
+
export function applyCaptureEffectiveness(species, instance, effectiveness, rng) {
|
|
82
|
+
const bonusLevels = captureBonusLevels(instance.level, effectiveness);
|
|
83
|
+
const statIds = Object.keys(species);
|
|
84
|
+
const points = { ...instance.points };
|
|
85
|
+
distributePoints(statIds, bonusLevels, rng, points);
|
|
86
|
+
const tamedLevel = instance.level + bonusLevels;
|
|
87
|
+
return {
|
|
88
|
+
bonusLevels,
|
|
89
|
+
tamedLevel,
|
|
90
|
+
instance: { ...instance, level: tamedLevel, points },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Spend one earned post-capture level into `stat`, adding a single growth increment (one point)
|
|
95
|
+
* and raising both `level` and `domesticLevels`. When `maxDomesticLevels` is set and already
|
|
96
|
+
* reached, the spend is refused (`spent: false`) and the instance is returned untouched. Pure:
|
|
97
|
+
* returns a new instance rather than mutating the input.
|
|
98
|
+
*
|
|
99
|
+
* @capability domestic-level-spend spend an earned post-capture level into a chosen stat under a cap
|
|
100
|
+
*/
|
|
101
|
+
export function spendDomesticLevel(instance, stat, options) {
|
|
102
|
+
const cap = options?.maxDomesticLevels;
|
|
103
|
+
if (cap !== undefined && instance.domesticLevels >= cap) {
|
|
104
|
+
return { instance, spent: false };
|
|
105
|
+
}
|
|
106
|
+
const points = { ...instance.points };
|
|
107
|
+
points[stat] = (points[stat] ?? 0) + 1;
|
|
108
|
+
return {
|
|
109
|
+
instance: {
|
|
110
|
+
...instance,
|
|
111
|
+
points,
|
|
112
|
+
level: instance.level + 1,
|
|
113
|
+
domesticLevels: instance.domesticLevels + 1,
|
|
114
|
+
},
|
|
115
|
+
spent: true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Deep-copy an instance into a detached, serializable record — the transport/save counterpart of
|
|
120
|
+
* {@link restoreSpawnInstance}. Copies the points map so later edits don't leak into the snapshot.
|
|
121
|
+
*
|
|
122
|
+
* @capability spawn-instance-snapshot deep-copy a creature stat instance into a serializable record
|
|
123
|
+
*/
|
|
124
|
+
export function snapshotSpawnInstance(instance) {
|
|
125
|
+
return {
|
|
126
|
+
speciesId: instance.speciesId,
|
|
127
|
+
level: instance.level,
|
|
128
|
+
domesticLevels: instance.domesticLevels,
|
|
129
|
+
points: { ...instance.points },
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Rehydrate a creature stat instance from decoded data (e.g. `JSON.parse` output), returning a
|
|
134
|
+
* fresh deep copy the caller owns. Inverse of {@link snapshotSpawnInstance}.
|
|
135
|
+
*
|
|
136
|
+
* @capability spawn-instance-restore rehydrate a creature stat instance from decoded snapshot data
|
|
137
|
+
*/
|
|
138
|
+
export function restoreSpawnInstance(data) {
|
|
139
|
+
return snapshotSpawnInstance(data);
|
|
140
|
+
}
|
|
@@ -18,4 +18,9 @@ export interface Stats<TStat extends string> {
|
|
|
18
18
|
pruneExpired(nowMs: number): string[];
|
|
19
19
|
sources(): string[];
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* A stat block whose base values take stacking, timed buffs and debuffs, resolving the modified value on read.
|
|
23
|
+
*
|
|
24
|
+
* @capability stat-block base stats with stacking, expiring buffs and debuffs applied on read
|
|
25
|
+
*/
|
|
21
26
|
export declare function createStats<TStat extends string>(base: Record<TStat, number>, options?: CreateStatsOptions): Stats<TStat>;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A stat block whose base values take stacking, timed buffs and debuffs, resolving the modified value on read.
|
|
3
|
+
*
|
|
4
|
+
* @capability stat-block base stats with stacking, expiring buffs and debuffs applied on read
|
|
5
|
+
*/
|
|
1
6
|
export function createStats(base, options) {
|
|
2
7
|
const baseValues = { ...base };
|
|
3
8
|
const sourceEntries = new Map();
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** Serializable state for any bounded named resource. The caller defines what the resource means. */
|
|
2
|
+
export interface StatPool {
|
|
3
|
+
current: number;
|
|
4
|
+
max: number;
|
|
5
|
+
min: number;
|
|
6
|
+
}
|
|
7
|
+
/** Input used to create a normalized pool. `current` defaults to `max`; `min` defaults to zero. */
|
|
8
|
+
export interface StatPoolInput {
|
|
9
|
+
current?: number;
|
|
10
|
+
max: number;
|
|
11
|
+
min?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Partial update applied without mutating the previous pool. */
|
|
14
|
+
export interface StatPoolPatch {
|
|
15
|
+
current?: number;
|
|
16
|
+
max?: number;
|
|
17
|
+
min?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Structural bridge to caller-owned resource state. Implement it over an ECS,
|
|
21
|
+
* Redux/Zustand store, plain object, database-backed model, or JGengine's native
|
|
22
|
+
* entity stats without moving ownership into the SDK.
|
|
23
|
+
*/
|
|
24
|
+
export interface StatPoolAccess<TOwnerId extends string = string, TStatId extends string = string> {
|
|
25
|
+
get(ownerId: TOwnerId, statId: TStatId): StatPool | null;
|
|
26
|
+
set(ownerId: TOwnerId, statId: TStatId, next: StatPool): unknown;
|
|
27
|
+
}
|
|
28
|
+
/** Inspectable result of a bounded pool change. */
|
|
29
|
+
export interface StatPoolChange {
|
|
30
|
+
previous: StatPool;
|
|
31
|
+
pool: StatPool;
|
|
32
|
+
/** Actual applied amount after clamping. */
|
|
33
|
+
applied: number;
|
|
34
|
+
hitMin: boolean;
|
|
35
|
+
hitMax: boolean;
|
|
36
|
+
}
|
|
37
|
+
/** Outcome of changing a pool through {@link StatPoolAccess}. */
|
|
38
|
+
export type StatPoolAccessResult = ({
|
|
39
|
+
status: "ok";
|
|
40
|
+
} & StatPoolChange) | {
|
|
41
|
+
status: "rejected";
|
|
42
|
+
reason: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Normalize caller data into a complete plain-data pool.
|
|
46
|
+
*
|
|
47
|
+
* @capability stat-pool create a serializable current/min/max pool for any caller-named resource
|
|
48
|
+
*/
|
|
49
|
+
export declare function createStatPool(input: StatPoolInput): StatPool;
|
|
50
|
+
/**
|
|
51
|
+
* Apply new bounds/current to a pool, clamping the result and leaving the input untouched.
|
|
52
|
+
*
|
|
53
|
+
* @capability stat-pool-patch immutably retune a bounded resource's current value or bounds
|
|
54
|
+
*/
|
|
55
|
+
export declare function patchStatPool(pool: StatPool, patch: StatPoolPatch): StatPool;
|
|
56
|
+
/**
|
|
57
|
+
* Pure bounded delta transition with the exact applied amount and boundary flags.
|
|
58
|
+
*
|
|
59
|
+
* @capability stat-pool-change immutably increase or decrease any named bounded resource with clamp evidence
|
|
60
|
+
*/
|
|
61
|
+
export declare function changeStatPool(pool: StatPool, amount: number): StatPoolChange;
|
|
62
|
+
/**
|
|
63
|
+
* Read, transition, and write a caller-owned pool through the structural
|
|
64
|
+
* adapter. Positive amounts increase the resource; negative amounts decrease
|
|
65
|
+
* it. The adapter receives a complete replacement value, never a hidden
|
|
66
|
+
* mutation.
|
|
67
|
+
*
|
|
68
|
+
* @capability portable-stat-pool apply deterministic bounded resource changes through a caller-owned stat adapter
|
|
69
|
+
*/
|
|
70
|
+
export declare function applyStatPoolDelta<TOwnerId extends string, TStatId extends string>(access: StatPoolAccess<TOwnerId, TStatId>, ownerId: TOwnerId, statId: TStatId, amount: number): StatPoolAccessResult;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { clamp } from "../math/scalar.js";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize caller data into a complete plain-data pool.
|
|
4
|
+
*
|
|
5
|
+
* @capability stat-pool create a serializable current/min/max pool for any caller-named resource
|
|
6
|
+
*/
|
|
7
|
+
export function createStatPool(input) {
|
|
8
|
+
const min = input.min ?? 0;
|
|
9
|
+
return {
|
|
10
|
+
current: clamp(input.current ?? input.max, min, input.max),
|
|
11
|
+
max: input.max,
|
|
12
|
+
min,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Apply new bounds/current to a pool, clamping the result and leaving the input untouched.
|
|
17
|
+
*
|
|
18
|
+
* @capability stat-pool-patch immutably retune a bounded resource's current value or bounds
|
|
19
|
+
*/
|
|
20
|
+
export function patchStatPool(pool, patch) {
|
|
21
|
+
const max = patch.max ?? pool.max;
|
|
22
|
+
const min = patch.min ?? pool.min;
|
|
23
|
+
return {
|
|
24
|
+
current: clamp(patch.current ?? pool.current, min, max),
|
|
25
|
+
max,
|
|
26
|
+
min,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pure bounded delta transition with the exact applied amount and boundary flags.
|
|
31
|
+
*
|
|
32
|
+
* @capability stat-pool-change immutably increase or decrease any named bounded resource with clamp evidence
|
|
33
|
+
*/
|
|
34
|
+
export function changeStatPool(pool, amount) {
|
|
35
|
+
const next = patchStatPool(pool, { current: pool.current + amount });
|
|
36
|
+
return {
|
|
37
|
+
previous: pool,
|
|
38
|
+
pool: next,
|
|
39
|
+
applied: next.current - pool.current,
|
|
40
|
+
hitMin: next.current === next.min,
|
|
41
|
+
hitMax: next.current === next.max,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read, transition, and write a caller-owned pool through the structural
|
|
46
|
+
* adapter. Positive amounts increase the resource; negative amounts decrease
|
|
47
|
+
* it. The adapter receives a complete replacement value, never a hidden
|
|
48
|
+
* mutation.
|
|
49
|
+
*
|
|
50
|
+
* @capability portable-stat-pool apply deterministic bounded resource changes through a caller-owned stat adapter
|
|
51
|
+
*/
|
|
52
|
+
export function applyStatPoolDelta(access, ownerId, statId, amount) {
|
|
53
|
+
const pool = access.get(ownerId, statId);
|
|
54
|
+
if (pool === null)
|
|
55
|
+
return { status: "rejected", reason: `unknown stat "${statId}"` };
|
|
56
|
+
const change = changeStatPool(pool, amount);
|
|
57
|
+
access.set(ownerId, statId, change.pool);
|
|
58
|
+
return { status: "ok", ...change };
|
|
59
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export interface ChangeSignal {
|
|
2
3
|
subscribe(listener: () => void): () => void;
|
|
3
4
|
notify(): void;
|
|
4
5
|
version(): number;
|
|
5
6
|
}
|
|
7
|
+
/** @internal */
|
|
6
8
|
export declare function createChangeSignal(): ChangeSignal;
|
|
9
|
+
/** @internal */
|
|
7
10
|
export declare function notifyAfter<T extends object, K extends keyof T>(target: T, methods: readonly K[], notify: () => void): T;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export function createChangeSignal() {
|
|
2
3
|
const listeners = new Set();
|
|
3
4
|
let version = 0;
|
|
@@ -18,6 +19,7 @@ export function createChangeSignal() {
|
|
|
18
19
|
},
|
|
19
20
|
};
|
|
20
21
|
}
|
|
22
|
+
/** @internal */
|
|
21
23
|
export function notifyAfter(target, methods, notify) {
|
|
22
24
|
const wrapped = { ...target };
|
|
23
25
|
for (const method of methods) {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { GameContext } from "../runtime/gameContext.js";
|
|
2
|
+
/**
|
|
3
|
+
* A typed, cast-free handle onto a per-owner keyed family of slots on the reactive game store
|
|
4
|
+
* (`ctx.game.store`) — the {@link StoreHandle} shape widened with an `id` (userId, instanceId, …)
|
|
5
|
+
* so one definition covers every owner instead of one `defineStore` call per key. `keyFor` composes
|
|
6
|
+
* the underlying store key from the id; call sites never see it. Writes flow through the engine
|
|
7
|
+
* store, so they bump `ctx.version()`, serialize into a {@link WorldSnapshot}, and replay under host
|
|
8
|
+
* authority — the same guarantees a hand-rolled `` `prefix:${id}` `` string plus `store.get(key) as T`
|
|
9
|
+
* gives up.
|
|
10
|
+
*/
|
|
11
|
+
export interface KeyedStoreHandle<T> {
|
|
12
|
+
/** Compose the underlying store key for one owner. Exposed for snapshot/debug tooling; call sites use {@link read}/{@link write}. */
|
|
13
|
+
keyFor(id: string): string;
|
|
14
|
+
/** The current value for `id`, or the definition's initial when that slot has never been written. */
|
|
15
|
+
read(ctx: GameContext, id: string): T;
|
|
16
|
+
/** The raw stored value for `id`, or `undefined` when unset — distinguishes "never written" from the initial. */
|
|
17
|
+
peek(ctx: GameContext, id: string): T | undefined;
|
|
18
|
+
/** Overwrite `id`'s slot; bumps `ctx.version()` and notifies `ctx.subscribe`. */
|
|
19
|
+
write(ctx: GameContext, id: string, value: T): void;
|
|
20
|
+
/** Read-modify-write `id`'s slot in one step, returning the next value. `mutate` receives the current value (or initial when unset). */
|
|
21
|
+
update(ctx: GameContext, id: string, mutate: (previous: T) => T): T;
|
|
22
|
+
/** Delete `id`'s slot, so the next {@link read} for that id returns the initial again. */
|
|
23
|
+
clear(ctx: GameContext, id: string): void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Define a typed per-owner keyed family on the game store: game code expresses
|
|
27
|
+
* `read(ctx, userId)`/`write(ctx, userId, v)`/`update(...)` with the value type it means, and both the
|
|
28
|
+
* `` `prefix:${id}` `` key composition and the `unknown → T` cast live once, here, behind the boundary.
|
|
29
|
+
* Reach for this over N separate `defineStore` calls whenever the owning id varies at runtime (per-user
|
|
30
|
+
* class, per-instance auras) — `defineStore` stays the right call for a single fixed slot.
|
|
31
|
+
*
|
|
32
|
+
* Pass a factory for `initial` when the fallback is a fresh mutable object; the factory runs at most
|
|
33
|
+
* once **per id** and its result is reused, so an unwritten id's slot keeps a stable identity across
|
|
34
|
+
* reads (no per-read churn for a React selector, no allocation on a hot path).
|
|
35
|
+
*
|
|
36
|
+
* @capability typed-keyed-store a cast-free typed handle onto a per-owner keyed family of reactive game-store slots, replayable and host-authoritative
|
|
37
|
+
*/
|
|
38
|
+
export declare function defineKeyedStore<T>(keyFor: (id: string) => string, initial: T | (() => T)): KeyedStoreHandle<T>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Define a typed per-owner keyed family on the game store: game code expresses
|
|
3
|
+
* `read(ctx, userId)`/`write(ctx, userId, v)`/`update(...)` with the value type it means, and both the
|
|
4
|
+
* `` `prefix:${id}` `` key composition and the `unknown → T` cast live once, here, behind the boundary.
|
|
5
|
+
* Reach for this over N separate `defineStore` calls whenever the owning id varies at runtime (per-user
|
|
6
|
+
* class, per-instance auras) — `defineStore` stays the right call for a single fixed slot.
|
|
7
|
+
*
|
|
8
|
+
* Pass a factory for `initial` when the fallback is a fresh mutable object; the factory runs at most
|
|
9
|
+
* once **per id** and its result is reused, so an unwritten id's slot keeps a stable identity across
|
|
10
|
+
* reads (no per-read churn for a React selector, no allocation on a hot path).
|
|
11
|
+
*
|
|
12
|
+
* @capability typed-keyed-store a cast-free typed handle onto a per-owner keyed family of reactive game-store slots, replayable and host-authoritative
|
|
13
|
+
*/
|
|
14
|
+
export function defineKeyedStore(keyFor, initial) {
|
|
15
|
+
const resolved = new Map();
|
|
16
|
+
const initialValue = (id) => {
|
|
17
|
+
if (typeof initial !== "function")
|
|
18
|
+
return initial;
|
|
19
|
+
let entry = resolved.get(id);
|
|
20
|
+
if (entry === undefined) {
|
|
21
|
+
entry = { value: initial() };
|
|
22
|
+
resolved.set(id, entry);
|
|
23
|
+
}
|
|
24
|
+
return entry.value;
|
|
25
|
+
};
|
|
26
|
+
const read = (ctx, id) => {
|
|
27
|
+
const value = ctx.game.store.get(keyFor(id));
|
|
28
|
+
return value === undefined ? initialValue(id) : value;
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
keyFor,
|
|
32
|
+
read,
|
|
33
|
+
peek: (ctx, id) => ctx.game.store.get(keyFor(id)),
|
|
34
|
+
write: (ctx, id, value) => ctx.game.store.set(keyFor(id), value),
|
|
35
|
+
update: (ctx, id, mutate) => {
|
|
36
|
+
const next = mutate(read(ctx, id));
|
|
37
|
+
ctx.game.store.set(keyFor(id), next);
|
|
38
|
+
return next;
|
|
39
|
+
},
|
|
40
|
+
clear: (ctx, id) => ctx.game.store.delete(keyFor(id)),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GameContext } from "../runtime/gameContext.js";
|
|
2
|
+
/**
|
|
3
|
+
* A typed, cast-free handle onto one slot of the reactive game store (`ctx.game.store`). The single
|
|
4
|
+
* type parameter is fixed at definition; `read`/`write`/`update` never widen to `unknown`, so no call
|
|
5
|
+
* site repeats `store.get(key) as T`. Writes flow through the engine store, so they bump
|
|
6
|
+
* `ctx.version()`, serialize into a {@link WorldSnapshot}, and replay under host authority — the same
|
|
7
|
+
* guarantees a hand-rolled `store.get`/`store.set` pair gives up the moment it forks run state into a
|
|
8
|
+
* module-level singleton.
|
|
9
|
+
*/
|
|
10
|
+
export interface StoreHandle<T> {
|
|
11
|
+
/** The underlying store key. Exposed for snapshot/debug tooling; call sites use {@link read}/{@link write}. */
|
|
12
|
+
readonly key: string;
|
|
13
|
+
/** The current value, or the definition's initial when the slot has never been written. */
|
|
14
|
+
read(ctx: GameContext): T;
|
|
15
|
+
/** The raw stored value, or `undefined` when unset — for callers that need to distinguish "never written" from the initial. */
|
|
16
|
+
peek(ctx: GameContext): T | undefined;
|
|
17
|
+
/** Overwrite the slot; bumps `ctx.version()` and notifies `ctx.subscribe`. */
|
|
18
|
+
write(ctx: GameContext, value: T): void;
|
|
19
|
+
/** Read-modify-write in one step, returning the next value. `mutate` receives the current value (or initial when unset). */
|
|
20
|
+
update(ctx: GameContext, mutate: (previous: T) => T): T;
|
|
21
|
+
/** Delete the slot, so the next {@link read} returns the initial again. */
|
|
22
|
+
clear(ctx: GameContext): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Define a typed slot on the game store: game code expresses `read(ctx)`/`write(ctx, v)`/`update(...)`
|
|
26
|
+
* with the value type it means, and the `unknown → T` cast lives once, here, behind the boundary. Pass
|
|
27
|
+
* a factory for `initial` when the fallback is a fresh mutable object; the factory runs at most once and
|
|
28
|
+
* its result is reused, so an unwritten slot keeps a stable identity across reads (no per-read churn for
|
|
29
|
+
* a React selector, no allocation on a hot path).
|
|
30
|
+
*
|
|
31
|
+
* @capability typed-store a cast-free typed handle onto one reactive game-store slot, replayable and host-authoritative
|
|
32
|
+
*/
|
|
33
|
+
export declare function defineStore<T>(key: string, initial: T | (() => T)): StoreHandle<T>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Define a typed slot on the game store: game code expresses `read(ctx)`/`write(ctx, v)`/`update(...)`
|
|
3
|
+
* with the value type it means, and the `unknown → T` cast lives once, here, behind the boundary. Pass
|
|
4
|
+
* a factory for `initial` when the fallback is a fresh mutable object; the factory runs at most once and
|
|
5
|
+
* its result is reused, so an unwritten slot keeps a stable identity across reads (no per-read churn for
|
|
6
|
+
* a React selector, no allocation on a hot path).
|
|
7
|
+
*
|
|
8
|
+
* @capability typed-store a cast-free typed handle onto one reactive game-store slot, replayable and host-authoritative
|
|
9
|
+
*/
|
|
10
|
+
export function defineStore(key, initial) {
|
|
11
|
+
let resolved = null;
|
|
12
|
+
const initialValue = () => {
|
|
13
|
+
if (typeof initial !== "function")
|
|
14
|
+
return initial;
|
|
15
|
+
if (resolved === null)
|
|
16
|
+
resolved = { value: initial() };
|
|
17
|
+
return resolved.value;
|
|
18
|
+
};
|
|
19
|
+
const read = (ctx) => {
|
|
20
|
+
const value = ctx.game.store.get(key);
|
|
21
|
+
return value === undefined ? initialValue() : value;
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
key,
|
|
25
|
+
read,
|
|
26
|
+
peek: (ctx) => ctx.game.store.get(key),
|
|
27
|
+
write: (ctx, value) => ctx.game.store.set(key, value),
|
|
28
|
+
update: (ctx, mutate) => {
|
|
29
|
+
const next = mutate(read(ctx));
|
|
30
|
+
ctx.game.store.set(key, next);
|
|
31
|
+
return next;
|
|
32
|
+
},
|
|
33
|
+
clear: (ctx) => ctx.game.store.delete(key),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export interface ObservableKeyedStore<T> {
|
|
2
3
|
set(key: string, value: T): void;
|
|
3
4
|
delete(key: string): void;
|
|
4
5
|
get(key: string): T | undefined;
|
|
5
6
|
has(key: string): boolean;
|
|
6
7
|
subscribe(listener: () => void): () => void;
|
|
8
|
+
/** Notified only when membership changes (a key is added, deleted, or hydrated) — value updates on an existing key do not fire. Pair with {@link keysSnapshot}. */
|
|
9
|
+
subscribeMembership(listener: () => void): () => void;
|
|
10
|
+
/** An owned copy of the store's entries — mutating the returned map never reaches the store. Stable identity until the next write, like {@link arraySnapshot}. */
|
|
7
11
|
mapSnapshot(): ReadonlyMap<string, T>;
|
|
8
12
|
arraySnapshot(): readonly T[];
|
|
13
|
+
/** Stable-identity list of keys; identity changes only when membership changes, so a per-frame `set` on an existing key does not churn it. */
|
|
14
|
+
keysSnapshot(): readonly string[];
|
|
9
15
|
/** Serializable `[key, value]` entries — the transport counterpart of {@link hydrate} for host→client mirroring. */
|
|
10
16
|
snapshot(): readonly (readonly [string, T])[];
|
|
11
17
|
/** Replace all entries with `data` (clears keys absent from it), emitting once. */
|
|
12
18
|
hydrate(data: readonly (readonly [string, T])[]): void;
|
|
13
19
|
}
|
|
20
|
+
/** @internal */
|
|
14
21
|
export declare function createObservableKeyedStore<T>(areEqual?: (previous: T, next: T) => boolean): ObservableKeyedStore<T>;
|