@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,147 @@
|
|
|
1
|
+
import type { MobVec3 } from "../ai/mobBrain.js";
|
|
2
|
+
import type { StatCatalog, StatValue, StatValueMap } from "./entityStats.js";
|
|
3
|
+
/**
|
|
4
|
+
* A tamed companion's standing order. Genre-agnostic aggression + posture preset:
|
|
5
|
+
* - `follow` — heel to the owner and assist whatever the owner is fighting.
|
|
6
|
+
* - `stay` — hold at `home` and assist the owner's target from there.
|
|
7
|
+
* - `passive` — heel to the owner and never engage (a pacifist escort).
|
|
8
|
+
* - `neutral` — heel to the owner and only fight back nearby threats (defensive).
|
|
9
|
+
* - `aggressive` — heel to the owner and proactively engage nearby threats and the owner's target.
|
|
10
|
+
*/
|
|
11
|
+
export type CompanionCommand = "follow" | "stay" | "passive" | "neutral" | "aggressive";
|
|
12
|
+
/**
|
|
13
|
+
* Serializable per-companion state: who owns it, its standing order, where it holds, its
|
|
14
|
+
* leash radius, and its levelled stat pool. Plain data — JSON round-trips without loss.
|
|
15
|
+
*/
|
|
16
|
+
export interface CompanionRecord {
|
|
17
|
+
id: string;
|
|
18
|
+
/** Owning user/entity id — the roster ownership tie. */
|
|
19
|
+
ownerId: string;
|
|
20
|
+
/** The {@link RosterEntry.id} this companion was tamed from, or `null` when free-standing. */
|
|
21
|
+
sourceId: string | null;
|
|
22
|
+
command: CompanionCommand;
|
|
23
|
+
/** Hold/return anchor used by `stay`; `null` until the owner parks it somewhere. */
|
|
24
|
+
home: MobVec3 | null;
|
|
25
|
+
/** Radius the game keeps the companion within of its resolved anchor (feeds a brain's leash distance). */
|
|
26
|
+
leash: number;
|
|
27
|
+
level: number;
|
|
28
|
+
/** Stat points earned from levels and not yet spent via {@link CompanionRoster.spend}. */
|
|
29
|
+
unspentPoints: number;
|
|
30
|
+
/** Levelled stat pool, composed over `scene/entityStats`. */
|
|
31
|
+
stats: StatValueMap;
|
|
32
|
+
}
|
|
33
|
+
/** Per-tick world context the game supplies so a command resolves into a concrete intent. */
|
|
34
|
+
export interface CompanionIntentContext {
|
|
35
|
+
/** Owner's current world position — the anchor for every non-`stay` mode; `null` when absent. */
|
|
36
|
+
ownerPosition?: MobVec3 | null;
|
|
37
|
+
/** The owner's current attack target — the companion assists/aggros it per its command. */
|
|
38
|
+
ownerTargetId?: string | null;
|
|
39
|
+
/** Threat ids near the companion the game offers as engage candidates (already proximity-filtered upstream). */
|
|
40
|
+
threats?: readonly string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The companion's decision for one tick, shaped for `ai/mobBrain`: feed `candidates` into
|
|
44
|
+
* `MobBrainDeps.candidates()`, treat `leashTo` as the brain's `home`, and pass `leashDistance`
|
|
45
|
+
* as `leashDistance`. `kind` summarises the posture for HUD/animation.
|
|
46
|
+
*/
|
|
47
|
+
export interface CompanionIntent {
|
|
48
|
+
/** `follow`/`hold` when idle at the anchor; `engage` a fresh threat; `assist` the owner's target. */
|
|
49
|
+
kind: "follow" | "hold" | "engage" | "assist";
|
|
50
|
+
/** Whether the companion leashes to the owner (follow modes) or its `home` (stay). */
|
|
51
|
+
anchor: "owner" | "home";
|
|
52
|
+
/** Resolved anchor world point — owner position or `home`; `null` when that point is unknown. */
|
|
53
|
+
leashTo: MobVec3 | null;
|
|
54
|
+
/** Leash radius (copied from the record) the game passes to the brain / clamps movement against. */
|
|
55
|
+
leashDistance: number;
|
|
56
|
+
/** Threat ids to expose as `MobBrainDeps.candidates()`; empty when the command forbids engaging. */
|
|
57
|
+
candidates: readonly string[];
|
|
58
|
+
/** The primary threat to engage/assist this tick — `candidates[0]`; `null` while following/holding. */
|
|
59
|
+
targetId: string | null;
|
|
60
|
+
}
|
|
61
|
+
/** Rule for turning one spent level-point into a stat gain. Absent from config ⇒ the stat can't be upgraded. */
|
|
62
|
+
export interface CompanionStatUpgrade {
|
|
63
|
+
/** Amount a single point adds to the stat's `max` (and heals into `current`). */
|
|
64
|
+
increment: number;
|
|
65
|
+
/** Hard ceiling for the stat's `max`; spends that would exceed it are rejected. */
|
|
66
|
+
maxCap?: number;
|
|
67
|
+
}
|
|
68
|
+
/** Outcome of {@link CompanionRoster.spend}: the updated record + stat, or a rejection reason. */
|
|
69
|
+
export type CompanionSpendResult = {
|
|
70
|
+
status: "ok";
|
|
71
|
+
record: CompanionRecord;
|
|
72
|
+
stat: StatValue;
|
|
73
|
+
} | {
|
|
74
|
+
status: "rejected";
|
|
75
|
+
reason: string;
|
|
76
|
+
};
|
|
77
|
+
/** Per-companion configuration shared by every companion the roster mints. */
|
|
78
|
+
export interface CompanionConfig {
|
|
79
|
+
/** Stat catalog seeded into each new companion's pool (via `entityStats.seedStatValues`). */
|
|
80
|
+
stats?: StatCatalog;
|
|
81
|
+
/** Per-stat upgrade rules consulted by {@link CompanionRoster.spend}. */
|
|
82
|
+
upgrades?: Record<string, CompanionStatUpgrade>;
|
|
83
|
+
/** Points granted on reaching a given level; default `1` per level. Inject `game/progression` curves here. */
|
|
84
|
+
pointsPerLevel?: (level: number) => number;
|
|
85
|
+
/** Level ceiling; `levelUp` past it is a no-op. Default `Infinity`. */
|
|
86
|
+
maxLevel?: number;
|
|
87
|
+
/** Level every companion starts at; default `1`. */
|
|
88
|
+
startLevel?: number;
|
|
89
|
+
/** Default leash radius for new companions; default `12`. */
|
|
90
|
+
leash?: number;
|
|
91
|
+
}
|
|
92
|
+
/** Options for {@link CompanionRoster.adopt}. */
|
|
93
|
+
export interface CompanionAdoptOptions {
|
|
94
|
+
id?: string;
|
|
95
|
+
/** The {@link RosterEntry.id} this companion springs from — the ownership/catalog tie. */
|
|
96
|
+
sourceId?: string;
|
|
97
|
+
command?: CompanionCommand;
|
|
98
|
+
home?: MobVec3 | null;
|
|
99
|
+
leash?: number;
|
|
100
|
+
level?: number;
|
|
101
|
+
/** Override the config stat catalog for this one companion. */
|
|
102
|
+
stats?: StatCatalog;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A set of tamed companions keyed by companion id, scoped to owners. Wraps allegiance/command
|
|
106
|
+
* state, per-companion levelled stats, and intent resolution behind create/command/level/
|
|
107
|
+
* snapshot/hydrate — the counterpart of `scene/roster` for creatures that fight beside you.
|
|
108
|
+
*/
|
|
109
|
+
export interface CompanionRoster {
|
|
110
|
+
/** Mint a companion for an owner (optionally tied to a {@link RosterEntry}). */
|
|
111
|
+
adopt(ownerId: string, options?: CompanionAdoptOptions): CompanionRecord;
|
|
112
|
+
release(companionId: string): boolean;
|
|
113
|
+
get(companionId: string): CompanionRecord | null;
|
|
114
|
+
ownerOf(companionId: string): string | null;
|
|
115
|
+
list(ownerId: string): readonly CompanionRecord[];
|
|
116
|
+
/** Set a companion's standing order; `null` if the id is unknown. */
|
|
117
|
+
command(companionId: string, command: CompanionCommand): CompanionRecord | null;
|
|
118
|
+
/** Park/clear a companion's `stay` anchor. */
|
|
119
|
+
setHome(companionId: string, home: MobVec3 | null): CompanionRecord | null;
|
|
120
|
+
setLeash(companionId: string, leash: number): CompanionRecord | null;
|
|
121
|
+
/** Gain `levels` levels (bounded by `maxLevel`), accruing points from `pointsPerLevel`. */
|
|
122
|
+
levelUp(companionId: string, levels?: number): CompanionRecord | null;
|
|
123
|
+
/** Spend one earned point into a stat per its {@link CompanionStatUpgrade} rule. */
|
|
124
|
+
spend(companionId: string, statId: string): CompanionSpendResult;
|
|
125
|
+
/** Resolve the companion's per-tick {@link CompanionIntent}; `null` if the id is unknown. */
|
|
126
|
+
resolveIntent(companionId: string, context: CompanionIntentContext): CompanionIntent | null;
|
|
127
|
+
/** Whole-store serializable copy — the save/replication seam. */
|
|
128
|
+
snapshot(): Record<string, CompanionRecord>;
|
|
129
|
+
hydrate(data: Record<string, CompanionRecord>): void;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Pure command → intent resolver. Maps a companion's standing order plus this tick's owner
|
|
133
|
+
* position, owner target, and nearby threats into the {@link CompanionIntent} a game feeds into
|
|
134
|
+
* `ai/mobBrain` (or executes directly). Deterministic and allocation-light — no import of the
|
|
135
|
+
* `@internal` brain factory; the two interoperate purely by shape.
|
|
136
|
+
*
|
|
137
|
+
* @capability companion-intent resolve a companion's command + threat context into a per-tick follow/hold/engage/assist intent
|
|
138
|
+
*/
|
|
139
|
+
export declare function resolveCompanionIntent(record: CompanionRecord, context: CompanionIntentContext): CompanionIntent;
|
|
140
|
+
/**
|
|
141
|
+
* Build a {@link CompanionRoster}. Composes `scene/roster` ownership (via `ownerId`/`sourceId`),
|
|
142
|
+
* `scene/entityStats` for the per-companion stat pool, and {@link resolveCompanionIntent} for
|
|
143
|
+
* `ai/mobBrain`-shaped behavior — turning a captured creature into a loyal, levelling ally.
|
|
144
|
+
*
|
|
145
|
+
* @capability companion-roster manage tamed companions — allegiance, commands, per-companion stats/leveling, and mobBrain-shaped intent
|
|
146
|
+
*/
|
|
147
|
+
export declare function createCompanionRoster(config?: CompanionConfig): CompanionRoster;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { seedStatValues, setStatValue } from "./entityStats.js";
|
|
2
|
+
function dedupePush(out, id) {
|
|
3
|
+
if (!out.includes(id))
|
|
4
|
+
out.push(id);
|
|
5
|
+
}
|
|
6
|
+
function candidatesFor(command, ownerTargetId, threats) {
|
|
7
|
+
switch (command) {
|
|
8
|
+
case "passive":
|
|
9
|
+
return [];
|
|
10
|
+
case "follow":
|
|
11
|
+
case "stay":
|
|
12
|
+
return ownerTargetId === null ? [] : [ownerTargetId];
|
|
13
|
+
case "neutral":
|
|
14
|
+
return [...threats];
|
|
15
|
+
case "aggressive": {
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const threat of threats)
|
|
18
|
+
dedupePush(out, threat);
|
|
19
|
+
if (ownerTargetId !== null)
|
|
20
|
+
dedupePush(out, ownerTargetId);
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pure command → intent resolver. Maps a companion's standing order plus this tick's owner
|
|
27
|
+
* position, owner target, and nearby threats into the {@link CompanionIntent} a game feeds into
|
|
28
|
+
* `ai/mobBrain` (or executes directly). Deterministic and allocation-light — no import of the
|
|
29
|
+
* `@internal` brain factory; the two interoperate purely by shape.
|
|
30
|
+
*
|
|
31
|
+
* @capability companion-intent resolve a companion's command + threat context into a per-tick follow/hold/engage/assist intent
|
|
32
|
+
*/
|
|
33
|
+
export function resolveCompanionIntent(record, context) {
|
|
34
|
+
const ownerTargetId = context.ownerTargetId ?? null;
|
|
35
|
+
const threats = context.threats ?? [];
|
|
36
|
+
const anchor = record.command === "stay" ? "home" : "owner";
|
|
37
|
+
const leashTo = anchor === "home" ? record.home : (context.ownerPosition ?? null);
|
|
38
|
+
const candidates = candidatesFor(record.command, ownerTargetId, threats);
|
|
39
|
+
const targetId = candidates.length > 0 ? candidates[0] : null;
|
|
40
|
+
let kind;
|
|
41
|
+
if (targetId === null) {
|
|
42
|
+
kind = anchor === "home" ? "hold" : "follow";
|
|
43
|
+
}
|
|
44
|
+
else if (targetId === ownerTargetId) {
|
|
45
|
+
kind = "assist";
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
kind = "engage";
|
|
49
|
+
}
|
|
50
|
+
return { kind, anchor, leashTo, leashDistance: record.leash, candidates, targetId };
|
|
51
|
+
}
|
|
52
|
+
function cloneStats(stats) {
|
|
53
|
+
const out = {};
|
|
54
|
+
for (const [statId, value] of Object.entries(stats))
|
|
55
|
+
out[statId] = { ...value };
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
function cloneRecord(record) {
|
|
59
|
+
return {
|
|
60
|
+
id: record.id,
|
|
61
|
+
ownerId: record.ownerId,
|
|
62
|
+
sourceId: record.sourceId,
|
|
63
|
+
command: record.command,
|
|
64
|
+
home: record.home === null ? null : [record.home[0], record.home[1], record.home[2]],
|
|
65
|
+
leash: record.leash,
|
|
66
|
+
level: record.level,
|
|
67
|
+
unspentPoints: record.unspentPoints,
|
|
68
|
+
stats: cloneStats(record.stats),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Build a {@link CompanionRoster}. Composes `scene/roster` ownership (via `ownerId`/`sourceId`),
|
|
73
|
+
* `scene/entityStats` for the per-companion stat pool, and {@link resolveCompanionIntent} for
|
|
74
|
+
* `ai/mobBrain`-shaped behavior — turning a captured creature into a loyal, levelling ally.
|
|
75
|
+
*
|
|
76
|
+
* @capability companion-roster manage tamed companions — allegiance, commands, per-companion stats/leveling, and mobBrain-shaped intent
|
|
77
|
+
*/
|
|
78
|
+
export function createCompanionRoster(config = {}) {
|
|
79
|
+
const records = new Map();
|
|
80
|
+
const pointsPerLevel = config.pointsPerLevel ?? (() => 1);
|
|
81
|
+
const maxLevel = config.maxLevel ?? Number.POSITIVE_INFINITY;
|
|
82
|
+
const startLevel = config.startLevel ?? 1;
|
|
83
|
+
const defaultLeash = config.leash ?? 12;
|
|
84
|
+
let counter = 0;
|
|
85
|
+
const write = (record) => {
|
|
86
|
+
records.set(record.id, record);
|
|
87
|
+
return record;
|
|
88
|
+
};
|
|
89
|
+
const patch = (companionId, fn) => {
|
|
90
|
+
const record = records.get(companionId);
|
|
91
|
+
if (record === undefined)
|
|
92
|
+
return null;
|
|
93
|
+
return write(fn(record));
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
adopt(ownerId, options = {}) {
|
|
97
|
+
counter += 1;
|
|
98
|
+
const id = options.id ?? `companion_${counter}`;
|
|
99
|
+
const seed = options.stats ?? config.stats ?? {};
|
|
100
|
+
const record = {
|
|
101
|
+
id,
|
|
102
|
+
ownerId,
|
|
103
|
+
sourceId: options.sourceId ?? null,
|
|
104
|
+
command: options.command ?? "follow",
|
|
105
|
+
home: options.home ?? null,
|
|
106
|
+
leash: options.leash ?? defaultLeash,
|
|
107
|
+
level: options.level ?? startLevel,
|
|
108
|
+
unspentPoints: 0,
|
|
109
|
+
stats: seedStatValues(seed),
|
|
110
|
+
};
|
|
111
|
+
return write(record);
|
|
112
|
+
},
|
|
113
|
+
release(companionId) {
|
|
114
|
+
return records.delete(companionId);
|
|
115
|
+
},
|
|
116
|
+
get(companionId) {
|
|
117
|
+
return records.get(companionId) ?? null;
|
|
118
|
+
},
|
|
119
|
+
ownerOf(companionId) {
|
|
120
|
+
return records.get(companionId)?.ownerId ?? null;
|
|
121
|
+
},
|
|
122
|
+
list(ownerId) {
|
|
123
|
+
const out = [];
|
|
124
|
+
for (const record of records.values())
|
|
125
|
+
if (record.ownerId === ownerId)
|
|
126
|
+
out.push(record);
|
|
127
|
+
return out;
|
|
128
|
+
},
|
|
129
|
+
command(companionId, command) {
|
|
130
|
+
return patch(companionId, (record) => ({ ...record, command }));
|
|
131
|
+
},
|
|
132
|
+
setHome(companionId, home) {
|
|
133
|
+
return patch(companionId, (record) => ({
|
|
134
|
+
...record,
|
|
135
|
+
home: home === null ? null : [home[0], home[1], home[2]],
|
|
136
|
+
}));
|
|
137
|
+
},
|
|
138
|
+
setLeash(companionId, leash) {
|
|
139
|
+
return patch(companionId, (record) => ({ ...record, leash }));
|
|
140
|
+
},
|
|
141
|
+
levelUp(companionId, levels = 1) {
|
|
142
|
+
return patch(companionId, (record) => {
|
|
143
|
+
let level = record.level;
|
|
144
|
+
let points = record.unspentPoints;
|
|
145
|
+
for (let i = 0; i < levels && level < maxLevel; i += 1) {
|
|
146
|
+
level += 1;
|
|
147
|
+
points += pointsPerLevel(level);
|
|
148
|
+
}
|
|
149
|
+
return { ...record, level, unspentPoints: points };
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
spend(companionId, statId) {
|
|
153
|
+
const record = records.get(companionId);
|
|
154
|
+
if (record === undefined)
|
|
155
|
+
return { status: "rejected", reason: `unknown companion "${companionId}"` };
|
|
156
|
+
if (record.unspentPoints <= 0)
|
|
157
|
+
return { status: "rejected", reason: "no unspent points" };
|
|
158
|
+
const upgrade = config.upgrades?.[statId];
|
|
159
|
+
if (upgrade === undefined)
|
|
160
|
+
return { status: "rejected", reason: `stat "${statId}" is not upgradable` };
|
|
161
|
+
const existing = record.stats[statId];
|
|
162
|
+
if (existing === undefined)
|
|
163
|
+
return { status: "rejected", reason: `unknown stat "${statId}"` };
|
|
164
|
+
const nextMax = existing.max + upgrade.increment;
|
|
165
|
+
if (upgrade.maxCap !== undefined && nextMax > upgrade.maxCap) {
|
|
166
|
+
return { status: "rejected", reason: `stat "${statId}" is at its cap` };
|
|
167
|
+
}
|
|
168
|
+
const stats = setStatValue(record.stats, statId, {
|
|
169
|
+
max: nextMax,
|
|
170
|
+
current: existing.current + upgrade.increment,
|
|
171
|
+
});
|
|
172
|
+
const updated = write({ ...record, unspentPoints: record.unspentPoints - 1, stats });
|
|
173
|
+
return { status: "ok", record: updated, stat: updated.stats[statId] };
|
|
174
|
+
},
|
|
175
|
+
resolveIntent(companionId, context) {
|
|
176
|
+
const record = records.get(companionId);
|
|
177
|
+
if (record === undefined)
|
|
178
|
+
return null;
|
|
179
|
+
return resolveCompanionIntent(record, context);
|
|
180
|
+
},
|
|
181
|
+
snapshot() {
|
|
182
|
+
const out = {};
|
|
183
|
+
for (const [id, record] of records)
|
|
184
|
+
out[id] = cloneRecord(record);
|
|
185
|
+
return out;
|
|
186
|
+
},
|
|
187
|
+
hydrate(data) {
|
|
188
|
+
records.clear();
|
|
189
|
+
for (const [id, record] of Object.entries(data))
|
|
190
|
+
records.set(id, cloneRecord(record));
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
min: number;
|
|
1
|
+
import { type StatPool, type StatPoolAccess, type StatPoolPatch } from "../stats/statPool.js";
|
|
2
|
+
/** Native entity-stat name retained as a compatibility bridge to the portable pool model. */
|
|
3
|
+
export interface StatValue extends StatPool {
|
|
5
4
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
max?: number;
|
|
9
|
-
min?: number;
|
|
5
|
+
/** Native entity-stat patch retained as a compatibility bridge. */
|
|
6
|
+
export interface StatValuePatch extends StatPoolPatch {
|
|
10
7
|
}
|
|
11
8
|
export type StatValueMap = Record<string, StatValue>;
|
|
12
9
|
export type StatCatalog = Record<string, {
|
|
@@ -24,19 +21,29 @@ export type PoolDeltaResult = {
|
|
|
24
21
|
status: "rejected";
|
|
25
22
|
reason: string;
|
|
26
23
|
};
|
|
24
|
+
/** @internal */
|
|
27
25
|
export declare function getStatValue(map: StatValueMap, statId: string): StatValue | null;
|
|
26
|
+
/** @internal */
|
|
28
27
|
export declare function setStatValue(map: StatValueMap, statId: string, patch: StatValuePatch): StatValueMap;
|
|
28
|
+
/** @internal */
|
|
29
29
|
export declare function applyPoolDelta(map: StatValueMap, statId: string, amount: number): PoolDeltaResult;
|
|
30
|
+
/** @internal */
|
|
30
31
|
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}.
|
|
32
|
+
/** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
32
35
|
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.
|
|
36
|
+
/** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
34
39
|
export declare function hydrateEntityStats(store: Map<string, StatValueMap>, data: Record<string, StatValueMap>): void;
|
|
35
|
-
|
|
40
|
+
/** Native entity-stat adapter over the portable {@link StatPoolAccess} contract. */
|
|
41
|
+
export interface EntityStatsApi extends StatPoolAccess {
|
|
36
42
|
get(instanceId: string, statId: string): StatValue | null;
|
|
37
43
|
set(instanceId: string, statId: string, patch: StatValuePatch): boolean;
|
|
38
44
|
delta(instanceId: string, statId: string, amount: number): null | {
|
|
39
45
|
reason: string;
|
|
40
46
|
};
|
|
41
47
|
}
|
|
48
|
+
/** @internal */
|
|
42
49
|
export declare function createEntityStatsApi(resolve: (instanceId: string) => StatValueMap | undefined): EntityStatsApi;
|
|
@@ -1,41 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
1
|
+
import { changeStatPool, createStatPool, patchStatPool, } from "../stats/statPool.js";
|
|
2
|
+
/** @internal */
|
|
4
3
|
export function getStatValue(map, statId) {
|
|
5
4
|
return map[statId] ?? null;
|
|
6
5
|
}
|
|
6
|
+
/** @internal */
|
|
7
7
|
export function setStatValue(map, statId, patch) {
|
|
8
8
|
const existing = map[statId];
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return { ...map, [statId]:
|
|
9
|
+
const next = existing === undefined
|
|
10
|
+
? createStatPool({ max: patch.max ?? 0, min: patch.min, current: patch.current })
|
|
11
|
+
: patchStatPool(existing, patch);
|
|
12
|
+
return { ...map, [statId]: next };
|
|
13
13
|
}
|
|
14
|
+
/** @internal */
|
|
14
15
|
export function applyPoolDelta(map, statId, amount) {
|
|
15
16
|
const existing = map[statId];
|
|
16
17
|
if (existing === undefined) {
|
|
17
18
|
return { status: "rejected", reason: `unknown stat "${statId}"` };
|
|
18
19
|
}
|
|
19
|
-
const
|
|
20
|
-
const stat =
|
|
20
|
+
const change = changeStatPool(existing, amount);
|
|
21
|
+
const stat = change.pool;
|
|
21
22
|
return {
|
|
22
23
|
status: "ok",
|
|
23
24
|
map: { ...map, [statId]: stat },
|
|
24
25
|
stat,
|
|
25
|
-
hitMin:
|
|
26
|
-
hitMax:
|
|
26
|
+
hitMin: change.hitMin,
|
|
27
|
+
hitMax: change.hitMax,
|
|
27
28
|
};
|
|
28
29
|
}
|
|
30
|
+
/** @internal */
|
|
29
31
|
export function seedStatValues(catalogStats) {
|
|
30
32
|
const map = {};
|
|
31
33
|
for (const [statId, declaration] of Object.entries(catalogStats)) {
|
|
32
|
-
|
|
33
|
-
const current = clamp(declaration.current ?? declaration.max, min, declaration.max);
|
|
34
|
-
map[statId] = { current, max: declaration.max, min };
|
|
34
|
+
map[statId] = createStatPool(declaration);
|
|
35
35
|
}
|
|
36
36
|
return map;
|
|
37
37
|
}
|
|
38
|
-
/** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
|
|
38
|
+
/** Deep-copy the per-entity stat maps into a serializable record — the transport counterpart of {@link hydrateEntityStats}.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
39
41
|
export function snapshotEntityStats(store) {
|
|
40
42
|
const out = {};
|
|
41
43
|
for (const [instanceId, map] of store) {
|
|
@@ -46,7 +48,9 @@ export function snapshotEntityStats(store) {
|
|
|
46
48
|
}
|
|
47
49
|
return out;
|
|
48
50
|
}
|
|
49
|
-
/** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
|
|
51
|
+
/** Replace a live stat store with deep copies of a snapshot, clearing entities absent from it.
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
50
54
|
export function hydrateEntityStats(store, data) {
|
|
51
55
|
store.clear();
|
|
52
56
|
for (const [instanceId, map] of Object.entries(data)) {
|
|
@@ -56,6 +60,7 @@ export function hydrateEntityStats(store, data) {
|
|
|
56
60
|
store.set(instanceId, copy);
|
|
57
61
|
}
|
|
58
62
|
}
|
|
63
|
+
/** @internal */
|
|
59
64
|
export function createEntityStatsApi(resolve) {
|
|
60
65
|
return {
|
|
61
66
|
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 };
|