@jgengine/core 0.9.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 +34 -3
- 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 +19 -1
- package/dist/ai/spawnDirector.js +53 -26
- package/dist/ai/spawnPoint.d.ts +7 -0
- package/dist/ai/spawnPoint.js +7 -0
- 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/audio/audioFalloff.d.ts +5 -2
- package/dist/audio/music.d.ts +53 -0
- package/dist/audio/music.js +34 -0
- package/dist/audio/synth.d.ts +60 -0
- package/dist/audio/synth.js +8 -0
- package/dist/authoring.d.ts +15 -0
- package/dist/authoring.js +15 -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 +47 -0
- package/dist/combat/dotField.js +52 -0
- 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 +7 -2
- package/dist/combat/projectiles.js +48 -17
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +39 -0
- package/dist/combat/regenShield.js +49 -0
- 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 +30 -1
- package/dist/combat/shotOrigin.js +70 -2
- 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 +248 -0
- package/dist/editor/commands.js +865 -0
- package/dist/editor/document.d.ts +186 -0
- package/dist/editor/document.js +884 -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 +97 -0
- package/dist/editor/index.js +10 -0
- 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 +175 -0
- package/dist/editor/types.js +29 -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/connectedPlayers.d.ts +30 -0
- package/dist/game/connectedPlayers.js +21 -0
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +141 -2
- package/dist/game/defineGame.js +39 -1
- 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 +50 -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/keyValueStore.d.ts +25 -0
- package/dist/game/keyValueStore.js +61 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/levelSequence.d.ts +24 -2
- package/dist/game/levelSequence.js +51 -2
- 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 +21 -0
- package/dist/game/lootTable.js +15 -4
- package/dist/game/modelAnimation.d.ts +8 -0
- package/dist/game/modelAnimation.js +18 -0
- 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 +160 -12
- 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 +5 -5
- 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 -7
- package/dist/index.js +5 -7
- package/dist/input/actionBindings.d.ts +24 -5
- package/dist/input/actionBindings.js +23 -5
- package/dist/input/axisInput.d.ts +13 -1
- package/dist/input/axisInput.js +22 -1
- 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/contextMenu.d.ts +1 -0
- package/dist/interaction/contextMenu.js +1 -0
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +5 -1
- package/dist/interaction/proximityPrompt.js +5 -3
- 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 +36 -1
- 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 +38 -7
- package/dist/movement/movementModel.js +54 -13
- package/dist/movement/playerMovement.d.ts +41 -0
- package/dist/movement/playerMovement.js +236 -0
- 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 +24 -0
- package/dist/random/rng.js +30 -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 +76 -0
- package/dist/render/postProcessing.js +21 -0
- 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 +58 -0
- package/dist/runtime/adapter.js +54 -5
- 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 +163 -19
- package/dist/runtime/gameContext.js +385 -339
- 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 +54 -0
- package/dist/runtime/hostedGameRunner.js +85 -0
- package/dist/runtime/hostedWorldSession.d.ts +73 -0
- package/dist/runtime/hostedWorldSession.js +64 -0
- package/dist/runtime/inputSnapshot.d.ts +21 -3
- package/dist/runtime/inputSnapshot.js +8 -2
- package/dist/runtime/motionIntents.d.ts +12 -1
- package/dist/runtime/motionIntents.js +26 -1
- 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 +62 -0
- package/dist/runtime/worldChannel.js +114 -0
- package/dist/runtime/worldMirror.d.ts +36 -0
- package/dist/runtime/worldMirror.js +44 -0
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +69 -0
- package/dist/runtime/worldReplication.js +217 -0
- package/dist/runtime/worldSnapshot.d.ts +44 -0
- package/dist/runtime/worldSnapshot.js +30 -0
- package/dist/scene/assetCatalog.d.ts +22 -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 +18 -0
- package/dist/scene/colliders.js +61 -1
- package/dist/scene/entityStats.d.ts +13 -0
- package/dist/scene/entityStats.js +30 -0
- package/dist/scene/entityStore.d.ts +41 -1
- package/dist/scene/entityStore.js +75 -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 +9 -0
- package/dist/store/observableKeyedStore.js +43 -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 +6 -4
- package/dist/tactics/fallingGrid.js +6 -4
- 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 +144 -0
- package/dist/ui/gameLayout.js +148 -0
- 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/orientation.d.ts +39 -0
- package/dist/ui/orientation.js +49 -0
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/swingTimer.d.ts +42 -0
- package/dist/ui/swingTimer.js +38 -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/visibility/spatialIndex.js +34 -20
- 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/environmentSummary.d.ts +11 -2
- package/dist/world/environmentSummary.js +11 -1
- package/dist/world/features.d.ts +244 -7
- package/dist/world/features.js +92 -4
- 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 +55 -0
- package/dist/world/roads.js +184 -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/streets.d.ts +80 -0
- package/dist/world/streets.js +144 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +655 -20
- package/dist/world/terrain.d.ts +138 -12
- package/dist/world/terrain.js +346 -28
- 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 -4983
package/dist/world/terrain.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { withPathProfiles } from "./pathTerrain.js";
|
|
2
|
+
import { nearestOnPath } from "./roads.js";
|
|
1
3
|
function clamp01(value) {
|
|
2
4
|
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
3
5
|
}
|
|
@@ -13,6 +15,9 @@ function hash2(ix, iz, seed) {
|
|
|
13
15
|
h ^= h >>> 12;
|
|
14
16
|
return (h >>> 0) / 4294967295;
|
|
15
17
|
}
|
|
18
|
+
/** Smoothly interpolated 2D value noise in `[-1, 1]` for the given seed.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
16
21
|
export function valueNoise(x, z, seed) {
|
|
17
22
|
const x0 = Math.floor(x);
|
|
18
23
|
const z0 = Math.floor(z);
|
|
@@ -28,6 +33,9 @@ export function valueNoise(x, z, seed) {
|
|
|
28
33
|
const bottom = lerp(v01, v11, sx);
|
|
29
34
|
return lerp(top, bottom, sz) * 2 - 1;
|
|
30
35
|
}
|
|
36
|
+
/** Layers `valueNoise` octaves per `config` into a single normalized noise sample.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
31
39
|
export function fractalNoise(x, z, config) {
|
|
32
40
|
let amplitude = 1;
|
|
33
41
|
let frequency = config.frequency;
|
|
@@ -44,6 +52,7 @@ export function fractalNoise(x, z, config) {
|
|
|
44
52
|
}
|
|
45
53
|
return norm === 0 ? 0 : sum / norm;
|
|
46
54
|
}
|
|
55
|
+
/** @internal */
|
|
47
56
|
export function seedFrom(value, fallback) {
|
|
48
57
|
if (typeof value === "number")
|
|
49
58
|
return value | 0;
|
|
@@ -57,6 +66,9 @@ export function seedFrom(value, fallback) {
|
|
|
57
66
|
}
|
|
58
67
|
return fallback;
|
|
59
68
|
}
|
|
69
|
+
/** Derives a `TerrainField.sampleNormal` from a height sampler via finite-difference gradients.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
60
72
|
export function withNormal(sampleHeight) {
|
|
61
73
|
const epsilon = 0.75;
|
|
62
74
|
return (x, z) => {
|
|
@@ -81,9 +93,15 @@ export const FLAT_FIELD = {
|
|
|
81
93
|
sampleHeight: () => 0,
|
|
82
94
|
sampleNormal: () => [0, 1, 0],
|
|
83
95
|
};
|
|
96
|
+
/** A flat, zero-height `TerrainField` for arenas with no elevation.
|
|
97
|
+
* @internal
|
|
98
|
+
*/
|
|
84
99
|
export function flatField() {
|
|
85
100
|
return FLAT_FIELD;
|
|
86
101
|
}
|
|
102
|
+
/** Builds a `TerrainField` whose height is fractal noise shaped by `config`.
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
87
105
|
export function noiseField(config = {}) {
|
|
88
106
|
const fractal = {
|
|
89
107
|
seed: seedFrom(config.seed, 1337),
|
|
@@ -100,6 +118,7 @@ export function noiseField(config = {}) {
|
|
|
100
118
|
waterLevel: config.waterLevel,
|
|
101
119
|
});
|
|
102
120
|
}
|
|
121
|
+
/** @internal */
|
|
103
122
|
export function rollingField(config = {}) {
|
|
104
123
|
return noiseField({
|
|
105
124
|
seed: config.seed ?? "rolling",
|
|
@@ -120,6 +139,9 @@ function smoothstep(edge0, edge1, value) {
|
|
|
120
139
|
const t = clamp01((value - edge0) / (edge1 - edge0));
|
|
121
140
|
return t * t * (3 - 2 * t);
|
|
122
141
|
}
|
|
142
|
+
/** Builds a `TerrainField` with a flat spawn plateau, rolling hills, and a basin, for combat arenas.
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
123
145
|
export function arenaField(config = {}) {
|
|
124
146
|
const seed = seedFrom(config.seed ?? "arena", 7);
|
|
125
147
|
const rolling = {
|
|
@@ -148,11 +170,18 @@ export function arenaField(config = {}) {
|
|
|
148
170
|
};
|
|
149
171
|
return fieldFromHeight(sampleHeight, { bounds: config.bounds, waterLevel: ARENA_WATER_LEVEL });
|
|
150
172
|
}
|
|
173
|
+
/** @internal */
|
|
151
174
|
export function groundFieldFor(world) {
|
|
152
175
|
if (world !== undefined && world.kind === "environment")
|
|
153
176
|
return resolveEnvironmentField(world);
|
|
154
177
|
return flatField();
|
|
155
178
|
}
|
|
179
|
+
/** Whether a world declares real terrain (base heightfield or islands) rather than a flat plane — gates terrain-floor sampling in the movement controllers.
|
|
180
|
+
* @internal
|
|
181
|
+
*/
|
|
182
|
+
export function hasEnvironmentTerrain(world) {
|
|
183
|
+
return world?.kind === "environment" && (world.terrain !== undefined || (world.islands?.length ?? 0) > 0);
|
|
184
|
+
}
|
|
156
185
|
/** Ground height between islands when no base terrain exists — deep enough to read as a fall into the void, finite so physics stays sane. */
|
|
157
186
|
export const ISLAND_VOID_HEIGHT = -256;
|
|
158
187
|
function islandContains(descriptor, x, z) {
|
|
@@ -163,7 +192,8 @@ function islandContains(descriptor, x, z) {
|
|
|
163
192
|
* Composes a base terrain and any number of bounded islands into one world field: inside an island's
|
|
164
193
|
* rect the island's own field (sampled in island-local coordinates) wins, elsewhere the base terrain
|
|
165
194
|
* answers, and with no base the gap is `ISLAND_VOID_HEIGHT` void. Later islands win overlaps.
|
|
166
|
-
|
|
195
|
+
* @internal
|
|
196
|
+
*/
|
|
167
197
|
export function composeIslandFields(base, islands, voidHeight = ISLAND_VOID_HEIGHT) {
|
|
168
198
|
if (islands.length === 0)
|
|
169
199
|
return base ?? flatField();
|
|
@@ -198,14 +228,95 @@ export function composeIslandFields(base, islands, voidHeight = ISLAND_VOID_HEIG
|
|
|
198
228
|
...(base?.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
|
|
199
229
|
};
|
|
200
230
|
}
|
|
201
|
-
/**
|
|
231
|
+
/** Bilinear offset sampled from an editor {@link TerraformSnapshot}'s vertex grid at a world point. */
|
|
232
|
+
function sampleSnapshotOffset(snapshot, x, z) {
|
|
233
|
+
const { bounds, cols, rows, offsets } = snapshot;
|
|
234
|
+
const vertsX = cols + 1;
|
|
235
|
+
const spanX = Math.max(bounds.maxX - bounds.minX, snapshot.cellSize);
|
|
236
|
+
const spanZ = Math.max(bounds.maxZ - bounds.minZ, snapshot.cellSize);
|
|
237
|
+
const fx = clamp01((x - bounds.minX) / spanX) * cols;
|
|
238
|
+
const fz = clamp01((z - bounds.minZ) / spanZ) * rows;
|
|
239
|
+
const x0 = Math.min(cols, Math.floor(fx));
|
|
240
|
+
const z0 = Math.min(rows, Math.floor(fz));
|
|
241
|
+
const x1 = Math.min(cols, x0 + 1);
|
|
242
|
+
const z1 = Math.min(rows, z0 + 1);
|
|
243
|
+
const tx = fx - x0;
|
|
244
|
+
const tz = fz - z0;
|
|
245
|
+
const v00 = offsets[z0 * vertsX + x0] ?? 0;
|
|
246
|
+
const v10 = offsets[z0 * vertsX + x1] ?? 0;
|
|
247
|
+
const v01 = offsets[z1 * vertsX + x0] ?? 0;
|
|
248
|
+
const v11 = offsets[z1 * vertsX + x1] ?? 0;
|
|
249
|
+
const top = v00 + (v10 - v00) * tx;
|
|
250
|
+
const bottom = v01 + (v11 - v01) * tx;
|
|
251
|
+
return top + (bottom - top) * tz;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Layers an authored sculpt snapshot's offsets over a base field — the editor-to-runtime ground seam.
|
|
255
|
+
* @internal — reached through `environment({ sculpt })`; not called directly by games.
|
|
256
|
+
*/
|
|
257
|
+
export function sculptedField(base, snapshot) {
|
|
258
|
+
const sampleHeight = (x, z) => base.sampleHeight(x, z) + sampleSnapshotOffset(snapshot, x, z);
|
|
259
|
+
return {
|
|
260
|
+
sampleHeight,
|
|
261
|
+
sampleNormal: withNormal(sampleHeight),
|
|
262
|
+
...(base.bounds === undefined ? {} : { bounds: base.bounds }),
|
|
263
|
+
...(base.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Levels a base field toward each clearance zone's center height within its radius (feathered) — so
|
|
268
|
+
* spawns, plots, and paths sit on flat ground even when a mound is nearby. The strongest overlapping
|
|
269
|
+
* zone wins. Pairs with scatter's avoid: one clearance zone both flattens ground and repels foliage.
|
|
270
|
+
* @internal — reached through `environment({ clearings })`; not called directly by games.
|
|
271
|
+
*/
|
|
272
|
+
export function flattenFieldAround(base, zones) {
|
|
273
|
+
if (zones.length === 0)
|
|
274
|
+
return base;
|
|
275
|
+
const sampleHeight = (x, z) => {
|
|
276
|
+
let best = 0;
|
|
277
|
+
let target = 0;
|
|
278
|
+
for (const zone of zones) {
|
|
279
|
+
const dist = Math.hypot(x - zone.x, z - zone.z);
|
|
280
|
+
if (dist >= zone.radius)
|
|
281
|
+
continue;
|
|
282
|
+
const feather = Math.max(0, zone.feather ?? 0);
|
|
283
|
+
const inner = zone.radius - feather;
|
|
284
|
+
const t = dist <= inner || feather <= 0 ? 1 : (zone.radius - dist) / feather;
|
|
285
|
+
if (t > best) {
|
|
286
|
+
best = t;
|
|
287
|
+
target = base.sampleHeight(zone.x, zone.z);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const height = base.sampleHeight(x, z);
|
|
291
|
+
return best > 0 ? height + (target - height) * best : height;
|
|
292
|
+
};
|
|
293
|
+
return {
|
|
294
|
+
sampleHeight,
|
|
295
|
+
sampleNormal: withNormal(sampleHeight),
|
|
296
|
+
...(base.bounds === undefined ? {} : { bounds: base.bounds }),
|
|
297
|
+
...(base.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* The full ground field for an environment world: base `terrain` composed with any `islands`, then
|
|
302
|
+
* any authored `sculpt` snapshot, then any `clearings` flattened on top — so an editor-sculpted
|
|
303
|
+
* heightfield drives both the rendered mesh and player collision, and gameplay spots stay level,
|
|
304
|
+
* through the one seam every consumer already reads.
|
|
305
|
+
* @internal
|
|
306
|
+
*/
|
|
202
307
|
export function resolveEnvironmentField(feature) {
|
|
203
308
|
const base = feature.terrain === undefined ? null : resolveTerrainField(feature.terrain);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
309
|
+
const composed = feature.islands === undefined || feature.islands.length === 0
|
|
310
|
+
? base ?? flatField()
|
|
311
|
+
: composeIslandFields(base, feature.islands);
|
|
312
|
+
const sculpted = feature.sculpt === undefined ? composed : sculptedField(composed, feature.sculpt);
|
|
313
|
+
return feature.clearings === undefined || feature.clearings.length === 0
|
|
314
|
+
? sculpted
|
|
315
|
+
: flattenFieldAround(sculpted, feature.clearings);
|
|
207
316
|
}
|
|
208
|
-
/** Local slope from the field's normal — the input for gravity-roll, ski acceleration, and slide checks (#284.6).
|
|
317
|
+
/** Local slope from the field's normal — the input for gravity-roll, ski acceleration, and slide checks (#284.6).
|
|
318
|
+
* @internal
|
|
319
|
+
*/
|
|
209
320
|
export function sampleSlope(field, x, z) {
|
|
210
321
|
const [nx, ny, nz] = field.sampleNormal(x, z);
|
|
211
322
|
const horizontal = Math.hypot(nx, nz);
|
|
@@ -219,7 +330,8 @@ export function sampleSlope(field, x, z) {
|
|
|
219
330
|
/**
|
|
220
331
|
* Downhill force/acceleration from the local slope: direction × sin(slope angle) × `scale`.
|
|
221
332
|
* Add it to any integrator's XZ velocity each tick (`scale` ≈ gravity for a free-rolling body).
|
|
222
|
-
|
|
333
|
+
* @internal
|
|
334
|
+
*/
|
|
223
335
|
export function slopeForce(field, x, z, scale = 9.8) {
|
|
224
336
|
const [nx, , nz] = field.sampleNormal(x, z);
|
|
225
337
|
if (Math.hypot(nx, nz) < 1e-9)
|
|
@@ -236,6 +348,46 @@ export const TERRAIN_MATERIAL_PALETTES = {
|
|
|
236
348
|
highland: { low: "#414f33", high: "#a3a86b", waterline: "#365f63" },
|
|
237
349
|
slate: { low: "#2f3540", high: "#7d8896", waterline: "#26404f" },
|
|
238
350
|
};
|
|
351
|
+
const DEFAULT_TERRAIN_DETAIL = {
|
|
352
|
+
rockColor: "#6f7175",
|
|
353
|
+
sandColor: "#c2b283",
|
|
354
|
+
snowColor: "#eef3f7",
|
|
355
|
+
rockSlopeStart: 0.42,
|
|
356
|
+
snowHeight: 26,
|
|
357
|
+
detailScale: 5,
|
|
358
|
+
macroScale: 45,
|
|
359
|
+
roughness: 0.9,
|
|
360
|
+
strength: 1,
|
|
361
|
+
};
|
|
362
|
+
const DEFAULT_TERRAIN_MATERIAL_REPEAT = 4;
|
|
363
|
+
const DEFAULT_TERRAIN_MATERIAL_STRENGTH = 1;
|
|
364
|
+
/** Fill a `TerrainDetailConfig` with defaults; `waterLevel` falls back to the terrain's own water level.
|
|
365
|
+
* @internal
|
|
366
|
+
*/
|
|
367
|
+
export function resolveTerrainDetail(config, terrainWaterLevel = 0) {
|
|
368
|
+
return {
|
|
369
|
+
rockColor: config.rockColor ?? DEFAULT_TERRAIN_DETAIL.rockColor,
|
|
370
|
+
sandColor: config.sandColor ?? DEFAULT_TERRAIN_DETAIL.sandColor,
|
|
371
|
+
snowColor: config.snowColor ?? DEFAULT_TERRAIN_DETAIL.snowColor,
|
|
372
|
+
rockSlopeStart: config.rockSlopeStart ?? DEFAULT_TERRAIN_DETAIL.rockSlopeStart,
|
|
373
|
+
snowHeight: config.snowHeight ?? DEFAULT_TERRAIN_DETAIL.snowHeight,
|
|
374
|
+
detailScale: config.detailScale ?? DEFAULT_TERRAIN_DETAIL.detailScale,
|
|
375
|
+
macroScale: config.macroScale ?? DEFAULT_TERRAIN_DETAIL.macroScale,
|
|
376
|
+
roughness: config.roughness ?? DEFAULT_TERRAIN_DETAIL.roughness,
|
|
377
|
+
strength: clamp01(config.strength ?? DEFAULT_TERRAIN_DETAIL.strength),
|
|
378
|
+
waterLevel: config.waterLevel ?? terrainWaterLevel,
|
|
379
|
+
...(config.material === undefined
|
|
380
|
+
? {}
|
|
381
|
+
: {
|
|
382
|
+
material: {
|
|
383
|
+
maps: config.material.maps,
|
|
384
|
+
repeat: config.material.repeat ?? DEFAULT_TERRAIN_MATERIAL_REPEAT,
|
|
385
|
+
strength: clamp01(config.material.strength ?? DEFAULT_TERRAIN_MATERIAL_STRENGTH),
|
|
386
|
+
},
|
|
387
|
+
}),
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
/** @internal */
|
|
239
391
|
export function resolveTerrainPalette(descriptor = {}) {
|
|
240
392
|
const material = descriptor.material ?? DEFAULT_TERRAIN_MATERIAL;
|
|
241
393
|
const preset = TERRAIN_MATERIAL_PALETTES[material];
|
|
@@ -277,36 +429,170 @@ function mixPalette(from, to, t) {
|
|
|
277
429
|
waterline: mixHex(from.waterline, to.waterline, t),
|
|
278
430
|
};
|
|
279
431
|
}
|
|
432
|
+
function createBandValueSampler(bands, fallback, resolve, mix) {
|
|
433
|
+
if (bands.length === 0)
|
|
434
|
+
return () => fallback;
|
|
435
|
+
const resolved = bands
|
|
436
|
+
.map((band) => ({ z: band.z, fade: band.fade ?? 64, value: resolve(band) }))
|
|
437
|
+
.sort((a, b) => a.z - b.z);
|
|
438
|
+
const first = resolved[0];
|
|
439
|
+
const last = resolved[resolved.length - 1];
|
|
440
|
+
return (z) => {
|
|
441
|
+
if (z <= first.z)
|
|
442
|
+
return first.value;
|
|
443
|
+
if (z >= last.z)
|
|
444
|
+
return last.value;
|
|
445
|
+
for (let i = 0; i < resolved.length - 1; i += 1) {
|
|
446
|
+
const lower = resolved[i];
|
|
447
|
+
const upper = resolved[i + 1];
|
|
448
|
+
if (z < lower.z || z > upper.z)
|
|
449
|
+
continue;
|
|
450
|
+
const boundary = (lower.z + upper.z) / 2;
|
|
451
|
+
const half = Math.min(lower.fade, upper.fade) / 2;
|
|
452
|
+
if (z <= boundary - half)
|
|
453
|
+
return lower.value;
|
|
454
|
+
if (z >= boundary + half)
|
|
455
|
+
return upper.value;
|
|
456
|
+
return mix(lower.value, upper.value, smoothstep(boundary - half, boundary + half, z));
|
|
457
|
+
}
|
|
458
|
+
return fallback;
|
|
459
|
+
};
|
|
460
|
+
}
|
|
280
461
|
/**
|
|
281
|
-
* Per-
|
|
282
|
-
* `
|
|
283
|
-
*
|
|
284
|
-
|
|
462
|
+
* Per-z palette sampler over a descriptor's `biomeBands` — ordered zones that cross-fade their
|
|
463
|
+
* ground palette across a `fade`-wide window centered on the midpoint z between adjacent centers.
|
|
464
|
+
* Below the first / above the last band clamps to that band's palette. Returns `fallback` when no
|
|
465
|
+
* bands are declared. Pure math, unit-testable independent of rendering.
|
|
466
|
+
* @internal
|
|
467
|
+
*/
|
|
468
|
+
export function createBiomeBandSampler(bands, fallback) {
|
|
469
|
+
return createBandValueSampler(bands, fallback, resolveTerrainPalette, mixPalette);
|
|
470
|
+
}
|
|
471
|
+
function mixBiomeFog(from, to, t) {
|
|
472
|
+
if (t <= 0)
|
|
473
|
+
return from;
|
|
474
|
+
if (t >= 1)
|
|
475
|
+
return to;
|
|
476
|
+
return {
|
|
477
|
+
color: mixHex(from.color, to.color, t),
|
|
478
|
+
near: lerp(from.near, to.near, t),
|
|
479
|
+
far: lerp(from.far, to.far, t),
|
|
480
|
+
density: lerp(from.density, to.density, t),
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Per-z fog sampler over a descriptor's `biomeBands` — cross-fades each band's `fog` (unset fields
|
|
485
|
+
* falling through to `fallback`) across the same `fade` window as the ground sampler, so fog color and
|
|
486
|
+
* range track the camera's z. Bands with no `fog` resolve to `fallback`. Pure math, unit-testable.
|
|
487
|
+
* @internal
|
|
488
|
+
*/
|
|
489
|
+
export function createBiomeFogSampler(bands, fallback) {
|
|
490
|
+
return createBandValueSampler(bands, fallback, (band) => band.fog === undefined
|
|
491
|
+
? fallback
|
|
492
|
+
: {
|
|
493
|
+
color: band.fog.color ?? fallback.color,
|
|
494
|
+
near: band.fog.near ?? fallback.near,
|
|
495
|
+
far: band.fog.far ?? fallback.far,
|
|
496
|
+
density: band.fog.density ?? fallback.density,
|
|
497
|
+
}, mixBiomeFog);
|
|
498
|
+
}
|
|
499
|
+
function mixBiomeSky(from, to, t) {
|
|
500
|
+
if (t <= 0)
|
|
501
|
+
return from;
|
|
502
|
+
if (t >= 1)
|
|
503
|
+
return to;
|
|
504
|
+
return {
|
|
505
|
+
horizonColor: mixHex(from.horizonColor, to.horizonColor, t),
|
|
506
|
+
zenithColor: mixHex(from.zenithColor, to.zenithColor, t),
|
|
507
|
+
sunIntensity: lerp(from.sunIntensity, to.sunIntensity, t),
|
|
508
|
+
ambientIntensity: lerp(from.ambientIntensity, to.ambientIntensity, t),
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Per-z sky sampler over a descriptor's `biomeBands` — cross-fades each band's `sky` (unset fields
|
|
513
|
+
* falling through to `fallback`) across the same `fade` window as the ground sampler, so horizon/zenith
|
|
514
|
+
* colors and sun/ambient intensity track the camera's z. Bands with no `sky` resolve to `fallback`.
|
|
515
|
+
* @internal
|
|
516
|
+
*/
|
|
517
|
+
export function createBiomeSkySampler(bands, fallback) {
|
|
518
|
+
return createBandValueSampler(bands, fallback, (band) => band.sky === undefined
|
|
519
|
+
? fallback
|
|
520
|
+
: {
|
|
521
|
+
horizonColor: band.sky.horizonColor ?? fallback.horizonColor,
|
|
522
|
+
zenithColor: band.sky.zenithColor ?? fallback.zenithColor,
|
|
523
|
+
sunIntensity: band.sky.sunIntensity ?? fallback.sunIntensity,
|
|
524
|
+
ambientIntensity: band.sky.ambientIntensity ?? fallback.ambientIntensity,
|
|
525
|
+
}, mixBiomeSky);
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Per-position palette sampler over the descriptor's base `material`/`colors` plus its z-ordered
|
|
529
|
+
* `biomeBands` (painted first) and radial `materialRegions` (painted over) — the multi-biome coloring
|
|
530
|
+
* seam. Regions paint fully inside `radius` and blend back across `falloff`; later regions win overlaps.
|
|
531
|
+
* @internal
|
|
532
|
+
*/
|
|
285
533
|
export function createTerrainPaletteSampler(descriptor) {
|
|
286
534
|
const base = resolveTerrainPalette(descriptor);
|
|
535
|
+
const bandSampler = descriptor.biomeBands === undefined || descriptor.biomeBands.length === 0
|
|
536
|
+
? null
|
|
537
|
+
: createBiomeBandSampler(descriptor.biomeBands, base);
|
|
287
538
|
const regions = (descriptor.materialRegions ?? []).map((region) => ({
|
|
288
|
-
|
|
289
|
-
radius: region.radius,
|
|
290
|
-
falloff: region.falloff ?? region.radius * 0.5,
|
|
539
|
+
...resolveRegionShape(region),
|
|
291
540
|
palette: resolveTerrainPalette(region),
|
|
292
541
|
}));
|
|
293
|
-
if (regions.length === 0)
|
|
542
|
+
if (regions.length === 0 && bandSampler === null)
|
|
294
543
|
return () => base;
|
|
295
544
|
return (x, z) => {
|
|
296
|
-
let palette = base;
|
|
545
|
+
let palette = bandSampler === null ? base : bandSampler(z);
|
|
297
546
|
for (const region of regions) {
|
|
298
|
-
const distance =
|
|
299
|
-
if (distance <=
|
|
547
|
+
const distance = region.coreDistance(x, z);
|
|
548
|
+
if (distance <= 0) {
|
|
300
549
|
palette = region.palette;
|
|
301
550
|
}
|
|
302
|
-
else if (distance <= region.
|
|
303
|
-
const t = smoothstep(
|
|
551
|
+
else if (distance <= region.falloff) {
|
|
552
|
+
const t = smoothstep(0, region.falloff, distance);
|
|
304
553
|
palette = mixPalette(region.palette, palette, t);
|
|
305
554
|
}
|
|
306
555
|
}
|
|
307
556
|
return palette;
|
|
308
557
|
};
|
|
309
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* Resolves a `TerrainMaterialRegion` of any shape to a `coreDistance(x, z)` — 0 inside the painted
|
|
561
|
+
* core, growing positive outward — plus its blend-ring `falloff`, so the palette sampler blends every
|
|
562
|
+
* shape through one shape-agnostic loop.
|
|
563
|
+
*/
|
|
564
|
+
function resolveRegionShape(region) {
|
|
565
|
+
if (region.shape === "polyline") {
|
|
566
|
+
const half = region.width * 0.5;
|
|
567
|
+
return {
|
|
568
|
+
falloff: region.falloff ?? half,
|
|
569
|
+
coreDistance: (x, z) => {
|
|
570
|
+
const sample = nearestOnPath(region.points, x, z);
|
|
571
|
+
return sample === null ? Number.POSITIVE_INFINITY : Math.max(0, sample.distance - half);
|
|
572
|
+
},
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
if (region.shape === "rect") {
|
|
576
|
+
const [hx, hz] = region.halfExtents;
|
|
577
|
+
const angle = region.rotationY ?? 0;
|
|
578
|
+
const cos = Math.cos(angle);
|
|
579
|
+
const sin = Math.sin(angle);
|
|
580
|
+
return {
|
|
581
|
+
falloff: region.falloff ?? Math.min(hx, hz) * 0.5,
|
|
582
|
+
coreDistance: (x, z) => {
|
|
583
|
+
const dx = x - region.center[0];
|
|
584
|
+
const dz = z - region.center[1];
|
|
585
|
+
const lx = dx * cos + dz * sin;
|
|
586
|
+
const lz = -dx * sin + dz * cos;
|
|
587
|
+
return Math.hypot(Math.max(0, Math.abs(lx) - hx), Math.max(0, Math.abs(lz) - hz));
|
|
588
|
+
},
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
return {
|
|
592
|
+
falloff: region.falloff ?? region.radius * 0.5,
|
|
593
|
+
coreDistance: (x, z) => Math.max(0, Math.hypot(x - region.center[0], z - region.center[1]) - region.radius),
|
|
594
|
+
};
|
|
595
|
+
}
|
|
310
596
|
function withFlattenMasks(sampleHeight, masks) {
|
|
311
597
|
const resolved = masks.map((mask) => ({
|
|
312
598
|
center: mask.center,
|
|
@@ -330,6 +616,7 @@ function withFlattenMasks(sampleHeight, masks) {
|
|
|
330
616
|
return height;
|
|
331
617
|
};
|
|
332
618
|
}
|
|
619
|
+
/** @internal */
|
|
333
620
|
export function heightMapField(config) {
|
|
334
621
|
const { columns, rows, samples } = config;
|
|
335
622
|
if (columns <= 0 || rows <= 0)
|
|
@@ -366,6 +653,9 @@ export function heightMapField(config) {
|
|
|
366
653
|
...(config.waterLevel === undefined ? {} : { waterLevel: config.waterLevel }),
|
|
367
654
|
});
|
|
368
655
|
}
|
|
656
|
+
/** Resolves a `TerrainEnvironmentDescriptor` into a concrete `TerrainField`, applying flatten masks.
|
|
657
|
+
* @internal
|
|
658
|
+
*/
|
|
369
659
|
export function resolveTerrainField(descriptor) {
|
|
370
660
|
if (descriptor === undefined)
|
|
371
661
|
return flatField();
|
|
@@ -387,19 +677,44 @@ export function resolveTerrainField(descriptor) {
|
|
|
387
677
|
waterLevel: descriptor.waterLevel,
|
|
388
678
|
bounds: descriptor.bounds,
|
|
389
679
|
});
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
680
|
+
const flattened = descriptor.flatten === undefined || descriptor.flatten.length === 0
|
|
681
|
+
? base
|
|
682
|
+
: fieldFromHeight(withFlattenMasks(base.sampleHeight, descriptor.flatten), {
|
|
683
|
+
bounds: base.bounds,
|
|
684
|
+
waterLevel: base.waterLevel,
|
|
685
|
+
});
|
|
686
|
+
if (descriptor.pathProfiles === undefined || descriptor.pathProfiles.length === 0)
|
|
687
|
+
return flattened;
|
|
688
|
+
return applyPathProfiles(flattened, descriptor.pathProfiles);
|
|
396
689
|
}
|
|
397
|
-
/**
|
|
690
|
+
/**
|
|
691
|
+
* Composes authored path profiles onto a field — the shared seam that turns a scene road/river/ramp path
|
|
692
|
+
* into flattened, graded, carved, or retained ground. Applies after `flatten` masks in `resolveTerrainField`
|
|
693
|
+
* so a corridor grades over already-leveled pads; call it directly to layer profiles onto any field a game
|
|
694
|
+
* builds by hand. Returns the field unchanged when no profile is given.
|
|
695
|
+
* @capability path-terrain apply flatten/grade/carve/retaining path profiles to a terrain field
|
|
696
|
+
*/
|
|
697
|
+
export function applyPathProfiles(field, profiles) {
|
|
698
|
+
if (profiles.length === 0)
|
|
699
|
+
return field;
|
|
700
|
+
const sampleHeight = withPathProfiles((x, z) => field.sampleHeight(x, z), profiles);
|
|
701
|
+
return {
|
|
702
|
+
sampleHeight,
|
|
703
|
+
sampleNormal: withNormal(sampleHeight),
|
|
704
|
+
...(field.bounds === undefined ? {} : { bounds: field.bounds }),
|
|
705
|
+
...(field.waterLevel === undefined ? {} : { waterLevel: field.waterLevel }),
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
/** Returns `position` with `y` replaced by the field's ground height (plus `offset`) at its `x`/`z`.
|
|
709
|
+
* @internal
|
|
710
|
+
*/
|
|
398
711
|
export function snapToGround(field, position, offset = 0) {
|
|
399
712
|
const [x, , z] = position;
|
|
400
713
|
return [x, field.sampleHeight(x, z) + offset, z];
|
|
401
714
|
}
|
|
402
|
-
/** Ground-snaps an already-spawned entity in place; returns false when `id` is unknown.
|
|
715
|
+
/** Ground-snaps an already-spawned entity in place; returns false when `id` is unknown.
|
|
716
|
+
* @internal
|
|
717
|
+
*/
|
|
403
718
|
export function snapEntityToGround(entities, id, field, offset = 0) {
|
|
404
719
|
const entity = entities.get(id);
|
|
405
720
|
if (entity === null)
|
|
@@ -407,6 +722,9 @@ export function snapEntityToGround(entities, id, field, offset = 0) {
|
|
|
407
722
|
return entities.setPose(id, { position: snapToGround(field, entity.position, offset) });
|
|
408
723
|
}
|
|
409
724
|
export const DEFAULT_MAX_WALK_SLOPE = 0.6;
|
|
725
|
+
/** Zeroes out a movement step's x or z component where it would climb steeper than `maxSlope`.
|
|
726
|
+
* @internal
|
|
727
|
+
*/
|
|
410
728
|
export function resolveGroundStep(field, x, z, stepX, stepZ, maxSlope = DEFAULT_MAX_WALK_SLOPE) {
|
|
411
729
|
const baseHeight = field.sampleHeight(x, z);
|
|
412
730
|
const tooSteep = (dx, dz) => {
|