@jgengine/core 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -2
- package/LICENSE +203 -661
- package/README.md +1 -1
- package/dist/ai/crowd.d.ts +55 -0
- package/dist/ai/crowd.js +114 -0
- package/dist/ai/flock.d.ts +5 -2
- package/dist/ai/flock.js +5 -2
- package/dist/ai/groupAssist.d.ts +1 -0
- package/dist/ai/groupAssist.js +1 -0
- package/dist/ai/heatSystem.d.ts +76 -0
- package/dist/ai/heatSystem.js +97 -0
- package/dist/ai/interestScheduler.d.ts +107 -0
- package/dist/ai/interestScheduler.js +118 -0
- package/dist/ai/jobBoard.d.ts +1 -0
- package/dist/ai/jobBoard.js +1 -0
- package/dist/ai/laneSelect.d.ts +5 -2
- package/dist/ai/laneSelect.js +5 -2
- package/dist/ai/mobBrain.d.ts +1 -0
- package/dist/ai/mobBrain.js +1 -0
- package/dist/ai/spawnDirector.d.ts +7 -2
- package/dist/ai/spawnDirector.js +18 -15
- package/dist/ai/spawnPoint.d.ts +3 -1
- package/dist/ai/spawnPoint.js +3 -1
- package/dist/ai/targetAcquisition.d.ts +84 -0
- package/dist/ai/targetAcquisition.js +92 -0
- package/dist/anim/easing.d.ts +19 -0
- package/dist/anim/easing.js +19 -0
- package/dist/anim/oscillator.d.ts +12 -0
- package/dist/anim/oscillator.js +25 -0
- package/dist/area/areaEffectField.d.ts +127 -0
- package/dist/area/areaEffectField.js +175 -0
- package/dist/area/stackPolicy.d.ts +47 -0
- package/dist/area/stackPolicy.js +99 -0
- package/dist/authoring.d.ts +1 -0
- package/dist/authoring.js +1 -0
- package/dist/board/laneBoard.d.ts +13 -0
- package/dist/board/laneBoard.js +13 -0
- package/dist/board/timelineBoard.d.ts +10 -0
- package/dist/board/timelineBoard.js +10 -0
- package/dist/combat/abilityKit.d.ts +18 -0
- package/dist/combat/abilityKit.js +24 -9
- package/dist/combat/animationState.d.ts +5 -0
- package/dist/combat/animationState.js +5 -0
- package/dist/combat/breakMeters.d.ts +10 -0
- package/dist/combat/breakMeters.js +10 -0
- package/dist/combat/castRunner.d.ts +5 -0
- package/dist/combat/castRunner.js +5 -0
- package/dist/combat/comboPoints.d.ts +5 -0
- package/dist/combat/comboPoints.js +5 -0
- package/dist/combat/comboString.d.ts +5 -0
- package/dist/combat/comboString.js +5 -0
- package/dist/combat/damageInterceptors.d.ts +192 -0
- package/dist/combat/damageInterceptors.js +251 -0
- package/dist/combat/damageMatchup.d.ts +68 -0
- package/dist/combat/damageMatchup.js +42 -0
- package/dist/combat/damageResolution.d.ts +63 -0
- package/dist/combat/damageResolution.js +50 -0
- package/dist/combat/death.d.ts +7 -1
- package/dist/combat/death.js +5 -0
- package/dist/combat/deathReason.d.ts +14 -0
- package/dist/combat/deathReason.js +1 -0
- package/dist/combat/defensiveWindow.d.ts +5 -0
- package/dist/combat/defensiveWindow.js +5 -0
- package/dist/combat/dotField.d.ts +5 -1
- package/dist/combat/dotField.js +5 -1
- package/dist/combat/downed.d.ts +5 -0
- package/dist/combat/downed.js +5 -0
- package/dist/combat/effects.d.ts +5 -0
- package/dist/combat/effects.js +5 -0
- package/dist/combat/encounterSequence.d.ts +258 -0
- package/dist/combat/encounterSequence.js +426 -0
- package/dist/combat/hitReaction.d.ts +57 -1
- package/dist/combat/hitReaction.js +45 -5
- package/dist/combat/magazine.d.ts +54 -0
- package/dist/combat/magazine.js +96 -0
- package/dist/combat/projectiles.d.ts +5 -0
- package/dist/combat/projectiles.js +32 -14
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +5 -1
- package/dist/combat/regenShield.js +5 -1
- package/dist/combat/renderCues.d.ts +51 -0
- package/dist/combat/renderCues.js +44 -0
- package/dist/combat/resourcePool.d.ts +5 -0
- package/dist/combat/resourcePool.js +5 -0
- package/dist/combat/rewardAllocation.d.ts +121 -0
- package/dist/combat/rewardAllocation.js +251 -0
- package/dist/combat/shotOrigin.d.ts +18 -1
- package/dist/combat/shotOrigin.js +39 -0
- package/dist/combat/statusApplication.d.ts +96 -0
- package/dist/combat/statusApplication.js +81 -0
- package/dist/combat/telegraph.d.ts +11 -2
- package/dist/combat/telegraph.js +11 -2
- package/dist/combat/thresholdCrossings.d.ts +85 -0
- package/dist/combat/thresholdCrossings.js +116 -0
- package/dist/combat.d.ts +34 -0
- package/dist/combat.js +34 -0
- package/dist/commands/commandRegistry.d.ts +11 -0
- package/dist/commands/commandRegistry.js +9 -2
- package/dist/crafting/crop.d.ts +18 -0
- package/dist/crafting/crop.js +18 -0
- package/dist/crafting/production.d.ts +5 -0
- package/dist/crafting/production.js +5 -0
- package/dist/devtools/rewriteTunables.d.ts +17 -0
- package/dist/devtools/rewriteTunables.js +276 -0
- package/dist/devtools/saveEndpoint.d.ts +46 -0
- package/dist/devtools/saveEndpoint.js +48 -0
- package/dist/devtools/transformTunables.d.ts +3 -0
- package/dist/devtools/transformTunables.js +3 -0
- package/dist/devtools/tunableSchema.d.ts +31 -0
- package/dist/devtools/tunableSchema.js +31 -0
- package/dist/economy/currency.d.ts +12 -1
- package/dist/economy/currency.js +12 -1
- package/dist/economy/listingBook.d.ts +91 -0
- package/dist/economy/listingBook.js +144 -0
- package/dist/economy/resourceLedger.d.ts +222 -0
- package/dist/economy/resourceLedger.js +353 -0
- package/dist/economy/sharedWallet.d.ts +14 -0
- package/dist/economy/sharedWallet.js +14 -0
- package/dist/economy/techTree.d.ts +12 -0
- package/dist/economy/techTree.js +12 -0
- package/dist/economy/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commands.d.ts +190 -7
- package/dist/editor/commands.js +727 -55
- package/dist/editor/document.d.ts +159 -13
- package/dist/editor/document.js +750 -19
- package/dist/editor/grid.d.ts +229 -0
- package/dist/editor/grid.js +366 -0
- package/dist/editor/gridAdapters.d.ts +80 -0
- package/dist/editor/gridAdapters.js +134 -0
- package/dist/editor/index.d.ts +73 -6
- package/dist/editor/index.js +6 -2
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/types.d.ts +107 -1
- package/dist/faction/reputation.d.ts +5 -0
- package/dist/faction/reputation.js +5 -0
- package/dist/format/distance.d.ts +17 -0
- package/dist/format/distance.js +18 -0
- package/dist/format/duration.d.ts +27 -0
- package/dist/format/duration.js +45 -0
- package/dist/format/speed.d.ts +17 -0
- package/dist/format/speed.js +25 -0
- package/dist/game/connectedPlayers.d.ts +6 -4
- package/dist/game/connectedPlayers.js +2 -2
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +100 -2
- package/dist/game/defineGame.js +39 -2
- package/dist/game/defineSystem.d.ts +88 -0
- package/dist/game/defineSystem.js +45 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +35 -13
- package/dist/game/events.js +5 -0
- package/dist/game/feed.d.ts +33 -0
- package/dist/game/feed.js +35 -2
- package/dist/game/gamePhase.d.ts +11 -0
- package/dist/game/gamePhase.js +16 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/loadout.d.ts +5 -0
- package/dist/game/loadout.js +5 -0
- package/dist/game/lootFilter.d.ts +2 -0
- package/dist/game/lootFilter.js +2 -0
- package/dist/game/lootPipeline.d.ts +164 -0
- package/dist/game/lootPipeline.js +216 -0
- package/dist/game/lootTable.d.ts +19 -2
- package/dist/game/lootTable.js +15 -5
- package/dist/game/objectives.d.ts +43 -0
- package/dist/game/objectives.js +36 -0
- package/dist/game/paramLayers.d.ts +148 -0
- package/dist/game/paramLayers.js +185 -0
- package/dist/game/ping.d.ts +5 -0
- package/dist/game/ping.js +5 -0
- package/dist/game/playableGame.d.ts +92 -7
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +29 -0
- package/dist/game/race.d.ts +141 -0
- package/dist/game/race.js +169 -0
- package/dist/game/recordBook.d.ts +3 -1
- package/dist/game/recordBook.js +4 -1
- package/dist/game/ruleSelection.d.ts +75 -0
- package/dist/game/ruleSelection.js +127 -0
- package/dist/game/runDraft.d.ts +5 -0
- package/dist/game/runDraft.js +5 -0
- package/dist/game/saveStore.d.ts +111 -0
- package/dist/game/saveStore.js +312 -0
- package/dist/game/snapshotHistory.d.ts +67 -0
- package/dist/game/snapshotHistory.js +95 -0
- package/dist/game/social.d.ts +38 -1
- package/dist/game/social.js +71 -0
- package/dist/game/spawnPoints.d.ts +5 -0
- package/dist/game/spawnPoints.js +5 -0
- package/dist/game/systemRuntime.d.ts +50 -0
- package/dist/game/systemRuntime.js +157 -0
- package/dist/game/systemSchedule.d.ts +72 -0
- package/dist/game/systemSchedule.js +242 -0
- package/dist/game/toasts.d.ts +43 -0
- package/dist/game/toasts.js +44 -0
- package/dist/game/trade.d.ts +10 -0
- package/dist/game/trade.js +10 -0
- package/dist/game/unlocks.d.ts +8 -0
- package/dist/game/unlocks.js +16 -0
- package/dist/game/vfxInstance.d.ts +138 -0
- package/dist/game/vfxInstance.js +96 -0
- package/dist/game/worldItem.d.ts +17 -4
- package/dist/game/worldItem.js +17 -4
- package/dist/gameplay.d.ts +91 -0
- package/dist/gameplay.js +91 -0
- package/dist/index.d.ts +5 -14
- package/dist/index.js +5 -14
- package/dist/input/actionBindings.d.ts +23 -6
- package/dist/input/actionBindings.js +23 -6
- package/dist/input/axisInput.d.ts +7 -2
- package/dist/input/axisInput.js +7 -2
- package/dist/input/controlGroups.d.ts +67 -0
- package/dist/input/controlGroups.js +41 -0
- package/dist/input/touchScheme.d.ts +82 -6
- package/dist/input/touchScheme.js +123 -10
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +2 -0
- package/dist/interaction/proximityPrompt.js +2 -0
- package/dist/interaction/qte.d.ts +5 -0
- package/dist/interaction/qte.js +5 -0
- package/dist/interaction/skillCheck.d.ts +5 -0
- package/dist/interaction/skillCheck.js +5 -0
- package/dist/inventory/inventoryModel.d.ts +12 -0
- package/dist/inventory/inventoryModel.js +12 -0
- package/dist/inventory/shapedGrid.d.ts +16 -0
- package/dist/inventory/shapedGrid.js +16 -0
- package/dist/inventory/slotModel.d.ts +10 -0
- package/dist/inventory/slotModel.js +10 -0
- package/dist/item/durability.d.ts +5 -0
- package/dist/item/durability.js +5 -0
- package/dist/item/itemIdentity.d.ts +171 -0
- package/dist/item/itemIdentity.js +138 -0
- package/dist/item/itemInstanceRegistry.d.ts +32 -0
- package/dist/item/itemInstanceRegistry.js +34 -0
- package/dist/item/itemgen.d.ts +163 -0
- package/dist/item/itemgen.js +151 -0
- package/dist/item/modularItem.d.ts +5 -0
- package/dist/item/modularItem.js +5 -0
- package/dist/item/use.d.ts +5 -0
- package/dist/item/use.js +5 -0
- package/dist/item/useBehavior.d.ts +142 -0
- package/dist/item/useBehavior.js +105 -0
- package/dist/item/weapon.d.ts +5 -0
- package/dist/item/weapon.js +5 -0
- package/dist/math/scalar.d.ts +25 -0
- package/dist/math/scalar.js +47 -0
- package/dist/meta/changelog.d.ts +4 -1
- package/dist/meta/changelog.js +16 -2
- package/dist/movement/avoidance.d.ts +45 -0
- package/dist/movement/avoidance.js +123 -0
- package/dist/movement/cameraRig.d.ts +8 -0
- package/dist/movement/cameraRig.js +8 -0
- package/dist/movement/dash.d.ts +11 -0
- package/dist/movement/dash.js +11 -0
- package/dist/movement/formation.d.ts +135 -0
- package/dist/movement/formation.js +194 -0
- package/dist/movement/glideModel.d.ts +5 -0
- package/dist/movement/glideModel.js +5 -0
- package/dist/movement/grappleSwing.d.ts +5 -0
- package/dist/movement/grappleSwing.js +5 -0
- package/dist/movement/leaderTrail.d.ts +5 -0
- package/dist/movement/leaderTrail.js +5 -0
- package/dist/movement/movementModel.d.ts +35 -8
- package/dist/movement/movementModel.js +42 -14
- package/dist/movement/playerMovement.js +65 -10
- package/dist/movement/poseState.d.ts +13 -0
- package/dist/movement/poseState.js +16 -0
- package/dist/movement/steering.d.ts +8 -0
- package/dist/movement/steering.js +18 -0
- package/dist/multiplayer/combatSnapshot.d.ts +3 -0
- package/dist/multiplayer/combatSnapshot.js +3 -0
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +9 -1
- package/dist/multiplayer/presenceModel.js +9 -1
- package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
- package/dist/multiplayer/simultaneousCommit.js +3 -0
- package/dist/multiplayer.d.ts +11 -0
- package/dist/multiplayer.js +11 -0
- package/dist/nav/pathFollow.d.ts +57 -0
- package/dist/nav/pathFollow.js +109 -0
- package/dist/orders/orderKinds.d.ts +156 -0
- package/dist/orders/orderKinds.js +197 -0
- package/dist/orders/orderQueue.d.ts +208 -0
- package/dist/orders/orderQueue.js +211 -0
- package/dist/physics/drivableVehicle.d.ts +29 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/kinematicVehicle.d.ts +21 -1
- package/dist/physics/kinematicVehicle.js +23 -8
- package/dist/physics/physicsWorld.d.ts +24 -12
- package/dist/physics/physicsWorld.js +11 -5
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -0
- package/dist/procedural.d.ts +3 -0
- package/dist/procedural.js +3 -0
- package/dist/progression/statGraph.d.ts +116 -0
- package/dist/progression/statGraph.js +318 -0
- package/dist/puzzle/cellGrid.d.ts +9 -0
- package/dist/puzzle/cellGrid.js +9 -0
- package/dist/puzzle/fallingPiece.d.ts +9 -0
- package/dist/puzzle/fallingPiece.js +9 -0
- package/dist/puzzle/nonogram.d.ts +39 -0
- package/dist/puzzle/nonogram.js +136 -0
- package/dist/random/nameGen.d.ts +5 -0
- package/dist/random/nameGen.js +5 -0
- package/dist/random/pick.d.ts +8 -0
- package/dist/random/pick.js +31 -0
- package/dist/random/rng.d.ts +22 -0
- package/dist/random/rng.js +28 -8
- package/dist/random/seedLink.d.ts +4 -0
- package/dist/random/seedLink.js +4 -0
- package/dist/relation/keyedValues.d.ts +54 -0
- package/dist/relation/keyedValues.js +115 -0
- package/dist/relation/thresholds.d.ts +62 -0
- package/dist/relation/thresholds.js +62 -0
- package/dist/render/color.d.ts +12 -0
- package/dist/render/color.js +26 -0
- package/dist/render/lookPreset.d.ts +41 -0
- package/dist/render/lookPreset.js +29 -0
- package/dist/render/postProcessing.d.ts +20 -0
- package/dist/render/postProcessing.js +21 -1
- package/dist/rules/predicate.d.ts +53 -0
- package/dist/rules/predicate.js +64 -0
- package/dist/rules/ruleEffects.d.ts +38 -0
- package/dist/rules/ruleEffects.js +37 -0
- package/dist/rules/triggeredRules.d.ts +160 -0
- package/dist/rules/triggeredRules.js +241 -0
- package/dist/runtime/adapter.d.ts +42 -3
- package/dist/runtime/adapter.js +44 -1
- package/dist/runtime/cameraDirector.d.ts +1 -0
- package/dist/runtime/cameraDirector.js +1 -0
- package/dist/runtime/commandRunner.d.ts +1 -0
- package/dist/runtime/commandRunner.js +1 -0
- package/dist/runtime/context/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -0
- package/dist/runtime/context/worldItems.d.ts +21 -0
- package/dist/runtime/context/worldItems.js +37 -0
- package/dist/runtime/descriptors/baseline.d.ts +48 -0
- package/dist/runtime/descriptors/baseline.js +134 -0
- package/dist/runtime/descriptors/features.d.ts +74 -0
- package/dist/runtime/descriptors/features.js +281 -0
- package/dist/runtime/gameContext.d.ts +114 -13
- package/dist/runtime/gameContext.js +303 -395
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +60 -0
- package/dist/runtime/headlessRunner.js +44 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostedGameRunner.d.ts +8 -3
- package/dist/runtime/hostedGameRunner.js +26 -3
- package/dist/runtime/hostedWorldSession.d.ts +12 -4
- package/dist/runtime/hostedWorldSession.js +11 -4
- package/dist/runtime/inputSnapshot.d.ts +8 -3
- package/dist/runtime/inputSnapshot.js +6 -2
- package/dist/runtime/motionIntents.d.ts +11 -2
- package/dist/runtime/motionIntents.js +16 -2
- package/dist/runtime/perContext.d.ts +15 -0
- package/dist/runtime/perContext.js +21 -0
- package/dist/runtime/runtimeSave.d.ts +79 -0
- package/dist/runtime/runtimeSave.js +105 -0
- package/dist/runtime/save.d.ts +4 -0
- package/dist/runtime/save.js +4 -0
- package/dist/runtime/snapshot.d.ts +7 -0
- package/dist/runtime/snapshot.js +7 -0
- package/dist/runtime/visibility.d.ts +2 -1
- package/dist/runtime/visibility.js +2 -1
- package/dist/runtime/worldChannel.d.ts +7 -3
- package/dist/runtime/worldChannel.js +51 -6
- package/dist/runtime/worldMirror.d.ts +14 -2
- package/dist/runtime/worldMirror.js +15 -2
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +30 -7
- package/dist/runtime/worldReplication.js +41 -9
- package/dist/runtime/worldSnapshot.d.ts +30 -3
- package/dist/runtime/worldSnapshot.js +20 -5
- package/dist/scene/assetCatalog.d.ts +21 -0
- package/dist/scene/assetCatalog.js +4 -0
- package/dist/scene/assetDiagnostics.d.ts +69 -0
- package/dist/scene/assetDiagnostics.js +110 -0
- package/dist/scene/assetGenerator.d.ts +65 -0
- package/dist/scene/assetGenerator.js +64 -0
- package/dist/scene/assetSpace.d.ts +137 -0
- package/dist/scene/assetSpace.js +259 -0
- package/dist/scene/authoredTriggers.d.ts +169 -0
- package/dist/scene/authoredTriggers.js +340 -0
- package/dist/scene/behaviorRuntime.d.ts +75 -0
- package/dist/scene/behaviorRuntime.js +217 -0
- package/dist/scene/behaviors.d.ts +14 -2
- package/dist/scene/behaviors.js +7 -2
- package/dist/scene/bodyBind.d.ts +60 -0
- package/dist/scene/bodyBind.js +51 -0
- package/dist/scene/builtinSceneKinds.d.ts +5 -0
- package/dist/scene/builtinSceneKinds.js +62 -0
- package/dist/scene/colliders.d.ts +13 -1
- package/dist/scene/colliders.js +37 -1
- package/dist/scene/entityStats.d.ts +11 -2
- package/dist/scene/entityStats.js +11 -2
- package/dist/scene/entityStore.d.ts +12 -1
- package/dist/scene/entityStore.js +15 -0
- package/dist/scene/facing.d.ts +18 -0
- package/dist/scene/facing.js +26 -0
- package/dist/scene/modelSockets.d.ts +33 -0
- package/dist/scene/modelSockets.js +29 -0
- package/dist/scene/objectQuery.d.ts +2 -0
- package/dist/scene/objectQuery.js +2 -0
- package/dist/scene/objectStore.d.ts +4 -0
- package/dist/scene/objectStore.js +6 -0
- package/dist/scene/possession.d.ts +8 -0
- package/dist/scene/possession.js +14 -0
- package/dist/scene/roster.d.ts +3 -0
- package/dist/scene/roster.js +12 -0
- package/dist/scene/sceneKinds.d.ts +240 -0
- package/dist/scene/sceneKinds.js +214 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -0
- package/dist/scene/selectionBookmarks.d.ts +93 -0
- package/dist/scene/selectionBookmarks.js +122 -0
- package/dist/scene/vehicleSeat.d.ts +68 -0
- package/dist/scene/vehicleSeat.js +59 -0
- package/dist/sensor/concealment.d.ts +3 -0
- package/dist/sensor/concealment.js +3 -0
- package/dist/sensor/freezeMonitor.d.ts +1 -0
- package/dist/sensor/freezeMonitor.js +1 -0
- package/dist/sensor/frustumSensor.d.ts +7 -3
- package/dist/sensor/frustumSensor.js +7 -3
- package/dist/sensor/hiddenStateProbe.d.ts +5 -2
- package/dist/sensor/hiddenStateProbe.js +5 -2
- package/dist/sensor/recordingBuffer.d.ts +2 -1
- package/dist/sensor/recordingBuffer.js +2 -1
- package/dist/sensor/replayLoop.d.ts +6 -2
- package/dist/sensor/replayLoop.js +6 -2
- package/dist/sensor/revealQuery.d.ts +2 -1
- package/dist/sensor/revealQuery.js +2 -1
- package/dist/sensor/visionCone.d.ts +10 -3
- package/dist/sensor/visionCone.js +10 -3
- package/dist/session/contestedChannel.d.ts +1 -0
- package/dist/session/contestedChannel.js +1 -0
- package/dist/session/extraction.d.ts +1 -0
- package/dist/session/extraction.js +1 -0
- package/dist/session/roles.d.ts +6 -0
- package/dist/session/roles.js +6 -0
- package/dist/session/roundState.d.ts +8 -0
- package/dist/session/roundState.js +2 -0
- package/dist/settings/settingsModel.d.ts +1 -0
- package/dist/settings/settingsModel.js +1 -0
- package/dist/stats/accumulatorMeter.d.ts +6 -0
- package/dist/stats/accumulatorMeter.js +6 -0
- package/dist/stats/eventMeter.d.ts +5 -0
- package/dist/stats/eventMeter.js +5 -0
- package/dist/stats/rollCheck.d.ts +5 -0
- package/dist/stats/rollCheck.js +5 -0
- package/dist/stats/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -0
- package/dist/store/defineKeyedStore.d.ts +38 -0
- package/dist/store/defineKeyedStore.js +42 -0
- package/dist/store/defineStore.d.ts +33 -0
- package/dist/store/defineStore.js +35 -0
- package/dist/store/observableKeyedStore.d.ts +5 -0
- package/dist/store/observableKeyedStore.js +34 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -55
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +5 -0
- package/dist/tactics/fallingGrid.d.ts +4 -2
- package/dist/tactics/fallingGrid.js +4 -2
- package/dist/tactics/predictiveQuery.d.ts +3 -0
- package/dist/tactics/predictiveQuery.js +3 -0
- package/dist/tactics/snapshot.d.ts +2 -0
- package/dist/tactics/snapshot.js +2 -0
- package/dist/tactics/surface.d.ts +1 -0
- package/dist/tactics/surface.js +1 -0
- package/dist/tactics/tacticalGrid.d.ts +1 -0
- package/dist/tactics/tacticalGrid.js +1 -0
- package/dist/time/beatClock.d.ts +14 -4
- package/dist/time/beatClock.js +14 -4
- package/dist/time/calendarClock.d.ts +3 -0
- package/dist/time/calendarClock.js +3 -0
- package/dist/time/idleProgress.d.ts +4 -0
- package/dist/time/idleProgress.js +4 -0
- package/dist/time/simClock.d.ts +2 -0
- package/dist/time/simClock.js +20 -5
- package/dist/ui/actionModel.d.ts +110 -0
- package/dist/ui/actionModel.js +159 -0
- package/dist/ui/gameLayout.d.ts +30 -11
- package/dist/ui/gameLayout.js +30 -11
- package/dist/ui/hudDocument.d.ts +114 -0
- package/dist/ui/hudDocument.js +220 -0
- package/dist/ui/hudLayout.d.ts +33 -1
- package/dist/ui/hudLayout.js +204 -17
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/tooltipModel.d.ts +63 -0
- package/dist/ui/tooltipModel.js +82 -0
- package/dist/ui.d.ts +15 -0
- package/dist/ui.js +15 -0
- package/dist/visibility/bounds.d.ts +8 -1
- package/dist/visibility/bounds.js +8 -1
- package/dist/visibility/frustum.d.ts +12 -3
- package/dist/visibility/frustum.js +12 -3
- package/dist/work/jobQueue.d.ts +201 -0
- package/dist/work/jobQueue.js +253 -0
- package/dist/work/unitTraining.d.ts +58 -0
- package/dist/work/unitTraining.js +52 -0
- package/dist/world/authoredObjects.d.ts +58 -0
- package/dist/world/authoredObjects.js +69 -0
- package/dist/world/buildingGenerator.d.ts +18 -0
- package/dist/world/buildingGenerator.js +62 -0
- package/dist/world/buildings.d.ts +5 -0
- package/dist/world/buildings.js +5 -0
- package/dist/world/catenary.d.ts +22 -0
- package/dist/world/catenary.js +69 -0
- package/dist/world/features.d.ts +115 -7
- package/dist/world/features.js +56 -5
- package/dist/world/footprintGrid.d.ts +59 -0
- package/dist/world/footprintGrid.js +141 -0
- package/dist/world/geometry.d.ts +64 -0
- package/dist/world/geometry.js +94 -0
- package/dist/world/grassKind.d.ts +51 -0
- package/dist/world/grassKind.js +101 -0
- package/dist/world/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +77 -0
- package/dist/world/placement.d.ts +4 -0
- package/dist/world/placement.js +4 -0
- package/dist/world/placementController.d.ts +6 -0
- package/dist/world/placementController.js +6 -0
- package/dist/world/polyline.d.ts +34 -0
- package/dist/world/polyline.js +81 -0
- package/dist/world/roads.d.ts +8 -0
- package/dist/world/roads.js +38 -0
- package/dist/world/scatterRegion.d.ts +164 -0
- package/dist/world/scatterRegion.js +409 -0
- package/dist/world/sceneShapes.d.ts +43 -0
- package/dist/world/sceneShapes.js +1 -0
- package/dist/world/segment.d.ts +27 -0
- package/dist/world/segment.js +43 -0
- package/dist/world/soilKind.d.ts +48 -0
- package/dist/world/soilKind.js +92 -0
- package/dist/world/spatialSample.d.ts +241 -0
- package/dist/world/spatialSample.js +465 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +655 -20
- package/dist/world/terrain.d.ts +119 -20
- package/dist/world/terrain.js +247 -41
- package/dist/world/terrainGuides.d.ts +182 -0
- package/dist/world/terrainGuides.js +343 -0
- package/dist/world/vec2.d.ts +81 -0
- package/dist/world/vec2.js +128 -0
- package/dist/world/vec3.d.ts +49 -0
- package/dist/world/vec3.js +76 -0
- package/dist/world/vegetation.d.ts +71 -0
- package/dist/world/vegetation.js +151 -0
- package/dist/world/visibilityField.d.ts +154 -0
- package/dist/world/visibilityField.js +271 -0
- package/dist/world/volumetricClouds.d.ts +52 -0
- package/dist/world/volumetricClouds.js +43 -0
- package/dist/world/walls.d.ts +9 -0
- package/dist/world/walls.js +9 -0
- package/dist/world/waterKind.d.ts +55 -0
- package/dist/world/waterKind.js +99 -0
- package/dist/world.d.ts +132 -0
- package/dist/world.js +132 -0
- package/package.json +32 -8
- package/skills/jgengine/SKILL.md +51 -0
- package/skills/jgengine/api.md +434 -0
- package/skills/jgengine/capabilities.md +29 -0
- package/skills/jgengine/reference-cartridge.md +72 -0
- package/skills/jgengine-combat/SKILL.md +34 -0
- package/skills/jgengine-combat/api.md +549 -0
- package/skills/jgengine-combat/capabilities.md +169 -0
- package/skills/jgengine-combat/reference.md +98 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1794 -0
- package/skills/jgengine-gameplay/capabilities.md +378 -0
- package/skills/jgengine-gameplay/reference-systems.md +60 -0
- package/skills/jgengine-world/SKILL.md +38 -0
- package/skills/jgengine-world/api.md +2652 -0
- package/skills/jgengine-world/capabilities.md +370 -0
- package/skills/jgengine-world/reference.md +222 -0
- package/dist/cartridge/runtime.d.ts +0 -15
- package/dist/cartridge/runtime.js +0 -556
- package/dist/cartridge/spec.d.ts +0 -188
- package/dist/cartridge/spec.js +0 -19
- package/dist/cartridge/validate.d.ts +0 -2
- package/dist/cartridge/validate.js +0 -78
- package/dist/store/engineStore.d.ts +0 -22
- package/dist/store/engineStore.js +0 -50
- package/dist/store/features.d.ts +0 -10
- package/dist/store/features.js +0 -23
- package/llms.txt +0 -5389
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import { pointInAabb } from "./geometry.js";
|
|
2
|
+
import { pointInPolygon, polygonBounds } from "./scatterRegion.js";
|
|
3
|
+
const DEFAULT_MAX_ATTEMPTS = 30;
|
|
4
|
+
const TWO_PI = Math.PI * 2;
|
|
5
|
+
function distanceSq(a, b) {
|
|
6
|
+
const n = a.length < b.length ? a.length : b.length;
|
|
7
|
+
let sum = 0;
|
|
8
|
+
for (let i = 0; i < n; i += 1) {
|
|
9
|
+
const d = a[i] - b[i];
|
|
10
|
+
sum += d * d;
|
|
11
|
+
}
|
|
12
|
+
return sum;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A uniform spatial hash over cells of `cellSize`, used to enforce minimum separation in O(1)
|
|
16
|
+
* neighborhood checks instead of an O(n²) scan — the allocation-aware index behind batch spacing.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
class SeparationIndex {
|
|
20
|
+
cellSize;
|
|
21
|
+
dimensions;
|
|
22
|
+
buckets = new Map();
|
|
23
|
+
minSq;
|
|
24
|
+
constructor(cellSize, dimensions) {
|
|
25
|
+
this.cellSize = cellSize;
|
|
26
|
+
this.dimensions = dimensions;
|
|
27
|
+
this.minSq = cellSize * cellSize;
|
|
28
|
+
}
|
|
29
|
+
key(cell) {
|
|
30
|
+
return cell.join(":");
|
|
31
|
+
}
|
|
32
|
+
cellOf(point) {
|
|
33
|
+
const cell = [];
|
|
34
|
+
for (let i = 0; i < this.dimensions; i += 1)
|
|
35
|
+
cell.push(Math.floor(point[i] / this.cellSize));
|
|
36
|
+
return cell;
|
|
37
|
+
}
|
|
38
|
+
/** True when `point` sits within `cellSize` of any inserted point. */
|
|
39
|
+
tooClose(point) {
|
|
40
|
+
const base = this.cellOf(point);
|
|
41
|
+
const dims = this.dimensions;
|
|
42
|
+
const stack = [];
|
|
43
|
+
const walk = (axis) => {
|
|
44
|
+
if (axis === dims) {
|
|
45
|
+
const bucket = this.buckets.get(this.key(stack));
|
|
46
|
+
if (bucket !== undefined)
|
|
47
|
+
for (const other of bucket)
|
|
48
|
+
if (distanceSq(point, other) < this.minSq)
|
|
49
|
+
return true;
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
for (let d = -1; d <= 1; d += 1) {
|
|
53
|
+
stack[axis] = base[axis] + d;
|
|
54
|
+
if (walk(axis + 1))
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
};
|
|
59
|
+
return walk(0);
|
|
60
|
+
}
|
|
61
|
+
insert(point) {
|
|
62
|
+
const key = this.key(this.cellOf(point));
|
|
63
|
+
const bucket = this.buckets.get(key);
|
|
64
|
+
if (bucket !== undefined)
|
|
65
|
+
bucket.push(point);
|
|
66
|
+
else
|
|
67
|
+
this.buckets.set(key, [point]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function passesConstraints(point, constraints, index) {
|
|
71
|
+
if (constraints === undefined)
|
|
72
|
+
return index === null || !index.tooClose(point);
|
|
73
|
+
if (constraints.include !== undefined)
|
|
74
|
+
for (const region of constraints.include)
|
|
75
|
+
if (!region.contains(point))
|
|
76
|
+
return false;
|
|
77
|
+
if (constraints.exclude !== undefined)
|
|
78
|
+
for (const region of constraints.exclude)
|
|
79
|
+
if (region.contains(point))
|
|
80
|
+
return false;
|
|
81
|
+
if (index !== null && index.tooClose(point))
|
|
82
|
+
return false;
|
|
83
|
+
if (constraints.accept !== undefined && !constraints.accept(point))
|
|
84
|
+
return false;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
function resolveFallback(fallback, last, attempts, reason) {
|
|
88
|
+
if (fallback !== undefined && fallback !== "none") {
|
|
89
|
+
if (fallback === "last-candidate") {
|
|
90
|
+
if (last !== null)
|
|
91
|
+
return { ok: false, point: last, attempts, reason, usedFallback: true };
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
return { ok: false, point: fallback.point, attempts, reason, usedFallback: true };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return { ok: false, point: null, attempts, reason, usedFallback: false };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Draw one point from `region` that clears every constraint, retrying up to `maxAttempts` times with
|
|
101
|
+
* the injected `rng`, then apply the `fallback` policy. Returns a structured {@link SampleResult} —
|
|
102
|
+
* a clean hit is `ok: true`; exhaustion or a degenerate region is reported with the attempt count and
|
|
103
|
+
* an explicit fallback flag, never a silently-accepted bad point.
|
|
104
|
+
*
|
|
105
|
+
* @capability spatial-sample draw one deterministic position from a region under include/exclude/distance constraints
|
|
106
|
+
*/
|
|
107
|
+
export function samplePoint(options) {
|
|
108
|
+
const { region, rng, constraints } = options;
|
|
109
|
+
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
110
|
+
if (region.isEmpty)
|
|
111
|
+
return resolveFallback(options.fallback, null, 0, "empty-region");
|
|
112
|
+
let index = null;
|
|
113
|
+
const minSeparation = constraints?.minSeparation ?? 0;
|
|
114
|
+
const placed = options.placed ?? [];
|
|
115
|
+
if (minSeparation > 0 && placed.length > 0) {
|
|
116
|
+
index = new SeparationIndex(minSeparation, region.dimensions);
|
|
117
|
+
for (const point of placed)
|
|
118
|
+
index.insert(point);
|
|
119
|
+
}
|
|
120
|
+
let last = null;
|
|
121
|
+
let attempts = 0;
|
|
122
|
+
while (attempts < maxAttempts) {
|
|
123
|
+
attempts += 1;
|
|
124
|
+
let candidate = region.sample(rng);
|
|
125
|
+
if (constraints?.project !== undefined)
|
|
126
|
+
candidate = constraints.project(candidate);
|
|
127
|
+
if (candidate === null)
|
|
128
|
+
continue;
|
|
129
|
+
last = candidate;
|
|
130
|
+
if (passesConstraints(candidate, constraints, index)) {
|
|
131
|
+
return { ok: true, point: candidate, attempts, reason: "accepted", usedFallback: false };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return resolveFallback(options.fallback, last, attempts, "exhausted");
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Place up to `count` points from `region`, each clearing the shared constraints and honoring
|
|
138
|
+
* `minSeparation` against every point already placed in this batch (via a spatial hash, not an
|
|
139
|
+
* O(n²) scan). Order is deterministic for a given `rng` stream. Batches never silently under-fill:
|
|
140
|
+
* the result reports `placed`, `complete`, and the total attempt count.
|
|
141
|
+
*
|
|
142
|
+
* @capability spatial-sample-batch place many deterministic spaced points from a region with minimum separation
|
|
143
|
+
*/
|
|
144
|
+
export function sampleBatch(options) {
|
|
145
|
+
const { region, rng, constraints } = options;
|
|
146
|
+
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
147
|
+
const requested = Math.max(0, Math.floor(options.count));
|
|
148
|
+
const points = [];
|
|
149
|
+
if (requested === 0 || region.isEmpty) {
|
|
150
|
+
return { points, requested, placed: 0, complete: requested === 0, attempts: 0 };
|
|
151
|
+
}
|
|
152
|
+
const minSeparation = constraints?.minSeparation ?? 0;
|
|
153
|
+
const index = minSeparation > 0 ? new SeparationIndex(minSeparation, region.dimensions) : null;
|
|
154
|
+
let attempts = 0;
|
|
155
|
+
for (let i = 0; i < requested; i += 1) {
|
|
156
|
+
let placed = null;
|
|
157
|
+
let tries = 0;
|
|
158
|
+
while (tries < maxAttempts) {
|
|
159
|
+
tries += 1;
|
|
160
|
+
attempts += 1;
|
|
161
|
+
let candidate = region.sample(rng);
|
|
162
|
+
if (constraints?.project !== undefined)
|
|
163
|
+
candidate = constraints.project(candidate);
|
|
164
|
+
if (candidate === null)
|
|
165
|
+
continue;
|
|
166
|
+
if (passesConstraints(candidate, constraints, index)) {
|
|
167
|
+
placed = candidate;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (placed === null)
|
|
172
|
+
break;
|
|
173
|
+
points.push(placed);
|
|
174
|
+
if (index !== null)
|
|
175
|
+
index.insert(placed);
|
|
176
|
+
}
|
|
177
|
+
return { points, requested, placed: points.length, complete: points.length === requested, attempts };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* A fixed set of candidate points sampled by (optionally weighted) selection — the "spawn point
|
|
181
|
+
* table" region. `contains` is exact membership. Empty when the set is empty.
|
|
182
|
+
*
|
|
183
|
+
* @capability spatial-region-point-set sample from a fixed, optionally weighted candidate point table
|
|
184
|
+
*/
|
|
185
|
+
export function pointSetRegion(points, options = {}) {
|
|
186
|
+
const pool = points.map((p) => [p[0], p[1]]);
|
|
187
|
+
const weights = options.weights;
|
|
188
|
+
const total = weights === undefined ? pool.length : weights.reduce((sum, w) => sum + Math.max(0, w), 0);
|
|
189
|
+
return {
|
|
190
|
+
dimensions: 2,
|
|
191
|
+
isEmpty: pool.length === 0 || total <= 0,
|
|
192
|
+
sample(rng) {
|
|
193
|
+
if (weights === undefined)
|
|
194
|
+
return pool[Math.min(pool.length - 1, Math.floor(rng() * pool.length))];
|
|
195
|
+
let roll = rng() * total;
|
|
196
|
+
for (let i = 0; i < pool.length; i += 1) {
|
|
197
|
+
roll -= Math.max(0, weights[i] ?? 0);
|
|
198
|
+
if (roll <= 0)
|
|
199
|
+
return pool[i];
|
|
200
|
+
}
|
|
201
|
+
return pool[pool.length - 1];
|
|
202
|
+
},
|
|
203
|
+
contains(point) {
|
|
204
|
+
return pool.some((p) => p[0] === point[0] && p[1] === point[1]);
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* An axis-aligned rectangle on the XZ plane. `"uniform"` spreads evenly (draws x then z);
|
|
210
|
+
* `"edge"` biases onto a boundary band of `edgeThickness` meters (perimeter-weighted side, then
|
|
211
|
+
* inward depth) — the two are never conflated, the caller opts in.
|
|
212
|
+
*/
|
|
213
|
+
export function rectRegion(area, options = {}) {
|
|
214
|
+
const width = area.maxX - area.minX;
|
|
215
|
+
const depth = area.maxZ - area.minZ;
|
|
216
|
+
const distribution = options.distribution ?? "uniform";
|
|
217
|
+
const edgeThickness = Math.max(0, options.edgeThickness ?? Math.min(width, depth) * 0.25);
|
|
218
|
+
return {
|
|
219
|
+
dimensions: 2,
|
|
220
|
+
isEmpty: !(width > 0) || !(depth > 0),
|
|
221
|
+
sample(rng) {
|
|
222
|
+
if (distribution === "edge") {
|
|
223
|
+
const perim = 2 * (width + depth);
|
|
224
|
+
const sidePick = rng() * perim;
|
|
225
|
+
const t = rng();
|
|
226
|
+
const inset = Math.min(edgeThickness, Math.min(width, depth) / 2) * rng();
|
|
227
|
+
if (sidePick < width)
|
|
228
|
+
return [area.minX + t * width, area.minZ + inset];
|
|
229
|
+
if (sidePick < width + depth)
|
|
230
|
+
return [area.maxX - inset, area.minZ + t * depth];
|
|
231
|
+
if (sidePick < 2 * width + depth)
|
|
232
|
+
return [area.minX + t * width, area.maxZ - inset];
|
|
233
|
+
return [area.minX + inset, area.minZ + t * depth];
|
|
234
|
+
}
|
|
235
|
+
const x = area.minX + rng() * width;
|
|
236
|
+
const z = area.minZ + rng() * depth;
|
|
237
|
+
return [x, z];
|
|
238
|
+
},
|
|
239
|
+
contains(point) {
|
|
240
|
+
return pointInAabb(point, area);
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function radialRadius(rng, inner, outer, distribution) {
|
|
245
|
+
const u = rng();
|
|
246
|
+
if (distribution === "area")
|
|
247
|
+
return Math.sqrt(inner * inner + u * (outer * outer - inner * inner));
|
|
248
|
+
return inner + u * (outer - inner);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* A filled circle. `"area"` is area-uniform (√-corrected radius, even density); `"radial"` is
|
|
252
|
+
* radius-uniform (clumps toward the center). Angle is drawn first, then radius — matching the common
|
|
253
|
+
* `angle = rng()·2π; r = rng()·R` idiom so migrations keep their stream.
|
|
254
|
+
*/
|
|
255
|
+
export function discRegion(center, radius, options = {}) {
|
|
256
|
+
const distribution = options.distribution ?? "area";
|
|
257
|
+
const r = Math.max(0, radius);
|
|
258
|
+
return {
|
|
259
|
+
dimensions: 2,
|
|
260
|
+
isEmpty: !(r > 0),
|
|
261
|
+
sample(rng) {
|
|
262
|
+
const angle = rng() * TWO_PI;
|
|
263
|
+
const dist = radialRadius(rng, 0, r, distribution);
|
|
264
|
+
return [center[0] + Math.cos(angle) * dist, center[1] + Math.sin(angle) * dist];
|
|
265
|
+
},
|
|
266
|
+
contains(point) {
|
|
267
|
+
return distanceSq(point, center) <= r * r;
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* A ring (annulus) between `innerRadius` and `outerRadius`. `"area"` fills the band with even
|
|
273
|
+
* density; `"radial"` spreads uniformly in radius. Angle first, then radius.
|
|
274
|
+
*/
|
|
275
|
+
export function annulusRegion(center, innerRadius, outerRadius, options = {}) {
|
|
276
|
+
const distribution = options.distribution ?? "area";
|
|
277
|
+
const inner = Math.max(0, Math.min(innerRadius, outerRadius));
|
|
278
|
+
const outer = Math.max(innerRadius, outerRadius, 0);
|
|
279
|
+
return {
|
|
280
|
+
dimensions: 2,
|
|
281
|
+
isEmpty: !(outer > 0) || outer <= inner,
|
|
282
|
+
sample(rng) {
|
|
283
|
+
const angle = rng() * TWO_PI;
|
|
284
|
+
const dist = radialRadius(rng, inner, outer, distribution);
|
|
285
|
+
return [center[0] + Math.cos(angle) * dist, center[1] + Math.sin(angle) * dist];
|
|
286
|
+
},
|
|
287
|
+
contains(point) {
|
|
288
|
+
const d2 = distanceSq(point, center);
|
|
289
|
+
return d2 >= inner * inner && d2 <= outer * outer;
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* An arbitrary closed polygon on the XZ plane. Candidates are drawn uniformly from the polygon's
|
|
295
|
+
* bounding box and gated by point-in-polygon `contains`, so a run's draw count stays fixed (the
|
|
296
|
+
* sampler's attempt budget bounds the rejection, not a hidden inner loop).
|
|
297
|
+
*
|
|
298
|
+
* @capability spatial-region-polygon sample within an arbitrary closed polygon on the XZ plane
|
|
299
|
+
*/
|
|
300
|
+
export function polygonRegion(polygon) {
|
|
301
|
+
const bounds = polygonBounds(polygon);
|
|
302
|
+
const width = bounds === null ? 0 : bounds.maxX - bounds.minX;
|
|
303
|
+
const depth = bounds === null ? 0 : bounds.maxZ - bounds.minZ;
|
|
304
|
+
return {
|
|
305
|
+
dimensions: 2,
|
|
306
|
+
isEmpty: bounds === null || polygon.length < 3 || !(width > 0) || !(depth > 0),
|
|
307
|
+
sample(rng) {
|
|
308
|
+
const b = bounds ?? { minX: 0, minZ: 0, maxX: 0, maxZ: 0 };
|
|
309
|
+
return [b.minX + rng() * width, b.minZ + rng() * depth];
|
|
310
|
+
},
|
|
311
|
+
contains(point) {
|
|
312
|
+
return pointInPolygon(point, polygon);
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* A composite that first picks one member by weight, then delegates to its sampler — the
|
|
318
|
+
* "weighted subregions" distribution policy. `contains` is true when any member contains the point.
|
|
319
|
+
*
|
|
320
|
+
* @capability spatial-region-weighted compose sub-regions behind a weighted selection policy
|
|
321
|
+
*/
|
|
322
|
+
export function weightedRegion(entries) {
|
|
323
|
+
const usable = entries.filter((e) => e.weight > 0 && !e.region.isEmpty);
|
|
324
|
+
const total = usable.reduce((sum, e) => sum + e.weight, 0);
|
|
325
|
+
const dimensions = entries[0]?.region.dimensions ?? 2;
|
|
326
|
+
return {
|
|
327
|
+
dimensions,
|
|
328
|
+
isEmpty: usable.length === 0,
|
|
329
|
+
sample(rng) {
|
|
330
|
+
let roll = rng() * total;
|
|
331
|
+
for (const entry of usable) {
|
|
332
|
+
roll -= entry.weight;
|
|
333
|
+
if (roll <= 0)
|
|
334
|
+
return entry.region.sample(rng);
|
|
335
|
+
}
|
|
336
|
+
return usable[usable.length - 1].region.sample(rng);
|
|
337
|
+
},
|
|
338
|
+
contains(point) {
|
|
339
|
+
return entries.some((e) => e.region.contains(point));
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Wrap a caller-defined sampler and bounds test as a {@link SampleRegion} — the escape hatch for
|
|
345
|
+
* regions the built-ins do not cover (a navmesh cell, a heightfield mask, a spline tube).
|
|
346
|
+
*
|
|
347
|
+
* @capability spatial-region-custom wrap a caller-defined sampler and bounds test as a region
|
|
348
|
+
*/
|
|
349
|
+
export function customRegion(spec) {
|
|
350
|
+
return {
|
|
351
|
+
dimensions: spec.dimensions,
|
|
352
|
+
isEmpty: spec.isEmpty ?? false,
|
|
353
|
+
sample: spec.sample,
|
|
354
|
+
contains: spec.contains,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
// ---------------------------------------------------------------------------
|
|
358
|
+
// 3D region builders
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
/**
|
|
361
|
+
* An axis-aligned box `[min..max]` in 3D. Uniform density; draws x, y, z in order.
|
|
362
|
+
*
|
|
363
|
+
* @capability spatial-region-box sample uniformly within an axis-aligned 3D box
|
|
364
|
+
*/
|
|
365
|
+
export function boxRegion(min, max) {
|
|
366
|
+
const size = [max[0] - min[0], max[1] - min[1], max[2] - min[2]];
|
|
367
|
+
return {
|
|
368
|
+
dimensions: 3,
|
|
369
|
+
isEmpty: !(size[0] > 0) || !(size[1] > 0) || !(size[2] > 0),
|
|
370
|
+
sample(rng) {
|
|
371
|
+
return [min[0] + rng() * size[0], min[1] + rng() * size[1], min[2] + rng() * size[2]];
|
|
372
|
+
},
|
|
373
|
+
contains(point) {
|
|
374
|
+
return (point[0] >= min[0] && point[0] <= max[0] &&
|
|
375
|
+
point[1] >= min[1] && point[1] <= max[1] &&
|
|
376
|
+
point[2] >= min[2] && point[2] <= max[2]);
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function sphereDirection(rng) {
|
|
381
|
+
const cosTheta = 1 - 2 * rng();
|
|
382
|
+
const sinTheta = Math.sqrt(Math.max(0, 1 - cosTheta * cosTheta));
|
|
383
|
+
const phi = rng() * TWO_PI;
|
|
384
|
+
return [sinTheta * Math.cos(phi), sinTheta * Math.sin(phi), cosTheta];
|
|
385
|
+
}
|
|
386
|
+
function volumeRadius(rng, inner, outer, distribution) {
|
|
387
|
+
const u = rng();
|
|
388
|
+
if (distribution === "volume")
|
|
389
|
+
return Math.cbrt(inner ** 3 + u * (outer ** 3 - inner ** 3));
|
|
390
|
+
return inner + u * (outer - inner);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* A filled ball. `"volume"` is volume-uniform (∛-corrected radius); `"radial"` is radius-uniform.
|
|
394
|
+
* Direction is drawn first (two draws), then radius.
|
|
395
|
+
*
|
|
396
|
+
* @capability spatial-region-sphere sample within a filled 3D ball, volume- or radius-uniform
|
|
397
|
+
*/
|
|
398
|
+
export function sphereRegion(center, radius, options = {}) {
|
|
399
|
+
const distribution = options.distribution ?? "volume";
|
|
400
|
+
const r = Math.max(0, radius);
|
|
401
|
+
return {
|
|
402
|
+
dimensions: 3,
|
|
403
|
+
isEmpty: !(r > 0),
|
|
404
|
+
sample(rng) {
|
|
405
|
+
const dir = sphereDirection(rng);
|
|
406
|
+
const dist = volumeRadius(rng, 0, r, distribution);
|
|
407
|
+
return [center[0] + dir[0] * dist, center[1] + dir[1] * dist, center[2] + dir[2] * dist];
|
|
408
|
+
},
|
|
409
|
+
contains(point) {
|
|
410
|
+
return distanceSq(point, center) <= r * r;
|
|
411
|
+
},
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* A spherical shell between `innerRadius` and `outerRadius`. `"volume"` fills the shell with even
|
|
416
|
+
* density; `"radial"` spreads uniformly in radius. Direction first, then radius.
|
|
417
|
+
*
|
|
418
|
+
* @capability spatial-region-shell sample within a 3D spherical shell, volume- or radius-uniform
|
|
419
|
+
*/
|
|
420
|
+
export function shellRegion(center, innerRadius, outerRadius, options = {}) {
|
|
421
|
+
const distribution = options.distribution ?? "volume";
|
|
422
|
+
const inner = Math.max(0, Math.min(innerRadius, outerRadius));
|
|
423
|
+
const outer = Math.max(innerRadius, outerRadius, 0);
|
|
424
|
+
return {
|
|
425
|
+
dimensions: 3,
|
|
426
|
+
isEmpty: !(outer > 0) || outer <= inner,
|
|
427
|
+
sample(rng) {
|
|
428
|
+
const dir = sphereDirection(rng);
|
|
429
|
+
const dist = volumeRadius(rng, inner, outer, distribution);
|
|
430
|
+
return [center[0] + dir[0] * dist, center[1] + dir[1] * dist, center[2] + dir[2] * dist];
|
|
431
|
+
},
|
|
432
|
+
contains(point) {
|
|
433
|
+
const d2 = distanceSq(point, center);
|
|
434
|
+
return d2 >= inner * inner && d2 <= outer * outer;
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Stratified 2D sampling: one jittered point per grid cell over `area`, in deterministic row-major
|
|
440
|
+
* order. Unlike pure rejection sampling this guarantees even coverage (no clumps, no gaps) — the
|
|
441
|
+
* distinct "stratified" distribution policy, kept separate from area-uniform draws.
|
|
442
|
+
*
|
|
443
|
+
* @capability spatial-sample-stratified evenly cover an area with one jittered point per grid cell, deterministic
|
|
444
|
+
*/
|
|
445
|
+
export function sampleStratified(options) {
|
|
446
|
+
const { area, rng } = options;
|
|
447
|
+
const cols = Math.max(0, Math.floor(options.cols));
|
|
448
|
+
const rows = Math.max(0, Math.floor(options.rows));
|
|
449
|
+
const width = area.maxX - area.minX;
|
|
450
|
+
const depth = area.maxZ - area.minZ;
|
|
451
|
+
if (cols === 0 || rows === 0 || !(width > 0) || !(depth > 0))
|
|
452
|
+
return [];
|
|
453
|
+
const jitter = Math.min(1, Math.max(0, options.jitter ?? 1));
|
|
454
|
+
const cellW = width / cols;
|
|
455
|
+
const cellD = depth / rows;
|
|
456
|
+
const points = [];
|
|
457
|
+
for (let row = 0; row < rows; row += 1) {
|
|
458
|
+
for (let col = 0; col < cols; col += 1) {
|
|
459
|
+
const jx = 0.5 + jitter * (rng() - 0.5);
|
|
460
|
+
const jz = 0.5 + jitter * (rng() - 0.5);
|
|
461
|
+
points.push([area.minX + (col + jx) * cellW, area.minZ + (row + jz) * cellD]);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return points;
|
|
465
|
+
}
|