@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
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
const PHYSICS_PRECISION_PRESETS = {
|
|
2
|
+
low: { solverIterations: 2, correctionFactor: 0.15, sleepThresholdSteps: 15, wakeThreshold: 0.75, jointCorrection: 0.35 },
|
|
3
|
+
standard: { solverIterations: 4, correctionFactor: 0.2, sleepThresholdSteps: 30, wakeThreshold: 0.5, jointCorrection: 0.5 },
|
|
4
|
+
high: { solverIterations: 8, correctionFactor: 0.3, sleepThresholdSteps: 45, wakeThreshold: 0.35, jointCorrection: 0.65 },
|
|
5
|
+
};
|
|
1
6
|
export const SHAPE_BOX = 0;
|
|
2
7
|
export const SHAPE_SPHERE = 1;
|
|
3
8
|
export const JOINT_FIXED = 0;
|
|
@@ -90,6 +95,9 @@ export class PhysicsWorld {
|
|
|
90
95
|
jFreeCount = 0;
|
|
91
96
|
jointHigh = 0;
|
|
92
97
|
jointActiveCount = 0;
|
|
98
|
+
// Reused scratch for a joint's two world anchor points [ax,ay,az,bx,by,bz]; filled by anchorWorld
|
|
99
|
+
// so the gather is defined once and no per-call array is allocated on the joint hot path.
|
|
100
|
+
anchorScratch = new Float64Array(6);
|
|
93
101
|
// Removed bodies tombstone (FLAG_DEAD) rather than compact: `id` is the SoA slot itself, handed
|
|
94
102
|
// out to callers and stored raw in joints/game state, so a slot can never move once allocated.
|
|
95
103
|
// `bodyHigh` is the high-water mark of ever-used slots; `bodyFree` recycles dead ones for addBody.
|
|
@@ -119,6 +127,7 @@ export class PhysicsWorld {
|
|
|
119
127
|
stepMs: 0,
|
|
120
128
|
};
|
|
121
129
|
constructor(config) {
|
|
130
|
+
const preset = PHYSICS_PRECISION_PRESETS[config.precision ?? "standard"];
|
|
122
131
|
this.capacity = config.capacity;
|
|
123
132
|
this.bounds = { min: config.bounds.min, max: config.bounds.max };
|
|
124
133
|
this.gravity = config.gravity ?? -20;
|
|
@@ -129,16 +138,16 @@ export class PhysicsWorld {
|
|
|
129
138
|
this.restitutionThreshold = config.restitutionThreshold ?? 1;
|
|
130
139
|
this.friction = config.friction ?? 0.4;
|
|
131
140
|
this.linearDamping = config.linearDamping ?? 0.2;
|
|
132
|
-
this.solverIterations = Math.max(1, config.solverIterations ??
|
|
133
|
-
this.correctionFactor = config.correctionFactor ??
|
|
141
|
+
this.solverIterations = Math.max(1, config.solverIterations ?? preset.solverIterations);
|
|
142
|
+
this.correctionFactor = config.correctionFactor ?? preset.correctionFactor;
|
|
134
143
|
this.slop = config.slop ?? 0.005;
|
|
135
144
|
const sleepV = config.sleepLinearVelocity ?? 0.08;
|
|
136
145
|
const sleepMoveEps = sleepV * this.fixedDt;
|
|
137
146
|
this.sleepMove2 = sleepMoveEps * sleepMoveEps;
|
|
138
|
-
this.sleepSteps = config.sleepThresholdSteps ??
|
|
139
|
-
this.wakeThreshold = config.wakeThreshold ??
|
|
147
|
+
this.sleepSteps = config.sleepThresholdSteps ?? preset.sleepThresholdSteps;
|
|
148
|
+
this.wakeThreshold = config.wakeThreshold ?? preset.wakeThreshold;
|
|
140
149
|
this.jointCapacity = Math.max(0, config.jointCapacity ?? 256);
|
|
141
|
-
this.jointCorrection = config.jointCorrection ??
|
|
150
|
+
this.jointCorrection = config.jointCorrection ?? preset.jointCorrection;
|
|
142
151
|
const cap = config.capacity;
|
|
143
152
|
this.posX = new Float32Array(cap);
|
|
144
153
|
this.posY = new Float32Array(cap);
|
|
@@ -307,18 +316,29 @@ export class PhysicsWorld {
|
|
|
307
316
|
setJointRest(id, restLength) {
|
|
308
317
|
this.jRest[id] = restLength;
|
|
309
318
|
}
|
|
310
|
-
|
|
319
|
+
/**
|
|
320
|
+
* Gather joint `id`'s two world anchor points into {@link anchorScratch} as [ax,ay,az,bx,by,bz]
|
|
321
|
+
* (A's local offset added to body A's centre, or world-origin when A is unset; B likewise, treating
|
|
322
|
+
* `anchorB` as a world point when B is unset). The single definition shared by {@link jointDistance},
|
|
323
|
+
* {@link readJointSegments}, and {@link solveJoints}.
|
|
324
|
+
*/
|
|
325
|
+
anchorWorld(id) {
|
|
326
|
+
const s = this.anchorScratch;
|
|
311
327
|
const bA = this.jBodyA[id];
|
|
312
328
|
const bB = this.jBodyB[id];
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
329
|
+
s[0] = (bA >= 0 ? this.posX[bA] : 0) + this.jAnchorAX[id];
|
|
330
|
+
s[1] = (bA >= 0 ? this.posY[bA] : 0) + this.jAnchorAY[id];
|
|
331
|
+
s[2] = (bA >= 0 ? this.posZ[bA] : 0) + this.jAnchorAZ[id];
|
|
332
|
+
s[3] = bB >= 0 ? this.posX[bB] + this.jAnchorBX[id] : this.jAnchorBX[id];
|
|
333
|
+
s[4] = bB >= 0 ? this.posY[bB] + this.jAnchorBY[id] : this.jAnchorBY[id];
|
|
334
|
+
s[5] = bB >= 0 ? this.posZ[bB] + this.jAnchorBZ[id] : this.jAnchorBZ[id];
|
|
335
|
+
}
|
|
336
|
+
jointDistance(id) {
|
|
337
|
+
this.anchorWorld(id);
|
|
338
|
+
const s = this.anchorScratch;
|
|
339
|
+
const dx = s[3] - s[0];
|
|
340
|
+
const dy = s[4] - s[1];
|
|
341
|
+
const dz = s[5] - s[2];
|
|
322
342
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
323
343
|
}
|
|
324
344
|
/** Write [ax,ay,az,bx,by,bz] world endpoints per active joint into `out`; returns the joint count. */
|
|
@@ -327,15 +347,15 @@ export class PhysicsWorld {
|
|
|
327
347
|
for (let id = 0; id < this.jointHigh; id += 1) {
|
|
328
348
|
if (this.jActive[id] !== 1)
|
|
329
349
|
continue;
|
|
330
|
-
|
|
331
|
-
const
|
|
350
|
+
this.anchorWorld(id);
|
|
351
|
+
const s = this.anchorScratch;
|
|
332
352
|
const o = n * 6;
|
|
333
|
-
out[o] =
|
|
334
|
-
out[o + 1] =
|
|
335
|
-
out[o + 2] =
|
|
336
|
-
out[o + 3] =
|
|
337
|
-
out[o + 4] =
|
|
338
|
-
out[o + 5] =
|
|
353
|
+
out[o] = s[0];
|
|
354
|
+
out[o + 1] = s[1];
|
|
355
|
+
out[o + 2] = s[2];
|
|
356
|
+
out[o + 3] = s[3];
|
|
357
|
+
out[o + 4] = s[4];
|
|
358
|
+
out[o + 5] = s[5];
|
|
339
359
|
n += 1;
|
|
340
360
|
}
|
|
341
361
|
return n;
|
|
@@ -603,6 +623,29 @@ export class PhysicsWorld {
|
|
|
603
623
|
this.velY[i] = this.velY[i] < rt ? 0 : -this.velY[i] * e;
|
|
604
624
|
}
|
|
605
625
|
}
|
|
626
|
+
/**
|
|
627
|
+
* Walk every broadphase cell body `i`'s AABB overlaps, invoking `visit(cell)` once per cell. The
|
|
628
|
+
* cell-range math (six `cellCoord` calls plus the row-major triple loop) lives here so the count
|
|
629
|
+
* and scatter passes of {@link buildGrid} share one definition. `visit` is a caller-hoisted closure
|
|
630
|
+
* (created once per `buildGrid`, not per body) so the hot loop stays allocation-free.
|
|
631
|
+
*/
|
|
632
|
+
forEachBodyCell(i, visit) {
|
|
633
|
+
const nx = this.nx;
|
|
634
|
+
const ny = this.ny;
|
|
635
|
+
const x0 = cellCoord(this.posX[i] - this.halfX[i], this.bounds.min[0], this.cellSize, this.nx);
|
|
636
|
+
const x1 = cellCoord(this.posX[i] + this.halfX[i], this.bounds.min[0], this.cellSize, this.nx);
|
|
637
|
+
const y0 = cellCoord(this.posY[i] - this.halfY[i], this.bounds.min[1], this.cellSize, this.ny);
|
|
638
|
+
const y1 = cellCoord(this.posY[i] + this.halfY[i], this.bounds.min[1], this.cellSize, this.ny);
|
|
639
|
+
const z0 = cellCoord(this.posZ[i] - this.halfZ[i], this.bounds.min[2], this.cellSize, this.nz);
|
|
640
|
+
const z1 = cellCoord(this.posZ[i] + this.halfZ[i], this.bounds.min[2], this.cellSize, this.nz);
|
|
641
|
+
for (let z = z0; z <= z1; z += 1) {
|
|
642
|
+
for (let y = y0; y <= y1; y += 1) {
|
|
643
|
+
const rowBase = (z * ny + y) * nx;
|
|
644
|
+
for (let x = x0; x <= x1; x += 1)
|
|
645
|
+
visit(rowBase + x);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
606
649
|
buildGrid() {
|
|
607
650
|
const n = this.bodyHigh;
|
|
608
651
|
const start = this.cellStart;
|
|
@@ -612,24 +655,13 @@ export class PhysicsWorld {
|
|
|
612
655
|
const i = this.awakeList[a];
|
|
613
656
|
this.bodyCell[i] = this.cellOf(i);
|
|
614
657
|
}
|
|
615
|
-
const
|
|
616
|
-
|
|
658
|
+
const countCell = (cell) => {
|
|
659
|
+
start[cell + 1] += 1;
|
|
660
|
+
};
|
|
617
661
|
for (let i = 0; i < n; i += 1) {
|
|
618
662
|
if ((this.flags[i] & FLAG_DEAD) !== 0)
|
|
619
663
|
continue;
|
|
620
|
-
|
|
621
|
-
const x1 = cellCoord(this.posX[i] + this.halfX[i], this.bounds.min[0], this.cellSize, this.nx);
|
|
622
|
-
const y0 = cellCoord(this.posY[i] - this.halfY[i], this.bounds.min[1], this.cellSize, this.ny);
|
|
623
|
-
const y1 = cellCoord(this.posY[i] + this.halfY[i], this.bounds.min[1], this.cellSize, this.ny);
|
|
624
|
-
const z0 = cellCoord(this.posZ[i] - this.halfZ[i], this.bounds.min[2], this.cellSize, this.nz);
|
|
625
|
-
const z1 = cellCoord(this.posZ[i] + this.halfZ[i], this.bounds.min[2], this.cellSize, this.nz);
|
|
626
|
-
for (let z = z0; z <= z1; z += 1) {
|
|
627
|
-
for (let y = y0; y <= y1; y += 1) {
|
|
628
|
-
const rowBase = (z * ny + y) * nx;
|
|
629
|
-
for (let x = x0; x <= x1; x += 1)
|
|
630
|
-
start[rowBase + x + 1] += 1;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
664
|
+
this.forEachBodyCell(i, countCell);
|
|
633
665
|
}
|
|
634
666
|
for (let c = 0; c < this.numCells; c += 1) {
|
|
635
667
|
start[c + 1] += start[c];
|
|
@@ -639,24 +671,15 @@ export class PhysicsWorld {
|
|
|
639
671
|
if (total > this.sorted.length) {
|
|
640
672
|
this.sorted = new Int32Array(Math.max(total, this.sorted.length * 2));
|
|
641
673
|
}
|
|
674
|
+
let scatterBody = 0;
|
|
675
|
+
const scatterCell = (cell) => {
|
|
676
|
+
this.sorted[this.cursor[cell]++] = scatterBody;
|
|
677
|
+
};
|
|
642
678
|
for (let i = 0; i < n; i += 1) {
|
|
643
679
|
if ((this.flags[i] & FLAG_DEAD) !== 0)
|
|
644
680
|
continue;
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
const y0 = cellCoord(this.posY[i] - this.halfY[i], this.bounds.min[1], this.cellSize, this.ny);
|
|
648
|
-
const y1 = cellCoord(this.posY[i] + this.halfY[i], this.bounds.min[1], this.cellSize, this.ny);
|
|
649
|
-
const z0 = cellCoord(this.posZ[i] - this.halfZ[i], this.bounds.min[2], this.cellSize, this.nz);
|
|
650
|
-
const z1 = cellCoord(this.posZ[i] + this.halfZ[i], this.bounds.min[2], this.cellSize, this.nz);
|
|
651
|
-
for (let z = z0; z <= z1; z += 1) {
|
|
652
|
-
for (let y = y0; y <= y1; y += 1) {
|
|
653
|
-
const rowBase = (z * ny + y) * nx;
|
|
654
|
-
for (let x = x0; x <= x1; x += 1) {
|
|
655
|
-
const c = rowBase + x;
|
|
656
|
-
this.sorted[this.cursor[c]++] = i;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
681
|
+
scatterBody = i;
|
|
682
|
+
this.forEachBodyCell(i, scatterCell);
|
|
660
683
|
}
|
|
661
684
|
}
|
|
662
685
|
cellOf(i) {
|
|
@@ -861,6 +884,39 @@ export class PhysicsWorld {
|
|
|
861
884
|
this.posY[j] += corr * imJ * nY;
|
|
862
885
|
this.posZ[j] += corr * imJ * nZ;
|
|
863
886
|
}
|
|
887
|
+
/**
|
|
888
|
+
* Apply an axial velocity impulse `jn` along unit axis (nX,nY,nZ) to a joint's two bodies: body A
|
|
889
|
+
* recoils (−) and body B advances (+), each scaled by its inverse mass. A world anchor (body index
|
|
890
|
+
* < 0) is skipped. Scalar args only — no allocation on the joint hot path.
|
|
891
|
+
*/
|
|
892
|
+
applyAxialImpulse(bA, bB, imA, imB, jn, nX, nY, nZ) {
|
|
893
|
+
if (bA >= 0) {
|
|
894
|
+
this.velX[bA] -= jn * imA * nX;
|
|
895
|
+
this.velY[bA] -= jn * imA * nY;
|
|
896
|
+
this.velZ[bA] -= jn * imA * nZ;
|
|
897
|
+
}
|
|
898
|
+
if (bB >= 0) {
|
|
899
|
+
this.velX[bB] += jn * imB * nX;
|
|
900
|
+
this.velY[bB] += jn * imB * nY;
|
|
901
|
+
this.velZ[bB] += jn * imB * nZ;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Positional (Baumgarte) twin of {@link applyAxialImpulse}: nudge the joint's two bodies along
|
|
906
|
+
* (nX,nY,nZ) by `corr` — body A advances (+), body B recoils (−), each scaled by its inverse mass.
|
|
907
|
+
*/
|
|
908
|
+
applyAxialCorrection(bA, bB, imA, imB, corr, nX, nY, nZ) {
|
|
909
|
+
if (bA >= 0) {
|
|
910
|
+
this.posX[bA] += corr * imA * nX;
|
|
911
|
+
this.posY[bA] += corr * imA * nY;
|
|
912
|
+
this.posZ[bA] += corr * imA * nZ;
|
|
913
|
+
}
|
|
914
|
+
if (bB >= 0) {
|
|
915
|
+
this.posX[bB] -= corr * imB * nX;
|
|
916
|
+
this.posY[bB] -= corr * imB * nY;
|
|
917
|
+
this.posZ[bB] -= corr * imB * nZ;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
864
920
|
solveJoints(dt) {
|
|
865
921
|
const beta = this.jointCorrection;
|
|
866
922
|
const slop = this.slop;
|
|
@@ -870,15 +926,11 @@ export class PhysicsWorld {
|
|
|
870
926
|
const kind = this.jKind[id];
|
|
871
927
|
const bA = this.jBodyA[id];
|
|
872
928
|
const bB = this.jBodyB[id];
|
|
873
|
-
|
|
874
|
-
const
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
const bz = bB >= 0 ? this.posZ[bB] + this.jAnchorBZ[id] : this.jAnchorBZ[id];
|
|
879
|
-
let dx = bx - ax;
|
|
880
|
-
let dy = by - ay;
|
|
881
|
-
let dz = bz - az;
|
|
929
|
+
this.anchorWorld(id);
|
|
930
|
+
const s = this.anchorScratch;
|
|
931
|
+
let dx = s[3] - s[0];
|
|
932
|
+
let dy = s[4] - s[1];
|
|
933
|
+
let dz = s[5] - s[2];
|
|
882
934
|
const imA = bA >= 0 ? this.invMass[bA] : 0;
|
|
883
935
|
const imB = bB >= 0 ? this.invMass[bB] : 0;
|
|
884
936
|
const imSum = imA + imB;
|
|
@@ -918,27 +970,9 @@ export class PhysicsWorld {
|
|
|
918
970
|
}
|
|
919
971
|
const rvn = rvx * nX + rvy * nY + rvz * nZ;
|
|
920
972
|
const jn = -rvn / imSum;
|
|
921
|
-
|
|
922
|
-
this.velX[bA] -= jn * imA * nX;
|
|
923
|
-
this.velY[bA] -= jn * imA * nY;
|
|
924
|
-
this.velZ[bA] -= jn * imA * nZ;
|
|
925
|
-
}
|
|
926
|
-
if (bB >= 0) {
|
|
927
|
-
this.velX[bB] += jn * imB * nX;
|
|
928
|
-
this.velY[bB] += jn * imB * nY;
|
|
929
|
-
this.velZ[bB] += jn * imB * nZ;
|
|
930
|
-
}
|
|
973
|
+
this.applyAxialImpulse(bA, bB, imA, imB, jn, nX, nY, nZ);
|
|
931
974
|
const corr = (dist * beta) / imSum;
|
|
932
|
-
|
|
933
|
-
this.posX[bA] += corr * imA * nX;
|
|
934
|
-
this.posY[bA] += corr * imA * nY;
|
|
935
|
-
this.posZ[bA] += corr * imA * nZ;
|
|
936
|
-
}
|
|
937
|
-
if (bB >= 0) {
|
|
938
|
-
this.posX[bB] -= corr * imB * nX;
|
|
939
|
-
this.posY[bB] -= corr * imB * nY;
|
|
940
|
-
this.posZ[bB] -= corr * imB * nZ;
|
|
941
|
-
}
|
|
975
|
+
this.applyAxialCorrection(bA, bB, imA, imB, corr, nX, nY, nZ);
|
|
942
976
|
}
|
|
943
977
|
else {
|
|
944
978
|
const rvl = Math.sqrt(rvx * rvx + rvy * rvy + rvz * rvz);
|
|
@@ -947,16 +981,7 @@ export class PhysicsWorld {
|
|
|
947
981
|
const nY = rvy / rvl;
|
|
948
982
|
const nZ = rvz / rvl;
|
|
949
983
|
const jn = -rvl / imSum;
|
|
950
|
-
|
|
951
|
-
this.velX[bA] -= jn * imA * nX;
|
|
952
|
-
this.velY[bA] -= jn * imA * nY;
|
|
953
|
-
this.velZ[bA] -= jn * imA * nZ;
|
|
954
|
-
}
|
|
955
|
-
if (bB >= 0) {
|
|
956
|
-
this.velX[bB] += jn * imB * nX;
|
|
957
|
-
this.velY[bB] += jn * imB * nY;
|
|
958
|
-
this.velZ[bB] += jn * imB * nZ;
|
|
959
|
-
}
|
|
984
|
+
this.applyAxialImpulse(bA, bB, imA, imB, jn, nX, nY, nZ);
|
|
960
985
|
}
|
|
961
986
|
}
|
|
962
987
|
continue;
|
|
@@ -988,16 +1013,7 @@ export class PhysicsWorld {
|
|
|
988
1013
|
jn = maxJ;
|
|
989
1014
|
else if (jn < -maxJ)
|
|
990
1015
|
jn = -maxJ;
|
|
991
|
-
|
|
992
|
-
this.velX[bA] -= jn * imA * nX;
|
|
993
|
-
this.velY[bA] -= jn * imA * nY;
|
|
994
|
-
this.velZ[bA] -= jn * imA * nZ;
|
|
995
|
-
}
|
|
996
|
-
if (bB >= 0) {
|
|
997
|
-
this.velX[bB] += jn * imB * nX;
|
|
998
|
-
this.velY[bB] += jn * imB * nY;
|
|
999
|
-
this.velZ[bB] += jn * imB * nZ;
|
|
1000
|
-
}
|
|
1016
|
+
this.applyAxialImpulse(bA, bB, imA, imB, jn, nX, nY, nZ);
|
|
1001
1017
|
continue;
|
|
1002
1018
|
}
|
|
1003
1019
|
if (kind !== JOINT_FIXED && kind !== JOINT_DISTANCE) {
|
|
@@ -1010,27 +1026,9 @@ export class PhysicsWorld {
|
|
|
1010
1026
|
this.wake(bB);
|
|
1011
1027
|
}
|
|
1012
1028
|
const jn = -rvn / imSum;
|
|
1013
|
-
|
|
1014
|
-
this.velX[bA] -= jn * imA * nX;
|
|
1015
|
-
this.velY[bA] -= jn * imA * nY;
|
|
1016
|
-
this.velZ[bA] -= jn * imA * nZ;
|
|
1017
|
-
}
|
|
1018
|
-
if (bB >= 0) {
|
|
1019
|
-
this.velX[bB] += jn * imB * nX;
|
|
1020
|
-
this.velY[bB] += jn * imB * nY;
|
|
1021
|
-
this.velZ[bB] += jn * imB * nZ;
|
|
1022
|
-
}
|
|
1029
|
+
this.applyAxialImpulse(bA, bB, imA, imB, jn, nX, nY, nZ);
|
|
1023
1030
|
const corr = (c * beta) / imSum;
|
|
1024
|
-
|
|
1025
|
-
this.posX[bA] += corr * imA * nX;
|
|
1026
|
-
this.posY[bA] += corr * imA * nY;
|
|
1027
|
-
this.posZ[bA] += corr * imA * nZ;
|
|
1028
|
-
}
|
|
1029
|
-
if (bB >= 0) {
|
|
1030
|
-
this.posX[bB] -= corr * imB * nX;
|
|
1031
|
-
this.posY[bB] -= corr * imB * nY;
|
|
1032
|
-
this.posZ[bB] -= corr * imB * nZ;
|
|
1033
|
-
}
|
|
1031
|
+
this.applyAxialCorrection(bA, bB, imA, imB, corr, nX, nY, nZ);
|
|
1034
1032
|
}
|
|
1035
1033
|
}
|
|
1036
1034
|
updateSleep() {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** How a radial impulse fades from the blast center to its edge. */
|
|
2
|
+
export type RadialFalloff = "linear" | "quadratic" | "none";
|
|
3
|
+
/** A radial push: the impulse vector plus the 0..1 falloff sampled at the target. */
|
|
4
|
+
export interface RadialImpulse {
|
|
5
|
+
/** Impulse along the first axis (direction × magnitude). */
|
|
6
|
+
x: number;
|
|
7
|
+
/** Impulse along the second axis (direction × magnitude). */
|
|
8
|
+
y: number;
|
|
9
|
+
/** Impulse magnitude = `power` × `falloff`. */
|
|
10
|
+
magnitude: number;
|
|
11
|
+
/** Falloff weight at the target, 1 at the center down to 0 at the radius. */
|
|
12
|
+
falloff: number;
|
|
13
|
+
}
|
|
14
|
+
/** Options for {@link radialImpulse}. */
|
|
15
|
+
export interface RadialImpulseOptions {
|
|
16
|
+
/** Falloff shape. Defaults to `"linear"` (`1 − d/r`). */
|
|
17
|
+
falloff?: RadialFalloff;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Point-source radial impulse pushing a `target` away from a blast `source`: full `power` at the center
|
|
21
|
+
* fading to zero at `radius`. Returns `null` when the target sits at or beyond the radius (unaffected),
|
|
22
|
+
* so callers can early-out. At the exact center the direction is zero. This is the explosion/knockback/
|
|
23
|
+
* shockwave push — every arena game hand-rolled the distance, falloff, and normalize.
|
|
24
|
+
*/
|
|
25
|
+
export declare function radialImpulse(source: readonly [number, number], target: readonly [number, number], radius: number, power: number, options?: RadialImpulseOptions): RadialImpulse | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function falloffAt(distance, radius, shape) {
|
|
2
|
+
const linear = 1 - distance / radius;
|
|
3
|
+
if (shape === "none")
|
|
4
|
+
return 1;
|
|
5
|
+
if (shape === "quadratic")
|
|
6
|
+
return linear * linear;
|
|
7
|
+
return linear;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Point-source radial impulse pushing a `target` away from a blast `source`: full `power` at the center
|
|
11
|
+
* fading to zero at `radius`. Returns `null` when the target sits at or beyond the radius (unaffected),
|
|
12
|
+
* so callers can early-out. At the exact center the direction is zero. This is the explosion/knockback/
|
|
13
|
+
* shockwave push — every arena game hand-rolled the distance, falloff, and normalize.
|
|
14
|
+
*/
|
|
15
|
+
export function radialImpulse(source, target, radius, power, options = {}) {
|
|
16
|
+
if (radius <= 0)
|
|
17
|
+
return null;
|
|
18
|
+
const dx = target[0] - source[0];
|
|
19
|
+
const dy = target[1] - source[1];
|
|
20
|
+
const distance = Math.hypot(dx, dy);
|
|
21
|
+
if (distance >= radius)
|
|
22
|
+
return null;
|
|
23
|
+
const falloff = falloffAt(distance, radius, options.falloff ?? "linear");
|
|
24
|
+
const magnitude = power * falloff;
|
|
25
|
+
const invLen = distance > 1e-6 ? 1 / distance : 0;
|
|
26
|
+
return { x: dx * invLen * magnitude, y: dy * invLen * magnitude, magnitude, falloff };
|
|
27
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type CollisionObstacle } from "../movement/movementModel.js";
|
|
2
|
+
/**
|
|
3
|
+
* A single blocked-move event a car can react to (#1051): crash damage, screen shake, a metal-crunch
|
|
4
|
+
* cue. Reported once, when a move is first vetoed, then consumed by {@link VehicleObstacleClamp.takeImpact}.
|
|
5
|
+
*/
|
|
6
|
+
export interface VehicleImpact {
|
|
7
|
+
/** Speed (world units/s) the car was carrying *into* the obstacle at the moment the move was blocked. */
|
|
8
|
+
closingSpeed: number;
|
|
9
|
+
/** Unit push-back direction — points from the struck surface back toward the car. */
|
|
10
|
+
normal: readonly [number, number];
|
|
11
|
+
/** Index into the obstacle set passed for the blocking tick. */
|
|
12
|
+
obstacleIndex: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A planar move clamp for a kinematic car: feed {@link clampMove} to a vehicle's `clampMove` hook so
|
|
16
|
+
* an attempted XZ displacement slides along world solids instead of driving through them, and read
|
|
17
|
+
* {@link takeImpact} once per tick for the crash it produced.
|
|
18
|
+
*/
|
|
19
|
+
export interface VehicleObstacleClamp {
|
|
20
|
+
/** Resolve an attempted `from`→`to` XZ move to the destination actually allowed (slide-along). */
|
|
21
|
+
clampMove(from: readonly [number, number], to: readonly [number, number]): readonly [number, number];
|
|
22
|
+
/** Impact recorded since last take, consumed on read (null when none). Closing speed is the velocity component into the obstacle at block time, units/s. */
|
|
23
|
+
takeImpact(): VehicleImpact | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build a slide-along move clamp for a kinematic car (#1051). `obstacles` is sampled fresh each tick —
|
|
27
|
+
* the caller hands back the already-filtered set of solids near the car — and `dt` supplies the current
|
|
28
|
+
* tick length so a blocked move's lost displacement converts to a closing speed. `radius` inflates each
|
|
29
|
+
* obstacle footprint by the car's body radius (default {@link DEFAULT_VEHICLE_RADIUS}).
|
|
30
|
+
*
|
|
31
|
+
* The slide itself is delegated to {@link resolveObstacleStep} so cars and pedestrians share one proven
|
|
32
|
+
* axis-separated resolver: a shallow graze keeps its tangential run and only the into-wall component is
|
|
33
|
+
* shed, a head-on zeroes forward progress. When any component is shed the largest such block this tick is
|
|
34
|
+
* kept as a {@link VehicleImpact}; {@link VehicleObstacleClamp.takeImpact} returns and clears it so a hit
|
|
35
|
+
* fires exactly once. The happy path (no solids near) is a zero-allocation passthrough returning `to`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createVehicleObstacleClamp(options: {
|
|
38
|
+
/** Solids near the car this tick (already filtered to the relevant, solid set). */
|
|
39
|
+
obstacles: () => readonly CollisionObstacle[];
|
|
40
|
+
/** Vehicle body radius (units). Default {@link DEFAULT_VEHICLE_RADIUS}. */
|
|
41
|
+
radius?: number;
|
|
42
|
+
/** Current tick dt (seconds) — the divisor turning shed displacement into closing speed. */
|
|
43
|
+
dt: () => number;
|
|
44
|
+
}): VehicleObstacleClamp;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { resolveObstacleStep } from "../movement/movementModel.js";
|
|
2
|
+
/** Matches the unit-box default {@link resolveObstacleStep} applies to obstacles without explicit extents. */
|
|
3
|
+
const DEFAULT_OBSTACLE_HALF_EXTENTS = [0.5, 0.5, 0.5];
|
|
4
|
+
/** Default vehicle body radius (units) inflating obstacle footprints; a compact hatchback-ish disc. */
|
|
5
|
+
const DEFAULT_VEHICLE_RADIUS = 1.4;
|
|
6
|
+
/**
|
|
7
|
+
* Y the car body is pinned to when handing solids to {@link resolveObstacleStep}. That stepper gates
|
|
8
|
+
* each obstacle by a 1.8-tall pedestrian span around `current[1]`; centring every pre-filtered solid
|
|
9
|
+
* on this value makes the gate always admit them, so collision is purely horizontal and the car hits
|
|
10
|
+
* world solids at any ground elevation (bridges, hills) even though the clamp only knows XZ.
|
|
11
|
+
*/
|
|
12
|
+
const CAR_BODY_MID_Y = 0.9;
|
|
13
|
+
/** Below this the returned step is treated as unblocked (float-noise slack), so no phantom impacts fire. */
|
|
14
|
+
const BLOCK_EPSILON = 1e-6;
|
|
15
|
+
/**
|
|
16
|
+
* Build a slide-along move clamp for a kinematic car (#1051). `obstacles` is sampled fresh each tick —
|
|
17
|
+
* the caller hands back the already-filtered set of solids near the car — and `dt` supplies the current
|
|
18
|
+
* tick length so a blocked move's lost displacement converts to a closing speed. `radius` inflates each
|
|
19
|
+
* obstacle footprint by the car's body radius (default {@link DEFAULT_VEHICLE_RADIUS}).
|
|
20
|
+
*
|
|
21
|
+
* The slide itself is delegated to {@link resolveObstacleStep} so cars and pedestrians share one proven
|
|
22
|
+
* axis-separated resolver: a shallow graze keeps its tangential run and only the into-wall component is
|
|
23
|
+
* shed, a head-on zeroes forward progress. When any component is shed the largest such block this tick is
|
|
24
|
+
* kept as a {@link VehicleImpact}; {@link VehicleObstacleClamp.takeImpact} returns and clears it so a hit
|
|
25
|
+
* fires exactly once. The happy path (no solids near) is a zero-allocation passthrough returning `to`.
|
|
26
|
+
*/
|
|
27
|
+
export function createVehicleObstacleClamp(options) {
|
|
28
|
+
const radius = options.radius ?? DEFAULT_VEHICLE_RADIUS;
|
|
29
|
+
// Grow-only scratch of Y-normalised solids, reused across ticks so a sustained crash allocates nothing
|
|
30
|
+
// after warm-up. Per-clamp (closure-local) so concurrent cars never share it.
|
|
31
|
+
const scratch = [];
|
|
32
|
+
let pending = null;
|
|
33
|
+
function vehicleView(source) {
|
|
34
|
+
const n = source.length;
|
|
35
|
+
for (let i = 0; i < n; i += 1) {
|
|
36
|
+
let entry = scratch[i];
|
|
37
|
+
if (entry === undefined) {
|
|
38
|
+
entry = { position: [0, 0, 0] };
|
|
39
|
+
scratch[i] = entry;
|
|
40
|
+
}
|
|
41
|
+
const from = source[i];
|
|
42
|
+
entry.position[0] = from.position[0];
|
|
43
|
+
entry.position[1] = CAR_BODY_MID_Y;
|
|
44
|
+
entry.position[2] = from.position[2];
|
|
45
|
+
entry.halfExtents = from.halfExtents;
|
|
46
|
+
}
|
|
47
|
+
if (scratch.length > n)
|
|
48
|
+
scratch.length = n;
|
|
49
|
+
return scratch;
|
|
50
|
+
}
|
|
51
|
+
/** Obstacle the attempted endpoint penetrates deepest (its inflated footprint), else nearest centre. */
|
|
52
|
+
function blockingIndex(source, tx, tz) {
|
|
53
|
+
let bestIndex = -1;
|
|
54
|
+
let bestDepth = -Number.POSITIVE_INFINITY;
|
|
55
|
+
let fallbackIndex = 0;
|
|
56
|
+
let fallbackDistSq = Number.POSITIVE_INFINITY;
|
|
57
|
+
for (let i = 0; i < source.length; i += 1) {
|
|
58
|
+
const o = source[i];
|
|
59
|
+
const half = o.halfExtents ?? DEFAULT_OBSTACLE_HALF_EXTENTS;
|
|
60
|
+
const ex = half[0] + radius;
|
|
61
|
+
const ez = half[2] + radius;
|
|
62
|
+
const minX = o.position[0] - ex;
|
|
63
|
+
const maxX = o.position[0] + ex;
|
|
64
|
+
const minZ = o.position[2] - ez;
|
|
65
|
+
const maxZ = o.position[2] + ez;
|
|
66
|
+
if (tx > minX && tx < maxX && tz > minZ && tz < maxZ) {
|
|
67
|
+
const depth = Math.min(tx - minX, maxX - tx, tz - minZ, maxZ - tz);
|
|
68
|
+
if (depth > bestDepth) {
|
|
69
|
+
bestDepth = depth;
|
|
70
|
+
bestIndex = i;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const dx = o.position[0] - tx;
|
|
74
|
+
const dz = o.position[2] - tz;
|
|
75
|
+
const distSq = dx * dx + dz * dz;
|
|
76
|
+
if (distSq < fallbackDistSq) {
|
|
77
|
+
fallbackDistSq = distSq;
|
|
78
|
+
fallbackIndex = i;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return bestIndex >= 0 ? bestIndex : fallbackIndex;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
clampMove(from, to) {
|
|
85
|
+
const obstacles = options.obstacles();
|
|
86
|
+
if (obstacles.length === 0)
|
|
87
|
+
return to;
|
|
88
|
+
const attemptedX = to[0] - from[0];
|
|
89
|
+
const attemptedZ = to[1] - from[1];
|
|
90
|
+
const step = resolveObstacleStep([from[0], CAR_BODY_MID_Y, from[1]], attemptedX, attemptedZ, vehicleView(obstacles), radius);
|
|
91
|
+
const blockedX = attemptedX - step.stepX;
|
|
92
|
+
const blockedZ = attemptedZ - step.stepZ;
|
|
93
|
+
if (blockedX === 0 && blockedZ === 0)
|
|
94
|
+
return to;
|
|
95
|
+
const blockedMag = Math.hypot(blockedX, blockedZ);
|
|
96
|
+
if (blockedMag > BLOCK_EPSILON) {
|
|
97
|
+
const dt = options.dt();
|
|
98
|
+
const closingSpeed = dt > 0 ? blockedMag / dt : 0;
|
|
99
|
+
if (pending === null || closingSpeed > pending.closingSpeed) {
|
|
100
|
+
pending = {
|
|
101
|
+
closingSpeed,
|
|
102
|
+
normal: [-blockedX / blockedMag, -blockedZ / blockedMag],
|
|
103
|
+
obstacleIndex: blockingIndex(obstacles, to[0], to[1]),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return [from[0] + step.stepX, from[1] + step.stepZ];
|
|
108
|
+
},
|
|
109
|
+
takeImpact() {
|
|
110
|
+
const impact = pending;
|
|
111
|
+
pending = null;
|
|
112
|
+
return impact;
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { createDecayMeterSet, type DecayMeterSet } from "./survival/decayMeter.js";
|
|
2
|
+
export { createMoodleStack, stackMoodles, type Moodle, type MoodleStack } from "./survival/moodle.js";
|
|
3
|
+
export { createMultiRegionHealth, type MultiRegionHealth } from "./survival/regionHealth.js";
|