@jgengine/core 0.18.1 → 0.21.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 +504 -7
- package/dist/ai/decisionGraph.d.ts +50 -4
- package/dist/ai/decisionGraph.js +159 -23
- package/dist/ai/flock.d.ts +1 -1
- package/dist/ai/flock.js +7 -4
- package/dist/ai/groupAssist.d.ts +10 -0
- package/dist/ai/groupAssist.js +11 -0
- package/dist/ai/pursuit.d.ts +1 -1
- package/dist/ai/pursuit.js +1 -1
- package/dist/ai/threat.d.ts +8 -0
- package/dist/ai/threat.js +10 -0
- package/dist/anim/animGraph.d.ts +43 -1
- package/dist/anim/animGraph.js +326 -10
- package/dist/anim/boneTexture.d.ts +55 -0
- package/dist/anim/boneTexture.js +43 -0
- package/dist/anim/footPlacement.d.ts +57 -0
- package/dist/anim/footPlacement.js +67 -0
- package/dist/anim/locomotionGraph.d.ts +18 -1
- package/dist/anim/locomotionGraph.js +42 -3
- package/dist/audio/audioFalloff.d.ts +6 -0
- package/dist/audio/doppler.d.ts +21 -0
- package/dist/audio/doppler.js +32 -0
- package/dist/audio/engineLayers.d.ts +83 -0
- package/dist/audio/engineLayers.js +115 -0
- package/dist/audio/voiceAllocator.d.ts +46 -0
- package/dist/audio/voiceAllocator.js +76 -0
- package/dist/combat/abilityKit.d.ts +20 -0
- package/dist/combat/abilityKit.js +41 -4
- package/dist/combat/death.d.ts +11 -3
- package/dist/combat/death.js +3 -3
- package/dist/combat/magazine.d.ts +9 -0
- package/dist/combat/magazine.js +24 -2
- package/dist/combat/projectiles.d.ts +94 -2
- package/dist/combat/projectiles.js +282 -61
- package/dist/combat/regenShield.d.ts +14 -0
- package/dist/combat/regenShield.js +23 -7
- package/dist/combat/shotOrigin.d.ts +6 -0
- package/dist/combat/shotOrigin.js +6 -0
- package/dist/combat/weaponFeedback.d.ts +36 -0
- package/dist/combat/weaponFeedback.js +42 -0
- package/dist/combat/weaponHandling.d.ts +161 -0
- package/dist/combat/weaponHandling.js +202 -0
- package/dist/combat/weaponPresentation.d.ts +115 -0
- package/dist/combat/weaponPresentation.js +96 -0
- package/dist/crafting/recipeCatalog.d.ts +16 -0
- package/dist/crafting/recipeCatalog.js +55 -0
- package/dist/devtools/warnOnce.d.ts +8 -0
- package/dist/devtools/warnOnce.js +18 -0
- package/dist/economy/auctionBook.d.ts +1 -1
- package/dist/economy/auctionBook.js +11 -1
- package/dist/economy/listingBook.d.ts +1 -1
- package/dist/economy/listingBook.js +11 -1
- package/dist/economy/resourceLedger.js +3 -3
- package/dist/economy/shopStock.js +7 -6
- package/dist/economy/techTree.js +7 -6
- package/dist/economy/unlockPoints.js +3 -6
- package/dist/editor/commandApply.js +89 -16
- package/dist/editor/commands.d.ts +38 -1
- package/dist/editor/commands.js +320 -3
- package/dist/editor/creatorStorage.d.ts +59 -0
- package/dist/editor/creatorStorage.js +164 -0
- package/dist/editor/document.d.ts +4 -0
- package/dist/editor/document.js +119 -18
- package/dist/editor/environment.js +8 -0
- package/dist/editor/index.d.ts +2 -0
- package/dist/editor/liveSync.d.ts +4 -1
- package/dist/editor/liveSync.js +26 -10
- package/dist/editor/materialAuthoring.d.ts +14 -0
- package/dist/editor/materialAuthoring.js +38 -0
- package/dist/editor/modelNodeVisibility.d.ts +11 -0
- package/dist/editor/modelNodeVisibility.js +29 -0
- package/dist/editor/movementCatalog.d.ts +90 -0
- package/dist/editor/movementCatalog.js +144 -0
- package/dist/editor/simulation.d.ts +60 -0
- package/dist/editor/simulation.js +202 -0
- package/dist/editor/staticPrefab.d.ts +17 -0
- package/dist/editor/staticPrefab.js +51 -0
- package/dist/editor/types.d.ts +15 -0
- package/dist/faction/reputation.d.ts +6 -0
- package/dist/faction/reputation.js +11 -0
- package/dist/game/cameraConfig.d.ts +54 -2
- package/dist/game/clipRoles.d.ts +2 -1
- package/dist/game/clipRoles.js +7 -3
- package/dist/game/contentValidation.d.ts +69 -0
- package/dist/game/contentValidation.js +118 -0
- package/dist/game/controlGate.d.ts +8 -0
- package/dist/game/controlGate.js +43 -6
- package/dist/game/defineGame.d.ts +32 -3
- package/dist/game/dialogueGraph.d.ts +20 -0
- package/dist/game/dialogueGraph.js +107 -0
- package/dist/game/events.d.ts +11 -0
- package/dist/game/keyValueStore.d.ts +17 -4
- package/dist/game/keyValueStore.js +35 -23
- package/dist/game/lootModifiers.d.ts +17 -0
- package/dist/game/lootModifiers.js +26 -0
- package/dist/game/lootTable.d.ts +4 -0
- package/dist/game/lootTable.js +16 -0
- package/dist/game/narrativeAuthoring.d.ts +67 -0
- package/dist/game/narrativeAuthoring.js +122 -0
- package/dist/game/playableGame.d.ts +134 -35
- package/dist/game/quest.d.ts +15 -0
- package/dist/game/quest.js +209 -63
- package/dist/game/questCatalog.d.ts +50 -0
- package/dist/game/questCatalog.js +205 -0
- package/dist/game/saveStore.d.ts +6 -5
- package/dist/game/saveStore.js +57 -57
- package/dist/game/systemRuntime.d.ts +2 -2
- package/dist/game/systemRuntime.js +84 -33
- package/dist/game/toasts.d.ts +8 -0
- package/dist/game/toasts.js +7 -0
- package/dist/game/vfxInstance.d.ts +9 -0
- package/dist/game/vfxInstance.js +12 -1
- package/dist/game/viewports.d.ts +43 -0
- package/dist/game/viewports.js +46 -0
- package/dist/game/worldItem.d.ts +5 -1
- package/dist/game/worldItem.js +0 -1
- package/dist/gameplay.d.ts +3 -0
- package/dist/gameplay.js +3 -0
- package/dist/input/actionBindings.d.ts +15 -1
- package/dist/input/actionBindings.js +14 -3
- package/dist/input/actionContexts.d.ts +25 -1
- package/dist/input/actionContexts.js +82 -25
- package/dist/input/axisInput.d.ts +4 -0
- package/dist/input/axisInput.js +4 -0
- package/dist/input/axisShaper.d.ts +73 -0
- package/dist/input/axisShaper.js +105 -0
- package/dist/input/gamepadModel.d.ts +36 -2
- package/dist/input/gamepadModel.js +69 -30
- package/dist/input/haptics.d.ts +50 -0
- package/dist/input/haptics.js +74 -0
- package/dist/input/inputBuffer.d.ts +40 -0
- package/dist/input/inputBuffer.js +59 -0
- package/dist/input/lookChannel.d.ts +10 -0
- package/dist/input/lookChannel.js +6 -0
- package/dist/input/pointer.d.ts +2 -0
- package/dist/input/pointer.js +4 -0
- package/dist/interaction/promptRegistry.d.ts +5 -4
- package/dist/interaction/promptRegistry.js +8 -2
- package/dist/inventory/inventoryModel.js +9 -6
- package/dist/inventory/shapedGrid.d.ts +48 -9
- package/dist/inventory/shapedGrid.js +69 -10
- package/dist/item/affix.d.ts +6 -0
- package/dist/item/affix.js +6 -0
- package/dist/item/durability.js +4 -0
- package/dist/item/itemInstanceRegistry.d.ts +32 -1
- package/dist/item/itemInstanceRegistry.js +111 -7
- package/dist/item/itemgen.d.ts +1 -1
- package/dist/item/itemgen.js +1 -1
- package/dist/item/modularItem.js +7 -1
- package/dist/material/appearanceSignals.d.ts +53 -0
- package/dist/material/appearanceSignals.js +47 -0
- package/dist/material/hairCards.d.ts +47 -0
- package/dist/material/hairCards.js +136 -0
- package/dist/material/materialAsset.d.ts +162 -0
- package/dist/material/materialAsset.js +382 -0
- package/dist/meta/changelog.d.ts +1 -1
- package/dist/meta/changelog.js +444 -1
- package/dist/movement/characterController.d.ts +5 -2
- package/dist/movement/characterController.js +50 -23
- package/dist/movement/freeFlight.d.ts +2 -2
- package/dist/movement/freeFlight.js +3 -3
- package/dist/movement/glideModel.d.ts +3 -0
- package/dist/movement/glideModel.js +6 -0
- package/dist/movement/grappleSwing.d.ts +2 -0
- package/dist/movement/grappleSwing.js +5 -1
- package/dist/movement/movementModel.d.ts +63 -1
- package/dist/movement/movementModel.js +136 -26
- package/dist/movement/movementProbe.d.ts +51 -0
- package/dist/movement/movementProbe.js +119 -0
- package/dist/movement/playerMovement.d.ts +48 -2
- package/dist/movement/playerMovement.js +493 -87
- package/dist/movement/poseState.d.ts +2 -0
- package/dist/movement/poseState.js +29 -1
- package/dist/movement/solidObstacles.d.ts +11 -1
- package/dist/movement/solidObstacles.js +48 -3
- package/dist/movement/terrainGrade.d.ts +13 -0
- package/dist/movement/terrainGrade.js +33 -0
- package/dist/movement/voxelController.d.ts +2 -2
- package/dist/movement/voxelController.js +10 -10
- package/dist/nav/navFromEnvironment.d.ts +9 -3
- package/dist/nav/navFromEnvironment.js +18 -12
- package/dist/nav/navGrid.d.ts +19 -1
- package/dist/nav/navGrid.js +26 -10
- package/dist/nav/navMesh.d.ts +43 -2
- package/dist/nav/navMesh.js +534 -128
- package/dist/nav/solidRoute.d.ts +50 -0
- package/dist/nav/solidRoute.js +144 -0
- package/dist/physics/aircraftDynamics.d.ts +390 -0
- package/dist/physics/aircraftDynamics.js +704 -0
- package/dist/physics/ballisticSweep.d.ts +10 -3
- package/dist/physics/ballisticSweep.js +53 -29
- package/dist/physics/boatDynamics.d.ts +116 -0
- package/dist/physics/boatDynamics.js +160 -0
- package/dist/physics/drivableVehicle.d.ts +22 -8
- package/dist/physics/drivableVehicle.js +4 -2
- package/dist/physics/flightDynamics.d.ts +21 -4
- package/dist/physics/flightDynamics.js +28 -5
- package/dist/physics/forceVolume.d.ts +41 -0
- package/dist/physics/forceVolume.js +88 -0
- package/dist/physics/handlingProbe.d.ts +249 -0
- package/dist/physics/handlingProbe.js +606 -0
- package/dist/physics/kinematicVehicle.d.ts +40 -5
- package/dist/physics/kinematicVehicle.js +17 -2
- package/dist/physics/physicsBackend.d.ts +12 -0
- package/dist/physics/physicsBackendConformance.js +34 -0
- package/dist/physics/physicsWorldBackend.d.ts +1 -0
- package/dist/physics/physicsWorldBackend.js +52 -3
- package/dist/physics/spatialGrid.d.ts +1 -1
- package/dist/physics/spatialGrid.js +8 -9
- package/dist/physics/vehicleBackendLink.d.ts +49 -0
- package/dist/physics/vehicleBackendLink.js +102 -0
- package/dist/physics/vehicleDynamics.d.ts +375 -0
- package/dist/physics/vehicleDynamics.js +737 -0
- package/dist/physics/vehicleObstacles.d.ts +3 -2
- package/dist/physics/vehicleObstacles.js +29 -5
- package/dist/physics/worldColliders.d.ts +1 -1
- package/dist/physics/worldColliders.js +35 -3
- package/dist/puzzle/cellGrid.d.ts +15 -9
- package/dist/puzzle/cellGrid.js +13 -9
- package/dist/render/lookPreset.d.ts +9 -2
- package/dist/render/lookPreset.js +29 -2
- package/dist/render/postProcessing.d.ts +30 -0
- package/dist/render/postProcessing.js +1 -1
- package/dist/runtime/cameraDirector.d.ts +54 -3
- package/dist/runtime/cameraDirector.js +187 -0
- package/dist/runtime/commandDispatch.d.ts +14 -0
- package/dist/runtime/commandDispatch.js +19 -0
- package/dist/runtime/commandInput.d.ts +37 -0
- package/dist/runtime/commandInput.js +58 -0
- package/dist/runtime/commandRunner.d.ts +27 -0
- package/dist/runtime/commandRunner.js +31 -3
- package/dist/runtime/context/combat.d.ts +12 -4
- package/dist/runtime/context/combat.js +179 -11
- package/dist/runtime/context/deathLoot.d.ts +11 -8
- package/dist/runtime/context/deathLoot.js +17 -16
- package/dist/runtime/context/scene.d.ts +2 -0
- package/dist/runtime/context/scene.js +13 -21
- package/dist/runtime/descriptors/baseline.js +34 -3
- package/dist/runtime/descriptors/features.d.ts +2 -1
- package/dist/runtime/descriptors/features.js +18 -0
- package/dist/runtime/gameContext.js +86 -13
- package/dist/runtime/gameContextTypes.d.ts +33 -3
- package/dist/runtime/gameRuntime.d.ts +3 -1
- package/dist/runtime/gameRuntime.js +4 -0
- package/dist/runtime/headlessRunner.d.ts +3 -1
- package/dist/runtime/headlessRunner.js +11 -11
- package/dist/runtime/hostedGameRunner.d.ts +24 -1
- package/dist/runtime/hostedGameRunner.js +156 -10
- package/dist/runtime/hostedWorldSession.d.ts +17 -5
- package/dist/runtime/hostedWorldSession.js +154 -16
- package/dist/runtime/hostedWorldStore.d.ts +2 -2
- package/dist/runtime/inputRecorder.d.ts +1 -1
- package/dist/runtime/inputRecorder.js +21 -1
- package/dist/runtime/inputSnapshot.d.ts +22 -4
- package/dist/runtime/inputSnapshot.js +41 -3
- package/dist/runtime/localPlayers.d.ts +73 -0
- package/dist/runtime/localPlayers.js +119 -0
- package/dist/runtime/runtimeSave.d.ts +10 -6
- package/dist/runtime/runtimeSave.js +11 -5
- package/dist/runtime/simContext.d.ts +8 -3
- package/dist/runtime/simContext.js +7 -3
- package/dist/runtime/simSnapshot.js +2 -0
- package/dist/runtime/transport.d.ts +9 -0
- package/dist/runtime/transport.js +7 -1
- package/dist/runtime/worldReplication.d.ts +2 -0
- package/dist/runtime/worldReplication.js +1 -1
- package/dist/scene/assetCatalog.d.ts +2 -0
- package/dist/scene/behaviorRuntime.d.ts +38 -7
- package/dist/scene/behaviorRuntime.js +293 -30
- package/dist/scene/behaviors.d.ts +35 -2
- package/dist/scene/behaviors.js +29 -0
- package/dist/scene/entityStore.d.ts +14 -3
- package/dist/scene/entityStore.js +45 -9
- package/dist/scene/mount.d.ts +9 -0
- package/dist/scene/mount.js +35 -0
- package/dist/scene/possession.d.ts +2 -0
- package/dist/scene/possession.js +21 -1
- package/dist/scene/sceneKinds.d.ts +9 -0
- package/dist/scene/sceneRaycast.d.ts +7 -0
- package/dist/scene/sceneRaycast.js +55 -0
- package/dist/scene/spatial.d.ts +20 -1
- package/dist/scene/spatial.js +94 -2
- package/dist/scene/vehicleSeat.d.ts +41 -3
- package/dist/scene/vehicleSeat.js +94 -3
- package/dist/sensor/concealment.d.ts +6 -0
- package/dist/sensor/concealment.js +8 -0
- package/dist/sensor/freezeMonitor.d.ts +6 -0
- package/dist/sensor/freezeMonitor.js +8 -0
- package/dist/sensor/perception.d.ts +11 -1
- package/dist/sensor/perception.js +57 -10
- package/dist/sensor/recordingBuffer.d.ts +3 -0
- package/dist/sensor/recordingBuffer.js +8 -0
- package/dist/session/roundState.d.ts +4 -0
- package/dist/session/roundState.js +11 -0
- package/dist/settings/frameRateLimit.d.ts +16 -0
- package/dist/settings/frameRateLimit.js +37 -0
- package/dist/settings/graphicsProfile.d.ts +2 -0
- package/dist/settings/graphicsProfile.js +12 -0
- package/dist/settings/graphicsSettings.d.ts +40 -0
- package/dist/settings/graphicsSettings.js +81 -0
- package/dist/settings/settingsModel.d.ts +9 -1
- package/dist/settings/settingsModel.js +10 -0
- package/dist/stats/accumulatorMeter.d.ts +10 -0
- package/dist/stats/accumulatorMeter.js +6 -0
- package/dist/stats/eventMeter.d.ts +10 -3
- package/dist/stats/eventMeter.js +6 -3
- package/dist/store/defineStore.d.ts +3 -1
- package/dist/store/defineStore.js +3 -1
- package/dist/store/observableKeyedStore.d.ts +1 -1
- package/dist/store/observableKeyedStore.js +8 -6
- package/dist/time/simClock.d.ts +6 -2
- package/dist/time/simClock.js +5 -0
- package/dist/vfx/feedbackMixer.d.ts +61 -0
- package/dist/vfx/feedbackMixer.js +106 -0
- package/dist/vfx/particleDirector.d.ts +58 -6
- package/dist/vfx/particleDirector.js +113 -22
- package/dist/vfx/particles.d.ts +68 -5
- package/dist/vfx/particles.js +284 -32
- package/dist/visibility/assetStreaming.d.ts +21 -3
- package/dist/visibility/assetStreaming.js +108 -24
- package/dist/visibility/settings.d.ts +8 -2
- package/dist/visibility/settings.js +3 -0
- package/dist/visibility/simulationCulling.d.ts +8 -1
- package/dist/visibility/simulationCulling.js +7 -0
- package/dist/visibility/spatialIndex.d.ts +21 -0
- package/dist/visibility/spatialIndex.js +16 -0
- package/dist/visibility/visibilitySystem.js +1 -0
- package/dist/work/expedition.d.ts +110 -0
- package/dist/work/expedition.js +195 -0
- package/dist/work/staffedStation.d.ts +29 -0
- package/dist/work/staffedStation.js +27 -0
- package/dist/world/authoredAnimation.d.ts +38 -0
- package/dist/world/authoredAnimation.js +99 -0
- package/dist/world/authoredObjects.d.ts +24 -4
- package/dist/world/authoredObjects.js +43 -16
- package/dist/world/authoredSimulation.d.ts +74 -0
- package/dist/world/authoredSimulation.js +302 -0
- package/dist/world/authoredSolids.d.ts +46 -0
- package/dist/world/authoredSolids.js +75 -0
- package/dist/world/authoredWeather.d.ts +120 -0
- package/dist/world/authoredWeather.js +314 -0
- package/dist/world/buildingGenerator.js +2 -2
- package/dist/world/buildingKit.d.ts +11 -4
- package/dist/world/buildingKit.js +21 -8
- package/dist/world/buildings.d.ts +34 -2
- package/dist/world/buildings.js +11 -1
- package/dist/world/cityKind.d.ts +7 -0
- package/dist/world/cityKind.js +52 -1
- package/dist/world/environmentForces.d.ts +21 -0
- package/dist/world/environmentForces.js +42 -0
- package/dist/world/features.d.ts +32 -5
- package/dist/world/features.js +6 -0
- package/dist/world/footprintGrid.d.ts +62 -0
- package/dist/world/footprintGrid.js +217 -0
- package/dist/world/interiors.d.ts +1 -0
- package/dist/world/interiors.js +5 -3
- package/dist/world/lod.d.ts +6 -0
- package/dist/world/lod.js +8 -0
- package/dist/world/pathTerrain.d.ts +1 -1
- package/dist/world/terraform.d.ts +9 -1
- package/dist/world/terraform.js +53 -18
- package/dist/world/walls.d.ts +7 -0
- package/dist/world/walls.js +7 -0
- package/dist/world/weather.d.ts +17 -0
- package/dist/world/weather.js +116 -20
- package/dist/world/worldSolids.d.ts +95 -0
- package/dist/world/worldSolids.js +351 -0
- package/dist/world.d.ts +6 -6
- package/dist/world.js +5 -5
- package/package.json +1 -1
- package/skills/ce-handoff/SKILL.md +2 -2
- package/skills/game-design/SKILL.md +2 -2
- package/skills/jgengine/SKILL.md +28 -6
- package/skills/jgengine/api.md +139 -99
- package/skills/jgengine/capabilities.md +28 -0
- package/skills/jgengine/recipes/minimal-game.md +10 -2
- package/skills/jgengine-combat/SKILL.md +13 -2
- package/skills/jgengine-combat/api.md +150 -103
- package/skills/jgengine-combat/capabilities.md +29 -1
- package/skills/jgengine-combat/recipes/portable-runtime-state.md +60 -6
- package/skills/jgengine-combat/recipes/portable-weapon-plumbing.md +37 -3
- package/skills/jgengine-combat/recipes/weapon-feel.md +50 -0
- package/skills/jgengine-combat/reference.md +24 -2
- package/skills/jgengine-gameplay/SKILL.md +63 -0
- package/skills/jgengine-gameplay/api.md +583 -463
- package/skills/jgengine-gameplay/capabilities.md +92 -0
- package/skills/jgengine-gameplay/recipes/device-save-status.md +46 -0
- package/skills/jgengine-gameplay/recipes/expeditions.md +108 -0
- package/skills/jgengine-gameplay/recipes/narrative-authoring.md +76 -0
- package/skills/jgengine-gameplay/recipes/paged-item-storage.md +101 -0
- package/skills/jgengine-gameplay/recipes/quest-authoring.md +63 -0
- package/skills/jgengine-gameplay/recipes/shaped-inventory.md +50 -0
- package/skills/jgengine-gameplay/reference-content-validation.md +74 -0
- package/skills/jgengine-gameplay/reference-systems.md +123 -0
- package/skills/jgengine-world/SKILL.md +25 -4
- package/skills/jgengine-world/api.md +1045 -655
- package/skills/jgengine-world/capabilities.md +246 -9
- package/skills/jgengine-world/recipes/character-animation.md +62 -0
- package/skills/jgengine-world/recipes/controls.md +48 -0
- package/skills/jgengine-world/recipes/flight-feel.md +76 -0
- package/skills/jgengine-world/recipes/npc-senses.md +55 -0
- package/skills/jgengine-world/recipes/vehicle-feel.md +87 -0
- package/skills/jgengine-world/reference.md +180 -4
- package/skills/jgengine-world/visibility.md +139 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { createInputBuffer } from "../input/inputBuffer.js";
|
|
2
|
+
import { advancePlayerMotion, createEmptyMovementKeys, createPlayerMotionState, resolveMovementIntent, } from "./movementModel.js";
|
|
3
|
+
import { resolvePlayerMovementTuning } from "./playerMovement.js";
|
|
4
|
+
const ARRIVED = 0.9;
|
|
5
|
+
const STOPPED = 0.05;
|
|
6
|
+
const SETTLE_SECONDS = 5;
|
|
7
|
+
const LIMIT_SECONDS = 10;
|
|
8
|
+
function held(keys) {
|
|
9
|
+
return resolveMovementIntent({ ...createEmptyMovementKeys(), ...keys }, true);
|
|
10
|
+
}
|
|
11
|
+
function speedOf(motion) {
|
|
12
|
+
return Math.hypot(motion.horizontalVelocityX, motion.horizontalVelocityZ);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Drives a walk character through fixed scenarios (standing start, release to stop, reversal, a standing
|
|
16
|
+
* jump, a tapped jump, a strafed jump) on the same integrator `stepPlayerMovement` uses, and reports the feel metrics a
|
|
17
|
+
* test can assert. Deterministic: the same subject and options always produce the same report, so a feel
|
|
18
|
+
* change shows up as a number moving. Collision, terrain and swimming are out of scope; it measures flat ground.
|
|
19
|
+
* @capability movement-metrics measure a walking character's feel as numbers — time to top speed, stop distance, jump height and apex, air control, turn-around
|
|
20
|
+
*/
|
|
21
|
+
export function measureMovement(subject = {}, options = {}) {
|
|
22
|
+
const dt = options.dt ?? 1 / 60;
|
|
23
|
+
const sprint = options.sprint === true;
|
|
24
|
+
const walkSpeed = subject.walkSpeed ?? 2;
|
|
25
|
+
const tuning = resolvePlayerMovementTuning({
|
|
26
|
+
...(subject.movement === undefined ? {} : { movement: subject.movement }),
|
|
27
|
+
...(subject.physics === undefined ? {} : { physics: subject.physics }),
|
|
28
|
+
}).physics;
|
|
29
|
+
const buffer = createInputBuffer({ windowMs: 0 });
|
|
30
|
+
const step = (motion, intent, forwardZ = 1, forwardX = 0) => advancePlayerMotion(motion, intent, forwardX, forwardZ, walkSpeed, dt, tuning, { buffer });
|
|
31
|
+
const forward = held({ w: true, shift: sprint });
|
|
32
|
+
const idle = held({});
|
|
33
|
+
const ticks = (seconds) => Math.ceil(seconds / dt);
|
|
34
|
+
const fresh = () => {
|
|
35
|
+
buffer.restore({ windowMs: 0, actions: {} });
|
|
36
|
+
return createPlayerMotionState();
|
|
37
|
+
};
|
|
38
|
+
const settled = () => {
|
|
39
|
+
const motion = fresh();
|
|
40
|
+
for (let i = 0; i < ticks(SETTLE_SECONDS); i += 1)
|
|
41
|
+
step(motion, forward);
|
|
42
|
+
return motion;
|
|
43
|
+
};
|
|
44
|
+
const topSpeed = speedOf(settled());
|
|
45
|
+
let timeToTopSpeed = Number.POSITIVE_INFINITY;
|
|
46
|
+
{
|
|
47
|
+
const motion = fresh();
|
|
48
|
+
for (let i = 1; i <= ticks(LIMIT_SECONDS); i += 1) {
|
|
49
|
+
step(motion, forward);
|
|
50
|
+
if (speedOf(motion) >= topSpeed * ARRIVED) {
|
|
51
|
+
timeToTopSpeed = i * dt;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
let stopDistance = Number.POSITIVE_INFINITY;
|
|
57
|
+
let stopTime = Number.POSITIVE_INFINITY;
|
|
58
|
+
{
|
|
59
|
+
const motion = settled();
|
|
60
|
+
let distance = 0;
|
|
61
|
+
for (let i = 1; i <= ticks(LIMIT_SECONDS); i += 1) {
|
|
62
|
+
const moved = step(motion, idle);
|
|
63
|
+
distance += Math.hypot(moved.stepX, moved.stepZ);
|
|
64
|
+
if (speedOf(motion) < STOPPED) {
|
|
65
|
+
stopDistance = distance;
|
|
66
|
+
stopTime = i * dt;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
let turnAroundTime = Number.POSITIVE_INFINITY;
|
|
72
|
+
{
|
|
73
|
+
const motion = settled();
|
|
74
|
+
for (let i = 1; i <= ticks(LIMIT_SECONDS); i += 1) {
|
|
75
|
+
step(motion, forward, -1);
|
|
76
|
+
if (-motion.horizontalVelocityZ >= topSpeed * ARRIVED) {
|
|
77
|
+
turnAroundTime = i * dt;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const jump = (airborne, releaseAfter = Number.POSITIVE_INFINITY) => {
|
|
83
|
+
const motion = fresh();
|
|
84
|
+
const takeoff = held({ space: true });
|
|
85
|
+
const released = held({ d: airborne.right !== 0, shift: sprint });
|
|
86
|
+
let height = 0;
|
|
87
|
+
let apex = 0;
|
|
88
|
+
let lateral = 0;
|
|
89
|
+
let landed = Number.POSITIVE_INFINITY;
|
|
90
|
+
for (let i = 1; i <= ticks(LIMIT_SECONDS); i += 1) {
|
|
91
|
+
const moved = step(motion, i === 1 ? takeoff : i * dt > releaseAfter ? released : airborne);
|
|
92
|
+
lateral += moved.stepX;
|
|
93
|
+
if (motion.jumpOffset > height) {
|
|
94
|
+
height = motion.jumpOffset;
|
|
95
|
+
apex = i * dt;
|
|
96
|
+
}
|
|
97
|
+
if (motion.grounded && i > 1) {
|
|
98
|
+
landed = i * dt;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { height, apex, lateral, landed };
|
|
103
|
+
};
|
|
104
|
+
const standing = jump(held({ space: true }));
|
|
105
|
+
const strafed = jump(held({ space: true, d: true, shift: sprint }));
|
|
106
|
+
const tapped = jump(held({ space: true }), options.tapSeconds ?? 0.1);
|
|
107
|
+
return {
|
|
108
|
+
topSpeed,
|
|
109
|
+
timeToTopSpeed,
|
|
110
|
+
stopDistance,
|
|
111
|
+
stopTime,
|
|
112
|
+
turnAroundTime,
|
|
113
|
+
jumpHeight: standing.height,
|
|
114
|
+
tapJumpHeight: tapped.height,
|
|
115
|
+
apexTime: standing.apex,
|
|
116
|
+
airTime: standing.landed,
|
|
117
|
+
airControlReach: Math.abs(strafed.lateral),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -2,13 +2,18 @@ import type { PhysicsConfig } from "../game/defineGame.js";
|
|
|
2
2
|
import type { PlayerMovementConfig, VoxelCollisionConfig } from "../game/playableGame.js";
|
|
3
3
|
import type { GameContext } from "../runtime/gameContext.js";
|
|
4
4
|
import type { InputFrame } from "../runtime/inputSnapshot.js";
|
|
5
|
-
import { type
|
|
5
|
+
import { type InputBufferSnapshot } from "../input/inputBuffer.js";
|
|
6
|
+
import { type CharacterControllerConfig, type CharacterControllerState } from "./characterController.js";
|
|
6
7
|
import { type TerrainField } from "../world/terrain.js";
|
|
7
8
|
import type { WorldFeature } from "../world/features.js";
|
|
8
9
|
import type { PhysicsBackend } from "../physics/physicsBackend.js";
|
|
9
|
-
import { type MovementTuningOverrides } from "./movementModel.js";
|
|
10
|
+
import { type MovementTuningOverrides, type PlayerMotionState } from "./movementModel.js";
|
|
11
|
+
import { type FreeFlightState } from "./freeFlight.js";
|
|
12
|
+
import { type VoxelPlayerBody } from "./voxelController.js";
|
|
10
13
|
/** The resolved, per-world movement configuration {@link stepPlayerMovement} integrates against — the same inputs the shell FrameDriver used to read piecemeal, gathered into one struct so single-player and host movement run identical math. */
|
|
11
14
|
export interface PlayerMovementTuning {
|
|
15
|
+
/** The simulation driver already clamps frame stalls; integrate its scaled step in full. */
|
|
16
|
+
authoritativeStep?: boolean;
|
|
12
17
|
collision?: VoxelCollisionConfig;
|
|
13
18
|
movement?: PlayerMovementConfig;
|
|
14
19
|
physics?: MovementTuningOverrides;
|
|
@@ -33,8 +38,49 @@ export declare function resolvePlayerMovementTuning(opts: {
|
|
|
33
38
|
physics?: PhysicsConfig;
|
|
34
39
|
world?: WorldFeature;
|
|
35
40
|
}): PlayerMovementTuning;
|
|
41
|
+
/** Last completed shared movement step for one entity; a live read-only view, not a save snapshot. */
|
|
42
|
+
export interface PlayerMovementTelemetry {
|
|
43
|
+
grounded: boolean;
|
|
44
|
+
verticalVelocity: number;
|
|
45
|
+
crouching: boolean;
|
|
46
|
+
/** Accepted physical height for heightfield walking; absent for other collision paths. */
|
|
47
|
+
collisionHeight?: number;
|
|
48
|
+
/** Live authored height requested for this completed heightfield step. */
|
|
49
|
+
requestedCollisionHeight?: number;
|
|
50
|
+
/** Growth is waiting for headroom; the accepted physical height remains collisionHeight. */
|
|
51
|
+
collisionHeightBlocked?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Read the entity's last shared movement result through indexed possession ownership. Returns `null` before a
|
|
55
|
+
* step, after movement restore/forget, when a commit policy replaces the motor proposal, or for an entity not
|
|
56
|
+
* currently driven by this motor. Reuses one live view;
|
|
57
|
+
* custom movers supply their own animation parameters. Flight never reports ground contact or a walking crouch.
|
|
58
|
+
*
|
|
59
|
+
* @capability movement-telemetry read physical grounded, vertical velocity and crouch state without animation-store writes
|
|
60
|
+
*/
|
|
61
|
+
export declare function playerMovementTelemetry(ctx: GameContext, entityId: string): Readonly<PlayerMovementTelemetry> | null;
|
|
36
62
|
/** One player's current heading (radians), integrated by {@link stepPlayerMovement} — the shell reads it back into its camera/aim yaw. */
|
|
37
63
|
export declare function playerMovementHeading(ctx: GameContext, userId: string): number;
|
|
64
|
+
/** One player's serializable movement state: heading, facing, velocities, jump latch and controller capsule. The entity pose lives in the entity store. */
|
|
65
|
+
export interface PlayerMovementSnapshot {
|
|
66
|
+
heading: number;
|
|
67
|
+
facing: number | null;
|
|
68
|
+
voxelBody: VoxelPlayerBody | null;
|
|
69
|
+
motion: PlayerMotionState | null;
|
|
70
|
+
flight: FreeFlightState | null;
|
|
71
|
+
controller: CharacterControllerState | null;
|
|
72
|
+
controllerJumpHeld: boolean;
|
|
73
|
+
/** Buffered jump presses; absent in snapshots taken before jump buffering existed. */
|
|
74
|
+
jumpBuffer?: InputBufferSnapshot | null;
|
|
75
|
+
/** Accepted heightfield body height. Older walking snapshots retain their historical 1.8m span. */
|
|
76
|
+
heightfieldHeight?: number | null;
|
|
77
|
+
/** Pawn that accepted heightfieldHeight; omission binds legacy dimensions to the active pawn on restore. */
|
|
78
|
+
heightfieldEntityId?: string | null;
|
|
79
|
+
}
|
|
80
|
+
/** Copy one player's movement state for prediction, rollback or a save; `null` when the player has not moved yet. */
|
|
81
|
+
export declare function snapshotPlayerMovement(ctx: GameContext, userId: string): PlayerMovementSnapshot | null;
|
|
82
|
+
/** Put a player's movement state back to a {@link snapshotPlayerMovement} copy. Pending state survives until first spawn; a driven actor's despawn clears it. */
|
|
83
|
+
export declare function restorePlayerMovement(ctx: GameContext, userId: string, snapshot: PlayerMovementSnapshot): void;
|
|
38
84
|
/** Drop a player's retained movement state (heading + kinematic body) — call on leave so a rejoin starts fresh instead of resuming stale velocity. */
|
|
39
85
|
export declare function forgetPlayerMovement(ctx: GameContext, userId: string): void;
|
|
40
86
|
/**
|