@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,75 @@
|
|
|
1
|
+
import { type PathFollowState, type PathProgress, type Waypoint } from "../nav/pathFollow.js";
|
|
2
|
+
import type { GameContext } from "../runtime/gameContext.js";
|
|
3
|
+
/** Whether a behavior instance advances and writes pose (`active`), is temporarily suspended retaining
|
|
4
|
+
* state (`paused`), or is held off until re-enabled (`disabled`). */
|
|
5
|
+
export type BehaviorStatus = "active" | "paused" | "disabled";
|
|
6
|
+
/**
|
|
7
|
+
* Catch-up policy applied when a paused instance resumes. `freeze` (default, deterministic) discards
|
|
8
|
+
* the time spent paused; `advance` silently fast-forwards the instance by the paused duration without
|
|
9
|
+
* emitting intermediate pose writes. Only patrol honors `advance`; wander treats it as `freeze`.
|
|
10
|
+
*/
|
|
11
|
+
export type BehaviorResumePolicy = "freeze" | "advance";
|
|
12
|
+
/** Serializable snapshot of one behavior instance — round-trips exactly through
|
|
13
|
+
* {@link BehaviorControl.serialize}/{@link BehaviorControl.restore}. */
|
|
14
|
+
export type BehaviorSnapshot = {
|
|
15
|
+
readonly kind: "patrol";
|
|
16
|
+
readonly state: PathFollowState;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: "wander";
|
|
19
|
+
readonly origin: Waypoint;
|
|
20
|
+
readonly target: Waypoint | null;
|
|
21
|
+
};
|
|
22
|
+
/** Inspection readout for editor/debug tooling, from {@link BehaviorControl.inspect}/{@link BehaviorControl.list}. */
|
|
23
|
+
export interface BehaviorInspection {
|
|
24
|
+
id: string;
|
|
25
|
+
kind: "patrol" | "wander";
|
|
26
|
+
status: BehaviorStatus;
|
|
27
|
+
reason: string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Per-entity control surface for the behavior runtime — pause/resume/disable/enable an instance,
|
|
31
|
+
* seek it to semantic progress, serialize/restore its state, and inspect it, all keyed by stable
|
|
32
|
+
* entity id without a full-world scan. Obtain it with {@link behaviorControl}.
|
|
33
|
+
*/
|
|
34
|
+
export interface BehaviorControl {
|
|
35
|
+
/** Current status of the instance, or `null` if the entity has no live behavior. */
|
|
36
|
+
status(id: string): BehaviorStatus | null;
|
|
37
|
+
/** Human-readable reason attached to the last pause/disable, or `null`. */
|
|
38
|
+
reason(id: string): string | null;
|
|
39
|
+
/** Suspend advancement and pose writes, retaining state. No-op (`false`) if not active. */
|
|
40
|
+
pause(id: string, reason?: string): boolean;
|
|
41
|
+
/** Resume a paused instance, applying the catch-up `policy` (default `freeze`). */
|
|
42
|
+
resume(id: string, policy?: BehaviorResumePolicy): boolean;
|
|
43
|
+
/** Hold the instance off (no advance, no pose) until {@link enable}. Retains state. */
|
|
44
|
+
disable(id: string, reason?: string): boolean;
|
|
45
|
+
/** Re-activate a disabled instance from its retained state (no catch-up). */
|
|
46
|
+
enable(id: string): boolean;
|
|
47
|
+
/** Jump a patrol instance to semantic {@link PathProgress}. Returns `false` for non-patrol instances. */
|
|
48
|
+
seek(id: string, progress: PathProgress): boolean;
|
|
49
|
+
/** Capture the instance's exact serializable state, or `null` if absent. */
|
|
50
|
+
serialize(id: string): BehaviorSnapshot | null;
|
|
51
|
+
/** Restore an instance from a {@link BehaviorSnapshot} of the matching kind. */
|
|
52
|
+
restore(id: string, snapshot: BehaviorSnapshot): boolean;
|
|
53
|
+
/** Inspect one instance, or `null` if absent. */
|
|
54
|
+
inspect(id: string): BehaviorInspection | null;
|
|
55
|
+
/** Inspect every live instance (bounded by spawned behavior entities). */
|
|
56
|
+
list(): BehaviorInspection[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Advance every spawned entity carrying a `patrol` or `wander` {@link BehaviorDescriptor} one tick — the
|
|
60
|
+
* engine reads the descriptor, keeps the per-entity nav state itself, and poses the entity, so ambient
|
|
61
|
+
* traffic and idle NPC routes are register-once (attach the behavior at spawn) instead of a per-game
|
|
62
|
+
* per-frame `advancePathFollow` + `setPose` loop. Instances that are paused or disabled through
|
|
63
|
+
* {@link behaviorControl} retain their state and are skipped. The shell/host call this each frame; a game never does.
|
|
64
|
+
*
|
|
65
|
+
* @capability behavior-tick auto-advance patrol/wander behaviors on spawned entities, no per-game route loop
|
|
66
|
+
*/
|
|
67
|
+
export declare function advanceBehaviors(ctx: GameContext, dt: number): void;
|
|
68
|
+
/**
|
|
69
|
+
* Obtain the per-context {@link BehaviorControl} surface for suspending, resuming, seeking, serializing,
|
|
70
|
+
* and inspecting behavior instances by entity id — the lifecycle contract games use to hand pose
|
|
71
|
+
* ownership to possession/streaming/staggering code instead of bypassing the behavior runtime.
|
|
72
|
+
*
|
|
73
|
+
* @capability behavior-control pause/disable/resume/seek/inspect behavior instances per entity
|
|
74
|
+
*/
|
|
75
|
+
export declare function behaviorControl(ctx: GameContext): BehaviorControl;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { seededRng } from "../random/rng.js";
|
|
2
|
+
import { advancePathFollow, createPathFollow, pathFollowSeek, } from "../nav/pathFollow.js";
|
|
3
|
+
import { perContext } from "../runtime/perContext.js";
|
|
4
|
+
const DEFAULT_WANDER_SPEED = 1.5;
|
|
5
|
+
const WANDER_ARRIVAL = 0.6;
|
|
6
|
+
function patrolOf(entity) {
|
|
7
|
+
return entity.behaviors.find((b) => b.kind === "patrol") ?? null;
|
|
8
|
+
}
|
|
9
|
+
function wanderOf(entity) {
|
|
10
|
+
return entity.behaviors.find((b) => b.kind === "wander") ?? null;
|
|
11
|
+
}
|
|
12
|
+
const runtimeOf = perContext((ctx) => {
|
|
13
|
+
const nav = new Map();
|
|
14
|
+
const refresh = () => {
|
|
15
|
+
const live = new Set();
|
|
16
|
+
for (const entity of ctx.scene.entity.list()) {
|
|
17
|
+
live.add(entity.id);
|
|
18
|
+
if (nav.has(entity.id))
|
|
19
|
+
continue;
|
|
20
|
+
const patrol = patrolOf(entity);
|
|
21
|
+
if (patrol !== null) {
|
|
22
|
+
const config = { waypoints: patrol.waypoints, speed: patrol.speed, loop: patrol.loop };
|
|
23
|
+
nav.set(entity.id, {
|
|
24
|
+
kind: "patrol",
|
|
25
|
+
config,
|
|
26
|
+
state: patrol.startProgress !== undefined ? pathFollowSeek(config, patrol.startProgress) : createPathFollow(config),
|
|
27
|
+
groundClamp: patrol.groundClamp ?? false,
|
|
28
|
+
status: "active",
|
|
29
|
+
reason: null,
|
|
30
|
+
pausedElapsed: 0,
|
|
31
|
+
});
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const wander = wanderOf(entity);
|
|
35
|
+
if (wander !== null) {
|
|
36
|
+
nav.set(entity.id, {
|
|
37
|
+
kind: "wander",
|
|
38
|
+
radius: wander.radius,
|
|
39
|
+
origin: entity.position,
|
|
40
|
+
target: null,
|
|
41
|
+
roll: seededRng(`wander:${entity.id}`),
|
|
42
|
+
status: "active",
|
|
43
|
+
reason: null,
|
|
44
|
+
pausedElapsed: 0,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const id of nav.keys())
|
|
49
|
+
if (!live.has(id))
|
|
50
|
+
nav.delete(id);
|
|
51
|
+
};
|
|
52
|
+
ctx.scene.entity.subscribeMembership(refresh);
|
|
53
|
+
refresh();
|
|
54
|
+
return { nav };
|
|
55
|
+
});
|
|
56
|
+
function stepWander(ctx, id, nav, dt) {
|
|
57
|
+
const entity = ctx.scene.entity.get(id);
|
|
58
|
+
if (entity === null)
|
|
59
|
+
return;
|
|
60
|
+
const [px, , pz] = entity.position;
|
|
61
|
+
if (nav.target === null || Math.hypot(px - nav.target[0], pz - nav.target[2]) < WANDER_ARRIVAL) {
|
|
62
|
+
const angle = nav.roll() * Math.PI * 2;
|
|
63
|
+
const distance = Math.sqrt(nav.roll()) * nav.radius;
|
|
64
|
+
const tx = nav.origin[0] + Math.cos(angle) * distance;
|
|
65
|
+
const tz = nav.origin[2] + Math.sin(angle) * distance;
|
|
66
|
+
nav.target = [tx, ctx.world.groundHeightAt(tx, tz), tz];
|
|
67
|
+
}
|
|
68
|
+
const speed = entity.movement.walkSpeed ?? DEFAULT_WANDER_SPEED;
|
|
69
|
+
const dx = nav.target[0] - px;
|
|
70
|
+
const dz = nav.target[2] - pz;
|
|
71
|
+
const dist = Math.hypot(dx, dz);
|
|
72
|
+
if (dist < 1e-6)
|
|
73
|
+
return;
|
|
74
|
+
const step = Math.min(dist, speed * dt);
|
|
75
|
+
const nx = px + (dx / dist) * step;
|
|
76
|
+
const nz = pz + (dz / dist) * step;
|
|
77
|
+
ctx.scene.entity.setPose(id, {
|
|
78
|
+
position: [nx, ctx.world.groundHeightAt(nx, nz), nz],
|
|
79
|
+
rotationY: Math.atan2(dx, dz),
|
|
80
|
+
dt,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function posePatrol(ctx, id, nav, dt) {
|
|
84
|
+
const [x, y, z] = nav.state.position;
|
|
85
|
+
ctx.scene.entity.setPose(id, {
|
|
86
|
+
position: nav.groundClamp ? [x, ctx.world.groundHeightAt(x, z), z] : [x, y, z],
|
|
87
|
+
rotationY: nav.state.heading,
|
|
88
|
+
dt,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Advance every spawned entity carrying a `patrol` or `wander` {@link BehaviorDescriptor} one tick — the
|
|
93
|
+
* engine reads the descriptor, keeps the per-entity nav state itself, and poses the entity, so ambient
|
|
94
|
+
* traffic and idle NPC routes are register-once (attach the behavior at spawn) instead of a per-game
|
|
95
|
+
* per-frame `advancePathFollow` + `setPose` loop. Instances that are paused or disabled through
|
|
96
|
+
* {@link behaviorControl} retain their state and are skipped. The shell/host call this each frame; a game never does.
|
|
97
|
+
*
|
|
98
|
+
* @capability behavior-tick auto-advance patrol/wander behaviors on spawned entities, no per-game route loop
|
|
99
|
+
*/
|
|
100
|
+
export function advanceBehaviors(ctx, dt) {
|
|
101
|
+
if (dt <= 0)
|
|
102
|
+
return;
|
|
103
|
+
const { nav } = runtimeOf(ctx);
|
|
104
|
+
if (nav.size === 0)
|
|
105
|
+
return;
|
|
106
|
+
for (const [id, entry] of nav) {
|
|
107
|
+
if (entry.status !== "active") {
|
|
108
|
+
if (entry.status === "paused")
|
|
109
|
+
entry.pausedElapsed += dt;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (entry.kind === "patrol") {
|
|
113
|
+
entry.state = advancePathFollow(entry.config, entry.state, dt);
|
|
114
|
+
posePatrol(ctx, id, entry, dt);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
stepWander(ctx, id, entry, dt);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Obtain the per-context {@link BehaviorControl} surface for suspending, resuming, seeking, serializing,
|
|
123
|
+
* and inspecting behavior instances by entity id — the lifecycle contract games use to hand pose
|
|
124
|
+
* ownership to possession/streaming/staggering code instead of bypassing the behavior runtime.
|
|
125
|
+
*
|
|
126
|
+
* @capability behavior-control pause/disable/resume/seek/inspect behavior instances per entity
|
|
127
|
+
*/
|
|
128
|
+
export function behaviorControl(ctx) {
|
|
129
|
+
const { nav } = runtimeOf(ctx);
|
|
130
|
+
const setStatus = (id, status, reason) => {
|
|
131
|
+
const entry = nav.get(id);
|
|
132
|
+
if (entry === undefined)
|
|
133
|
+
return false;
|
|
134
|
+
entry.status = status;
|
|
135
|
+
entry.reason = reason;
|
|
136
|
+
return true;
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
status: (id) => nav.get(id)?.status ?? null,
|
|
140
|
+
reason: (id) => nav.get(id)?.reason ?? null,
|
|
141
|
+
pause: (id, reason) => {
|
|
142
|
+
const entry = nav.get(id);
|
|
143
|
+
if (entry === undefined || entry.status !== "active")
|
|
144
|
+
return false;
|
|
145
|
+
entry.status = "paused";
|
|
146
|
+
entry.reason = reason ?? null;
|
|
147
|
+
entry.pausedElapsed = 0;
|
|
148
|
+
return true;
|
|
149
|
+
},
|
|
150
|
+
resume: (id, policy = "freeze") => {
|
|
151
|
+
const entry = nav.get(id);
|
|
152
|
+
if (entry === undefined || entry.status !== "paused")
|
|
153
|
+
return false;
|
|
154
|
+
if (policy === "advance" && entry.kind === "patrol" && entry.pausedElapsed > 0) {
|
|
155
|
+
entry.state = advancePathFollow(entry.config, entry.state, entry.pausedElapsed);
|
|
156
|
+
// Emit a single final pose at the caught-up position (no intermediate writes).
|
|
157
|
+
posePatrol(ctx, id, entry, entry.pausedElapsed);
|
|
158
|
+
}
|
|
159
|
+
entry.status = "active";
|
|
160
|
+
entry.reason = null;
|
|
161
|
+
entry.pausedElapsed = 0;
|
|
162
|
+
return true;
|
|
163
|
+
},
|
|
164
|
+
disable: (id, reason) => setStatus(id, "disabled", reason ?? null),
|
|
165
|
+
enable: (id) => {
|
|
166
|
+
const entry = nav.get(id);
|
|
167
|
+
if (entry === undefined || entry.status !== "disabled")
|
|
168
|
+
return false;
|
|
169
|
+
entry.status = "active";
|
|
170
|
+
entry.reason = null;
|
|
171
|
+
entry.pausedElapsed = 0;
|
|
172
|
+
return true;
|
|
173
|
+
},
|
|
174
|
+
seek: (id, progress) => {
|
|
175
|
+
const entry = nav.get(id);
|
|
176
|
+
if (entry === undefined || entry.kind !== "patrol")
|
|
177
|
+
return false;
|
|
178
|
+
entry.state = pathFollowSeek(entry.config, progress);
|
|
179
|
+
return true;
|
|
180
|
+
},
|
|
181
|
+
serialize: (id) => {
|
|
182
|
+
const entry = nav.get(id);
|
|
183
|
+
if (entry === undefined)
|
|
184
|
+
return null;
|
|
185
|
+
if (entry.kind === "patrol")
|
|
186
|
+
return { kind: "patrol", state: { ...entry.state } };
|
|
187
|
+
return { kind: "wander", origin: [...entry.origin], target: entry.target === null ? null : [...entry.target] };
|
|
188
|
+
},
|
|
189
|
+
restore: (id, snapshot) => {
|
|
190
|
+
const entry = nav.get(id);
|
|
191
|
+
if (entry === undefined || entry.kind !== snapshot.kind)
|
|
192
|
+
return false;
|
|
193
|
+
if (entry.kind === "patrol" && snapshot.kind === "patrol") {
|
|
194
|
+
entry.state = { ...snapshot.state };
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
if (entry.kind === "wander" && snapshot.kind === "wander") {
|
|
198
|
+
entry.origin = [...snapshot.origin];
|
|
199
|
+
entry.target = snapshot.target === null ? null : [...snapshot.target];
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
},
|
|
204
|
+
inspect: (id) => {
|
|
205
|
+
const entry = nav.get(id);
|
|
206
|
+
if (entry === undefined)
|
|
207
|
+
return null;
|
|
208
|
+
return { id, kind: entry.kind, status: entry.status, reason: entry.reason };
|
|
209
|
+
},
|
|
210
|
+
list: () => {
|
|
211
|
+
const out = [];
|
|
212
|
+
for (const [id, entry] of nav)
|
|
213
|
+
out.push({ id, kind: entry.kind, status: entry.status, reason: entry.reason });
|
|
214
|
+
return out;
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ProximityPrompt } from "../interaction/proximityPrompt.js";
|
|
2
|
-
import type { Waypoint } from "../nav/pathFollow.js";
|
|
2
|
+
import type { PathProgress, Waypoint } from "../nav/pathFollow.js";
|
|
3
3
|
export interface WanderBehavior {
|
|
4
4
|
kind: "wander";
|
|
5
5
|
radius: number;
|
|
@@ -9,6 +9,16 @@ export interface PatrolBehavior {
|
|
|
9
9
|
waypoints: readonly Waypoint[];
|
|
10
10
|
speed: number;
|
|
11
11
|
loop: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Optional initial progress the follower is seeded at instead of waypoint zero — lets a fleet of
|
|
14
|
+
* route followers start at distributed phases. Round-trips through the behavior lifecycle seek/serialize.
|
|
15
|
+
*/
|
|
16
|
+
startProgress?: PathProgress;
|
|
17
|
+
/**
|
|
18
|
+
* Sample world ground height for the pose Y each tick, so a route authored in the XZ plane rides
|
|
19
|
+
* uneven terrain. Default false (waypoint Y is used verbatim).
|
|
20
|
+
*/
|
|
21
|
+
groundClamp?: boolean;
|
|
12
22
|
}
|
|
13
23
|
export interface PromptableBehavior {
|
|
14
24
|
kind: "promptable";
|
|
@@ -21,10 +31,12 @@ export type BehaviorDescriptor = WanderBehavior | PatrolBehavior | PromptableBeh
|
|
|
21
31
|
export declare function wander({ radius }: {
|
|
22
32
|
radius: number;
|
|
23
33
|
}): WanderBehavior;
|
|
24
|
-
export declare function patrol({ waypoints, speed, loop, }: {
|
|
34
|
+
export declare function patrol({ waypoints, speed, loop, startProgress, groundClamp, }: {
|
|
25
35
|
waypoints: readonly Waypoint[];
|
|
26
36
|
speed: number;
|
|
27
37
|
loop?: boolean;
|
|
38
|
+
startProgress?: PathProgress;
|
|
39
|
+
groundClamp?: boolean;
|
|
28
40
|
}): PatrolBehavior;
|
|
29
41
|
export declare function promptable(prompt: ProximityPrompt): PromptableBehavior;
|
|
30
42
|
export declare function talkable(dialogueId: string): PromptableBehavior;
|
package/dist/scene/behaviors.js
CHANGED
|
@@ -2,8 +2,13 @@ import { command, keybind, proximityPrompt, } from "../interaction/proximityProm
|
|
|
2
2
|
export function wander({ radius }) {
|
|
3
3
|
return { kind: "wander", radius };
|
|
4
4
|
}
|
|
5
|
-
export function patrol({ waypoints, speed, loop = true, }) {
|
|
6
|
-
|
|
5
|
+
export function patrol({ waypoints, speed, loop = true, startProgress, groundClamp, }) {
|
|
6
|
+
const behavior = { kind: "patrol", waypoints, speed, loop };
|
|
7
|
+
if (startProgress !== undefined)
|
|
8
|
+
behavior.startProgress = startProgress;
|
|
9
|
+
if (groundClamp !== undefined)
|
|
10
|
+
behavior.groundClamp = groundClamp;
|
|
11
|
+
return behavior;
|
|
7
12
|
}
|
|
8
13
|
export function promptable(prompt) {
|
|
9
14
|
return { kind: "promptable", prompt };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { EntityRole, EntityUpdatePatch, SpawnPositionInput } from "./entityStore.js";
|
|
2
|
+
/**
|
|
3
|
+
* One sim body's per-tick pose, as the game's simulation computed it — the shape a game already builds
|
|
4
|
+
* to hand to `setPose`, just declared instead of imperatively pushed. `kind` is the entity catalog name
|
|
5
|
+
* used only the first time `id` is seen (a respawn/despawn never re-reads it).
|
|
6
|
+
*/
|
|
7
|
+
export interface BodySnapshot {
|
|
8
|
+
id: string;
|
|
9
|
+
kind: string;
|
|
10
|
+
position: SpawnPositionInput;
|
|
11
|
+
rotationY?: number;
|
|
12
|
+
rotationX?: number;
|
|
13
|
+
rotationZ?: number;
|
|
14
|
+
role?: EntityRole;
|
|
15
|
+
meta?: unknown;
|
|
16
|
+
}
|
|
17
|
+
/** The options a {@link BodyBindDeps.spawn} call receives for an id seen for the first time. */
|
|
18
|
+
export interface BodyBindSpawnInput {
|
|
19
|
+
id: string;
|
|
20
|
+
position: SpawnPositionInput;
|
|
21
|
+
rotationY?: number;
|
|
22
|
+
rotationX?: number;
|
|
23
|
+
rotationZ?: number;
|
|
24
|
+
role?: EntityRole;
|
|
25
|
+
meta?: unknown;
|
|
26
|
+
}
|
|
27
|
+
/** The pose a {@link BodyBindDeps.setPose} call receives for an id already bound. */
|
|
28
|
+
export interface BodyBindPose {
|
|
29
|
+
position: SpawnPositionInput;
|
|
30
|
+
rotationY?: number;
|
|
31
|
+
rotationX?: number;
|
|
32
|
+
rotationZ?: number;
|
|
33
|
+
dt?: number;
|
|
34
|
+
}
|
|
35
|
+
/** Structural entity-store seam a {@link BodyBind} mirrors onto — satisfied by `ctx.scene.entity` itself. */
|
|
36
|
+
export interface BodyBindDeps {
|
|
37
|
+
has(id: string): boolean;
|
|
38
|
+
spawn(kind: string, options: BodyBindSpawnInput): string;
|
|
39
|
+
despawn(id: string): boolean;
|
|
40
|
+
setPose(id: string, pose: BodyBindPose): boolean;
|
|
41
|
+
update(id: string, patch: EntityUpdatePatch): boolean;
|
|
42
|
+
}
|
|
43
|
+
/** The lazily-keyed handle `ctx.scene.entity.bind(key)` returns. */
|
|
44
|
+
export interface BodyBind {
|
|
45
|
+
/**
|
|
46
|
+
* Mirror this tick's `bodies` onto scene entities: spawns an id seen for the first time (catalog
|
|
47
|
+
* `kind` from its snapshot), poses one already bound, despawns one this bind previously spawned that
|
|
48
|
+
* is now absent from `bodies`. `dt` (when given) derives `velocity` the same as a direct `setPose`.
|
|
49
|
+
*/
|
|
50
|
+
sync(bodies: Iterable<BodySnapshot>, dt?: number): void;
|
|
51
|
+
/** Ids this bind currently considers itself responsible for (spawned by, and not yet despawned by, `sync`). */
|
|
52
|
+
boundIds(): ReadonlySet<string>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
|
|
56
|
+
* despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
|
|
57
|
+
*
|
|
58
|
+
* @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
|
|
59
|
+
*/
|
|
60
|
+
export declare function createBodyBind(deps: BodyBindDeps): BodyBind;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirror a sim's body snapshots onto scene entities each tick — spawn on first sight, pose while bound,
|
|
3
|
+
* despawn on drop — replacing a per-body `setPose` loop plus its `despawn`/`spawn` respawn dance.
|
|
4
|
+
*
|
|
5
|
+
* @capability body-bind mirror sim-body snapshots onto scene entities each tick, no per-body setPose
|
|
6
|
+
*/
|
|
7
|
+
export function createBodyBind(deps) {
|
|
8
|
+
const bound = new Set();
|
|
9
|
+
return {
|
|
10
|
+
sync(bodies, dt) {
|
|
11
|
+
const seen = new Set();
|
|
12
|
+
for (const body of bodies) {
|
|
13
|
+
seen.add(body.id);
|
|
14
|
+
const alreadyBound = bound.has(body.id);
|
|
15
|
+
if (!alreadyBound && !deps.has(body.id)) {
|
|
16
|
+
deps.spawn(body.kind, {
|
|
17
|
+
id: body.id,
|
|
18
|
+
position: body.position,
|
|
19
|
+
rotationY: body.rotationY,
|
|
20
|
+
rotationX: body.rotationX,
|
|
21
|
+
rotationZ: body.rotationZ,
|
|
22
|
+
role: body.role,
|
|
23
|
+
meta: body.meta,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
deps.setPose(body.id, {
|
|
28
|
+
position: body.position,
|
|
29
|
+
rotationY: body.rotationY,
|
|
30
|
+
rotationX: body.rotationX,
|
|
31
|
+
rotationZ: body.rotationZ,
|
|
32
|
+
...(dt === undefined ? {} : { dt }),
|
|
33
|
+
});
|
|
34
|
+
if (body.role !== undefined || body.meta !== undefined) {
|
|
35
|
+
deps.update(body.id, { role: body.role, meta: body.meta });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
bound.add(body.id);
|
|
39
|
+
}
|
|
40
|
+
for (const id of bound) {
|
|
41
|
+
if (seen.has(id))
|
|
42
|
+
continue;
|
|
43
|
+
deps.despawn(id);
|
|
44
|
+
bound.delete(id);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
boundIds() {
|
|
48
|
+
return bound;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ParamSchema } from "./sceneKinds.js";
|
|
2
|
+
/** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
|
|
3
|
+
export declare const SCATTER_SCHEMA: ParamSchema;
|
|
4
|
+
/** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
|
|
5
|
+
export declare function registerBuiltinSceneKinds(): void;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers the engine's built-in *environment* scene kinds against the {@link registerSceneKind}
|
|
3
|
+
* seam: `scatter` (the proof adopter — its inspector, `+ Add` entry, and parse now come from the
|
|
4
|
+
* registry), `water` (a reusable parametric water surface), `grass_field` (GPU vertex-wind grass), and
|
|
5
|
+
* `soil` (crack/moss ground-variation patch), and `pole_line` (poles + sagging cables along a path).
|
|
6
|
+
* These are genre-agnostic engine primitives, like terrain. Domain studios (bookcases, …) are NOT
|
|
7
|
+
* built in — they register themselves from example/game code via the same public seam, needing zero
|
|
8
|
+
* engine edits (see `examples/studios`). Call
|
|
9
|
+
* {@link registerBuiltinSceneKinds} once at startup (idempotent).
|
|
10
|
+
*/
|
|
11
|
+
import { SCATTER_PATH_KIND } from "../world/scatterRegion.js";
|
|
12
|
+
import { registerWaterKind } from "../world/waterKind.js";
|
|
13
|
+
import { registerGrassKind } from "../world/grassKind.js";
|
|
14
|
+
import { registerSoilKind } from "../world/soilKind.js";
|
|
15
|
+
import { registerPoleLineKind } from "../world/poleLineKind.js";
|
|
16
|
+
import { registerBuildingGenerator } from "../world/buildingGenerator.js";
|
|
17
|
+
import { registerCityKind } from "../world/cityKind.js";
|
|
18
|
+
import { registerSceneKind } from "./sceneKinds.js";
|
|
19
|
+
/** The scatter/foliage region schema — the fields the inspector exposed as hand-written `ScatterFields`. */
|
|
20
|
+
export const SCATTER_SCHEMA = {
|
|
21
|
+
fields: [
|
|
22
|
+
{ type: "range", key: "density", label: "density", min: 0, max: 2, step: 0.01, default: 0.15, unit: "/m²" },
|
|
23
|
+
{ type: "number", key: "minSpacing", label: "spacing", step: 0.25, default: 1.5, min: 0 },
|
|
24
|
+
{ type: "number", key: "minScale", label: "min scale", step: 0.05, default: 0.8, min: 0 },
|
|
25
|
+
{ type: "number", key: "maxScale", label: "max scale", step: 0.05, default: 1.3, min: 0 },
|
|
26
|
+
{ type: "number", key: "maxSlope", label: "max slope", step: 0.05, default: 0, min: 0 },
|
|
27
|
+
{ type: "number", key: "edgeFalloff", label: "edge fade", step: 0.5, default: 0, min: 0 },
|
|
28
|
+
{ type: "bool", key: "alignToNormal", label: "align to slope", default: false },
|
|
29
|
+
{ type: "bool", key: "autoAvoid", label: "auto-avoid gameplay spots", default: true },
|
|
30
|
+
{ type: "weightedList", key: "palette", label: "species (weighted)", itemLabel: "grass / tree id", default: [{ item: "grass", weight: 1 }] },
|
|
31
|
+
{ type: "seed", key: "seed", label: "seed", default: "" },
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
let registered = false;
|
|
35
|
+
/** Idempotently registers the engine's built-in environment scene kinds + generators. @internal */
|
|
36
|
+
export function registerBuiltinSceneKinds() {
|
|
37
|
+
if (registered)
|
|
38
|
+
return;
|
|
39
|
+
registered = true;
|
|
40
|
+
registerSceneKind({
|
|
41
|
+
kind: SCATTER_PATH_KIND,
|
|
42
|
+
target: "path",
|
|
43
|
+
label: "Foliage / scatter",
|
|
44
|
+
pathShape: "area",
|
|
45
|
+
addCategory: "Studios",
|
|
46
|
+
accent: "#34d399",
|
|
47
|
+
schema: SCATTER_SCHEMA,
|
|
48
|
+
note: (object, params) => {
|
|
49
|
+
const points = object.points ?? [];
|
|
50
|
+
if (points.length < 3)
|
|
51
|
+
return "Draw at least 3 points to close the region.";
|
|
52
|
+
let area = 0;
|
|
53
|
+
for (let i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
|
|
54
|
+
area += points[j].x * points[i].z - points[i].x * points[j].z;
|
|
55
|
+
}
|
|
56
|
+
area = Math.abs(area) / 2;
|
|
57
|
+
const density = typeof params["density"] === "number" ? params["density"] : 0;
|
|
58
|
+
return `≈ ${Math.floor(area * density).toLocaleString()} placements over ${Math.round(area).toLocaleString()} m²`;
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
registerWaterKind();
|
|
62
|
+
registerGrassKind();
|
|
63
|
+
registerSoilKind();
|
|
64
|
+
registerCityKind();
|
|
65
|
+
registerPoleLineKind();
|
|
66
|
+
registerBuildingGenerator();
|
|
67
|
+
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import type { ModelDims } from "./assetCatalog.js";
|
|
2
|
+
import { type CollisionMeshData, type PreparedCollisionMesh } from "./collisionMesh.js";
|
|
1
3
|
import type { EntityPosition } from "./entityStore.js";
|
|
2
4
|
export type ColliderPurpose = "physical" | "damage";
|
|
5
|
+
/**
|
|
6
|
+
* Collision geometry in entity-local space. `sphere` and `aabb` are analytic; `mesh` carries a
|
|
7
|
+
* prepared triangle mesh so opted-in concave models raycast their real surface while bounds and
|
|
8
|
+
* broadphase keep reading the conservative `halfExtents`.
|
|
9
|
+
* @capability mesh-hitboxes shots pass through holes in concave models — opted-in catalog assets raycast their actual triangles instead of the fitted box.
|
|
10
|
+
* @capability mesh-movement the walking player slides against a mesh collider's compound `boxes` — a capsule walks THROUGH an opted-in archway opening and is stopped by its pillars/lintel instead of one outer box.
|
|
11
|
+
*/
|
|
3
12
|
export type ColliderShape = {
|
|
4
13
|
kind: "sphere";
|
|
5
14
|
radius: number;
|
|
@@ -8,6 +17,27 @@ export type ColliderShape = {
|
|
|
8
17
|
kind: "aabb";
|
|
9
18
|
halfExtents: EntityPosition;
|
|
10
19
|
offset?: EntityPosition;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "mesh";
|
|
22
|
+
/** Prepared triangle mesh in model space — engine-derived from an opted-in catalog asset, never hand-authored. */
|
|
23
|
+
mesh: PreparedCollisionMesh;
|
|
24
|
+
/** Uniform model→entity-local scale (same composition as the fitted box). */
|
|
25
|
+
meshScale: number;
|
|
26
|
+
/** Entity-local translation applied after `meshScale`. */
|
|
27
|
+
meshTranslate: EntityPosition;
|
|
28
|
+
/** Conservative entity-local AABB of the placed mesh — bounds/broadphase read this exactly like an `aabb`. */
|
|
29
|
+
halfExtents: EntityPosition;
|
|
30
|
+
/**
|
|
31
|
+
* Optional compact entity-local solid decomposition (from the model's `collisionMesh.boxes`, scaled
|
|
32
|
+
* and translated onto the placement exactly like `mesh`). Movement obstruction slides against these
|
|
33
|
+
* sub-boxes so a capsule walks THROUGH a concave opening; raycasts still use `mesh`. Absent when the
|
|
34
|
+
* model shipped no `boxes`.
|
|
35
|
+
*/
|
|
36
|
+
boxes?: readonly {
|
|
37
|
+
min: EntityPosition;
|
|
38
|
+
max: EntityPosition;
|
|
39
|
+
}[];
|
|
40
|
+
offset?: EntityPosition;
|
|
11
41
|
};
|
|
12
42
|
export interface ColliderDef {
|
|
13
43
|
name: string;
|
|
@@ -37,13 +67,53 @@ export declare const DEFAULT_OBJECT_HALF_EXTENTS: EntityPosition;
|
|
|
37
67
|
export declare const DEFAULT_ENTITY_BODY_HALF_EXTENTS: EntityPosition;
|
|
38
68
|
/** Entity-local center of the default body hitbox (half its height above the feet). */
|
|
39
69
|
export declare const DEFAULT_ENTITY_BODY_OFFSET: EntityPosition;
|
|
70
|
+
/** @internal */
|
|
40
71
|
export declare function defaultEntityColliders(): EntityColliderSet;
|
|
72
|
+
/** Humanoid damage box uniformly scaled to match a visually scaled mesh, kept grounded (offset stays half its height). At scale 1 this equals `defaultEntityColliders()`.
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export declare function scaledEntityColliders(scale: number): EntityColliderSet;
|
|
76
|
+
/** @internal */
|
|
41
77
|
export declare function defaultObjectColliders(halfExtents?: EntityPosition): EntityColliderSet;
|
|
42
|
-
/** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
|
|
78
|
+
/** Blocking physical body derived from an object's rendered scale: a grounded box spanning the visual (base at y=0, matching the shell's fallback mesh).
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
43
81
|
export declare function scaledObjectColliders(scale: readonly [number, number, number]): EntityColliderSet;
|
|
82
|
+
/**
|
|
83
|
+
* The render-config subset collider fitting reads — structurally satisfied by a resolved `ModelConfig`,
|
|
84
|
+
* so the shell can hand its render config straight to the fitting math without a conversion step.
|
|
85
|
+
*/
|
|
86
|
+
export interface ModelBodySource {
|
|
87
|
+
/** Measured model-space bounds from the asset index; fitting requires `dims` with `maxY`. */
|
|
88
|
+
dims?: ModelDims;
|
|
89
|
+
/** Uniform render scale. Default `1`. */
|
|
90
|
+
scale?: number;
|
|
91
|
+
/** Normalize-to-height in world units — fitting composes it exactly like the renderer (`targetHeight / measured height`, multiplied by `scale`). */
|
|
92
|
+
targetHeight?: number;
|
|
93
|
+
/** Vertical render offset added to the placement Y. Default `0`. */
|
|
94
|
+
y?: number;
|
|
95
|
+
/** Placement registration. `"center"` (default) centers the footprint and grounds `minY` on the placement point; `"origin"` renders at the raw model origin. */
|
|
96
|
+
anchor?: "center" | "origin";
|
|
97
|
+
/** Opt-in triangle collision mesh extracted at asset reindex; when present, fitting emits a mesh-accurate shape (rays pass through holes in concave models) instead of the fitted box. */
|
|
98
|
+
collisionMesh?: CollisionMeshData;
|
|
99
|
+
}
|
|
100
|
+
/** Damage hitbox fitted to the rendered model's measured bounds — the model-aware replacement for the
|
|
101
|
+
* fixed humanoid default. `null` when the model is unmeasured, keeping the caller's existing fallback.
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
export declare function fittedEntityColliders(model: ModelBodySource): EntityColliderSet | null;
|
|
105
|
+
/** Blocking physical body fitted to the rendered model's measured bounds — the model-aware replacement
|
|
106
|
+
* for the unit-cube-times-scale guess. `null` when the model is unmeasured.
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
export declare function fittedObjectColliders(model: ModelBodySource): EntityColliderSet | null;
|
|
110
|
+
/** @internal */
|
|
44
111
|
export declare function resolveColliders(set: EntityColliderSet | null | undefined): ResolvedCollider[];
|
|
112
|
+
/** @internal */
|
|
45
113
|
export declare function worldOffset(local: EntityPosition | undefined, position: EntityPosition, rotationY: number): EntityPosition;
|
|
114
|
+
/** @internal */
|
|
46
115
|
export declare function colliderWorldCenter(collider: ResolvedCollider, position: EntityPosition, rotationY: number): EntityPosition;
|
|
116
|
+
/** @internal */
|
|
47
117
|
export declare function colliderBounds(collider: ResolvedCollider, position: EntityPosition, rotationY: number): {
|
|
48
118
|
min: EntityPosition;
|
|
49
119
|
max: EntityPosition;
|