@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
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { EditorCommand } from "./commands.js";
|
|
2
|
+
import type { EditorDocument } from "./types.js";
|
|
3
|
+
import { type RuntimeEntityState, type RuntimeStateSnapshot } from "./liveSync.js";
|
|
4
|
+
/** Play-mode sim gate held by the editor host — pause freezes ticks; step runs N frames then re-pauses. */
|
|
5
|
+
export interface RuntimePlayControl {
|
|
6
|
+
paused: boolean;
|
|
7
|
+
pendingSteps: number;
|
|
8
|
+
}
|
|
9
|
+
/** Compact reverse-channel view for the play-mode inspector and `runtime_summary` RPC. */
|
|
10
|
+
export interface RuntimeInspectorSummary {
|
|
11
|
+
seq: number;
|
|
12
|
+
entityCount: number;
|
|
13
|
+
entities: readonly {
|
|
14
|
+
id: string;
|
|
15
|
+
hasPosition: boolean;
|
|
16
|
+
rotationY?: number;
|
|
17
|
+
valueKeys: readonly string[];
|
|
18
|
+
}[];
|
|
19
|
+
tunableKeys: readonly string[];
|
|
20
|
+
overrideIds: readonly string[];
|
|
21
|
+
play: RuntimePlayControl;
|
|
22
|
+
}
|
|
23
|
+
/** One resolved runtime field returned by `runtime_get`. */
|
|
24
|
+
export interface RuntimeInspectorGetResult {
|
|
25
|
+
id: string;
|
|
26
|
+
kind: "entity" | "tunable" | "missing";
|
|
27
|
+
entity?: RuntimeEntityState;
|
|
28
|
+
path?: string;
|
|
29
|
+
value?: unknown;
|
|
30
|
+
override?: RuntimeEntityState;
|
|
31
|
+
}
|
|
32
|
+
/** Desired mutation from `runtime_set` before the host applies it. */
|
|
33
|
+
export interface RuntimeInspectorSetPlan {
|
|
34
|
+
entity?: RuntimeEntityState;
|
|
35
|
+
tunable?: {
|
|
36
|
+
key: string;
|
|
37
|
+
value: unknown;
|
|
38
|
+
};
|
|
39
|
+
writeBackCommands: readonly EditorCommand[];
|
|
40
|
+
error?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Builds the compact reverse-channel summary used by the play-mode inspector panel and the
|
|
44
|
+
* `runtime_summary` bridge RPC.
|
|
45
|
+
* @capability editor-runtime-inspector summarize live runtime entities and tunables for play mode
|
|
46
|
+
*/
|
|
47
|
+
export declare function summarizeRuntimeInspector(snapshot: RuntimeStateSnapshot, overrides: Readonly<Record<string, RuntimeEntityState>>, play: RuntimePlayControl): RuntimeInspectorSummary;
|
|
48
|
+
/**
|
|
49
|
+
* Resolves one entity, entity field, or tunable from the reverse-channel snapshot (with overrides
|
|
50
|
+
* layered on top for entity rows).
|
|
51
|
+
* @capability editor-runtime-inspector read one live runtime entity field or tunable
|
|
52
|
+
*/
|
|
53
|
+
export declare function getRuntimeInspectorValue(snapshot: RuntimeStateSnapshot, overrides: Readonly<Record<string, RuntimeEntityState>>, id: string, path?: string): RuntimeInspectorGetResult;
|
|
54
|
+
/**
|
|
55
|
+
* Plans a play-mode poke: builds the ephemeral entity/tunable override and, when `writeBack` is
|
|
56
|
+
* true, the undoable document commands that promote it into the scene document.
|
|
57
|
+
* @capability editor-runtime-inspector plan a play-mode runtime_set with optional document write-back
|
|
58
|
+
*/
|
|
59
|
+
export declare function planRuntimeInspectorSet(document: EditorDocument, input: {
|
|
60
|
+
id: string;
|
|
61
|
+
path?: string;
|
|
62
|
+
value?: unknown;
|
|
63
|
+
position?: {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
z: number;
|
|
67
|
+
};
|
|
68
|
+
rotationY?: number;
|
|
69
|
+
values?: Record<string, unknown>;
|
|
70
|
+
writeBack?: boolean;
|
|
71
|
+
}): RuntimeInspectorSetPlan;
|
|
72
|
+
/**
|
|
73
|
+
* Promotes ephemeral runtime `values` into an undoable meta patch on a document-linked object.
|
|
74
|
+
* Returns null when the id is not in the document or there are no values.
|
|
75
|
+
* @capability editor-runtime-inspector promote runtime entity values into a document meta write-back
|
|
76
|
+
*/
|
|
77
|
+
export declare function runtimeEntityMetaWriteBackCommand(document: EditorDocument, entity: RuntimeEntityState): EditorCommand | null;
|
|
78
|
+
/**
|
|
79
|
+
* Advances the play-control step counter: when paused with pending steps, consumes one and reports
|
|
80
|
+
* whether the sim should run this frame. When not paused, always runs.
|
|
81
|
+
* @capability editor-runtime-inspector gate a play-mode frame against pause/step control
|
|
82
|
+
*/
|
|
83
|
+
export declare function consumeRuntimePlayStep(play: RuntimePlayControl): {
|
|
84
|
+
runFrame: boolean;
|
|
85
|
+
next: RuntimePlayControl;
|
|
86
|
+
};
|
|
87
|
+
/** Default play-control state when entering play mode (running). */
|
|
88
|
+
export declare function createRuntimePlayControl(paused?: boolean): RuntimePlayControl;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { runtimeEntityWriteBackCommand, } from "./liveSync.js";
|
|
2
|
+
/**
|
|
3
|
+
* Builds the compact reverse-channel summary used by the play-mode inspector panel and the
|
|
4
|
+
* `runtime_summary` bridge RPC.
|
|
5
|
+
* @capability editor-runtime-inspector summarize live runtime entities and tunables for play mode
|
|
6
|
+
*/
|
|
7
|
+
export function summarizeRuntimeInspector(snapshot, overrides, play) {
|
|
8
|
+
const entities = Object.values(snapshot.entities)
|
|
9
|
+
.map((entity) => ({
|
|
10
|
+
id: entity.id,
|
|
11
|
+
hasPosition: entity.position !== undefined,
|
|
12
|
+
...(entity.rotationY === undefined ? {} : { rotationY: entity.rotationY }),
|
|
13
|
+
valueKeys: entity.values === undefined ? [] : Object.keys(entity.values).sort(),
|
|
14
|
+
}))
|
|
15
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
16
|
+
return {
|
|
17
|
+
seq: snapshot.seq,
|
|
18
|
+
entityCount: entities.length,
|
|
19
|
+
entities,
|
|
20
|
+
tunableKeys: Object.keys(snapshot.tunables).sort(),
|
|
21
|
+
overrideIds: Object.keys(overrides).sort(),
|
|
22
|
+
play: { paused: play.paused, pendingSteps: play.pendingSteps },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolves one entity, entity field, or tunable from the reverse-channel snapshot (with overrides
|
|
27
|
+
* layered on top for entity rows).
|
|
28
|
+
* @capability editor-runtime-inspector read one live runtime entity field or tunable
|
|
29
|
+
*/
|
|
30
|
+
export function getRuntimeInspectorValue(snapshot, overrides, id, path) {
|
|
31
|
+
if (id.startsWith("tunable:")) {
|
|
32
|
+
const key = id.slice("tunable:".length);
|
|
33
|
+
if (key.length === 0)
|
|
34
|
+
return { id, kind: "missing" };
|
|
35
|
+
if (!(key in snapshot.tunables) && path === undefined)
|
|
36
|
+
return { id, kind: "missing", path: key };
|
|
37
|
+
return {
|
|
38
|
+
id,
|
|
39
|
+
kind: "tunable",
|
|
40
|
+
path: key,
|
|
41
|
+
value: snapshot.tunables[key],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const base = snapshot.entities[id];
|
|
45
|
+
const override = overrides[id];
|
|
46
|
+
if (base === undefined && override === undefined) {
|
|
47
|
+
if (path !== undefined && path in snapshot.tunables) {
|
|
48
|
+
return { id: `tunable:${path}`, kind: "tunable", path, value: snapshot.tunables[path] };
|
|
49
|
+
}
|
|
50
|
+
return { id, kind: "missing", path };
|
|
51
|
+
}
|
|
52
|
+
const entity = {
|
|
53
|
+
id,
|
|
54
|
+
position: override?.position ?? base?.position,
|
|
55
|
+
rotationY: override?.rotationY ?? base?.rotationY,
|
|
56
|
+
values: override?.values === undefined && base?.values === undefined
|
|
57
|
+
? undefined
|
|
58
|
+
: { ...base?.values, ...override?.values },
|
|
59
|
+
};
|
|
60
|
+
if (path === undefined || path === "") {
|
|
61
|
+
return { id, kind: "entity", entity, ...(override === undefined ? {} : { override }) };
|
|
62
|
+
}
|
|
63
|
+
if (path === "position") {
|
|
64
|
+
return { id, kind: "entity", entity, path, value: entity.position, ...(override === undefined ? {} : { override }) };
|
|
65
|
+
}
|
|
66
|
+
if (path === "rotationY") {
|
|
67
|
+
return { id, kind: "entity", entity, path, value: entity.rotationY, ...(override === undefined ? {} : { override }) };
|
|
68
|
+
}
|
|
69
|
+
if (path.startsWith("values.")) {
|
|
70
|
+
const key = path.slice("values.".length);
|
|
71
|
+
return {
|
|
72
|
+
id,
|
|
73
|
+
kind: "entity",
|
|
74
|
+
entity,
|
|
75
|
+
path,
|
|
76
|
+
value: entity.values?.[key],
|
|
77
|
+
...(override === undefined ? {} : { override }),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
id,
|
|
82
|
+
kind: "entity",
|
|
83
|
+
entity,
|
|
84
|
+
path,
|
|
85
|
+
value: entity.values?.[path],
|
|
86
|
+
...(override === undefined ? {} : { override }),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function isFiniteNumber(value) {
|
|
90
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
91
|
+
}
|
|
92
|
+
function asPosition(value) {
|
|
93
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
94
|
+
return null;
|
|
95
|
+
const record = value;
|
|
96
|
+
if (!isFiniteNumber(record.x) || !isFiniteNumber(record.y) || !isFiniteNumber(record.z))
|
|
97
|
+
return null;
|
|
98
|
+
return { x: record.x, y: record.y, z: record.z };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Plans a play-mode poke: builds the ephemeral entity/tunable override and, when `writeBack` is
|
|
102
|
+
* true, the undoable document commands that promote it into the scene document.
|
|
103
|
+
* @capability editor-runtime-inspector plan a play-mode runtime_set with optional document write-back
|
|
104
|
+
*/
|
|
105
|
+
export function planRuntimeInspectorSet(document, input) {
|
|
106
|
+
const writeBack = input.writeBack !== false;
|
|
107
|
+
const writeBackCommands = [];
|
|
108
|
+
if (input.id.startsWith("tunable:")) {
|
|
109
|
+
const key = input.id.slice("tunable:".length);
|
|
110
|
+
if (key.length === 0)
|
|
111
|
+
return { writeBackCommands, error: "tunable id is empty" };
|
|
112
|
+
if (input.value === undefined)
|
|
113
|
+
return { writeBackCommands, error: "tunable set requires value" };
|
|
114
|
+
return { tunable: { key, value: input.value }, writeBackCommands };
|
|
115
|
+
}
|
|
116
|
+
if (input.path !== undefined && input.path.startsWith("tunable:")) {
|
|
117
|
+
const key = input.path.slice("tunable:".length);
|
|
118
|
+
if (key.length === 0)
|
|
119
|
+
return { writeBackCommands, error: "tunable path is empty" };
|
|
120
|
+
if (input.value === undefined)
|
|
121
|
+
return { writeBackCommands, error: "tunable set requires value" };
|
|
122
|
+
return { tunable: { key, value: input.value }, writeBackCommands };
|
|
123
|
+
}
|
|
124
|
+
const entity = { id: input.id };
|
|
125
|
+
let touched = false;
|
|
126
|
+
if (input.position !== undefined) {
|
|
127
|
+
entity.position = { ...input.position };
|
|
128
|
+
touched = true;
|
|
129
|
+
}
|
|
130
|
+
if (input.rotationY !== undefined) {
|
|
131
|
+
if (!isFiniteNumber(input.rotationY))
|
|
132
|
+
return { writeBackCommands, error: "rotationY must be finite" };
|
|
133
|
+
entity.rotationY = input.rotationY;
|
|
134
|
+
touched = true;
|
|
135
|
+
}
|
|
136
|
+
if (input.values !== undefined) {
|
|
137
|
+
entity.values = { ...input.values };
|
|
138
|
+
touched = true;
|
|
139
|
+
}
|
|
140
|
+
if (input.path === "position") {
|
|
141
|
+
const position = asPosition(input.value);
|
|
142
|
+
if (position === null)
|
|
143
|
+
return { writeBackCommands, error: "position value must be {x,y,z}" };
|
|
144
|
+
entity.position = position;
|
|
145
|
+
touched = true;
|
|
146
|
+
}
|
|
147
|
+
else if (input.path === "rotationY") {
|
|
148
|
+
if (!isFiniteNumber(input.value))
|
|
149
|
+
return { writeBackCommands, error: "rotationY value must be finite" };
|
|
150
|
+
entity.rotationY = input.value;
|
|
151
|
+
touched = true;
|
|
152
|
+
}
|
|
153
|
+
else if (input.path !== undefined && input.path.startsWith("values.")) {
|
|
154
|
+
const key = input.path.slice("values.".length);
|
|
155
|
+
if (key.length === 0)
|
|
156
|
+
return { writeBackCommands, error: "values path is empty" };
|
|
157
|
+
entity.values = { [key]: input.value };
|
|
158
|
+
touched = true;
|
|
159
|
+
}
|
|
160
|
+
else if (input.path !== undefined && input.path.length > 0 && input.value !== undefined) {
|
|
161
|
+
entity.values = { [input.path]: input.value };
|
|
162
|
+
touched = true;
|
|
163
|
+
}
|
|
164
|
+
if (!touched) {
|
|
165
|
+
return { writeBackCommands, error: `runtime_set "${input.id}" has no position, rotationY, values, or path` };
|
|
166
|
+
}
|
|
167
|
+
if (writeBack) {
|
|
168
|
+
const transform = runtimeEntityWriteBackCommand(document, entity);
|
|
169
|
+
if (transform !== null)
|
|
170
|
+
writeBackCommands.push(transform);
|
|
171
|
+
if (entity.values !== undefined) {
|
|
172
|
+
const metaCommand = runtimeEntityMetaWriteBackCommand(document, entity);
|
|
173
|
+
if (metaCommand !== null)
|
|
174
|
+
writeBackCommands.push(metaCommand);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { entity, writeBackCommands };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Promotes ephemeral runtime `values` into an undoable meta patch on a document-linked object.
|
|
181
|
+
* Returns null when the id is not in the document or there are no values.
|
|
182
|
+
* @capability editor-runtime-inspector promote runtime entity values into a document meta write-back
|
|
183
|
+
*/
|
|
184
|
+
export function runtimeEntityMetaWriteBackCommand(document, entity) {
|
|
185
|
+
if (entity.values === undefined || Object.keys(entity.values).length === 0)
|
|
186
|
+
return null;
|
|
187
|
+
const marker = document.markers.find((entry) => entry.id === entity.id);
|
|
188
|
+
if (marker !== undefined) {
|
|
189
|
+
return {
|
|
190
|
+
type: "setMarker",
|
|
191
|
+
id: entity.id,
|
|
192
|
+
patch: { meta: { ...marker.meta, ...entity.values } },
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const volume = document.volumes.find((entry) => entry.id === entity.id);
|
|
196
|
+
if (volume !== undefined) {
|
|
197
|
+
return {
|
|
198
|
+
type: "setVolume",
|
|
199
|
+
id: entity.id,
|
|
200
|
+
patch: { meta: { ...volume.meta, ...entity.values } },
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const path = document.paths.find((entry) => entry.id === entity.id);
|
|
204
|
+
if (path !== undefined) {
|
|
205
|
+
return {
|
|
206
|
+
type: "setPath",
|
|
207
|
+
id: entity.id,
|
|
208
|
+
patch: { meta: { ...path.meta, ...entity.values } },
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const note = document.annotations.find((entry) => entry.id === entity.id);
|
|
212
|
+
if (note !== undefined) {
|
|
213
|
+
return {
|
|
214
|
+
type: "setNote",
|
|
215
|
+
id: entity.id,
|
|
216
|
+
patch: { meta: { ...note.meta, ...entity.values } },
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Advances the play-control step counter: when paused with pending steps, consumes one and reports
|
|
223
|
+
* whether the sim should run this frame. When not paused, always runs.
|
|
224
|
+
* @capability editor-runtime-inspector gate a play-mode frame against pause/step control
|
|
225
|
+
*/
|
|
226
|
+
export function consumeRuntimePlayStep(play) {
|
|
227
|
+
if (!play.paused)
|
|
228
|
+
return { runFrame: true, next: play };
|
|
229
|
+
if (play.pendingSteps <= 0)
|
|
230
|
+
return { runFrame: false, next: play };
|
|
231
|
+
return {
|
|
232
|
+
runFrame: true,
|
|
233
|
+
next: { paused: true, pendingSteps: play.pendingSteps - 1 },
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/** Default play-control state when entering play mode (running). */
|
|
237
|
+
export function createRuntimePlayControl(paused = false) {
|
|
238
|
+
return { paused, pendingSteps: 0 };
|
|
239
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { ParamSchema } from "../scene/sceneKinds.js";
|
|
2
|
+
import type { EditorUiDocument } from "../ui/hudDocument.js";
|
|
3
|
+
import type { TerraformSnapshot } from "../world/terraform.js";
|
|
4
|
+
import type { EditorGridLayer } from "./grid.js";
|
|
5
|
+
export type { EditorUiDocument, EditorUiPanelLayout, HudResizeAxes, HudPanelTypeDef } from "../ui/hudDocument.js";
|
|
6
|
+
/** A world-space point used across editor markers, volumes, and paths. */
|
|
7
|
+
export type EditorVec3 = {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
z: number;
|
|
11
|
+
};
|
|
12
|
+
/** Collision shape a volume is rendered and tested as. */
|
|
13
|
+
export type EditorVolumeShape = "sphere" | "cylinder" | "box";
|
|
14
|
+
/** A placeable point object in the scene — spawn, mob, chest, POI, etc. */
|
|
15
|
+
export interface EditorMarker {
|
|
16
|
+
id: string;
|
|
17
|
+
kind: string;
|
|
18
|
+
position: EditorVec3;
|
|
19
|
+
rotationY?: number;
|
|
20
|
+
color?: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Catalog object id for a placed prop mesh. Prefer this over `meta.catalogId` for new content;
|
|
24
|
+
* `resolveAuthoredObjects` still reads `meta.catalogId` as the migration alias.
|
|
25
|
+
*/
|
|
26
|
+
catalogId?: string;
|
|
27
|
+
/** Id of the object this one is parented under; moving the parent moves this with it. */
|
|
28
|
+
parentId?: string;
|
|
29
|
+
meta?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
/** A spatial region — zone, aggro range, capture area — placed in the scene. */
|
|
32
|
+
export interface EditorVolume {
|
|
33
|
+
id: string;
|
|
34
|
+
kind: string;
|
|
35
|
+
shape: EditorVolumeShape;
|
|
36
|
+
center: EditorVec3;
|
|
37
|
+
radius?: number;
|
|
38
|
+
height?: number;
|
|
39
|
+
halfExtents?: EditorVec3;
|
|
40
|
+
color?: string;
|
|
41
|
+
label?: string;
|
|
42
|
+
/** Id of the object this one is parented under; moving the parent moves this with it. */
|
|
43
|
+
parentId?: string;
|
|
44
|
+
meta?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
/** A polyline of points — road, corridor, patrol route — placed in the scene. */
|
|
47
|
+
export interface EditorPath {
|
|
48
|
+
id: string;
|
|
49
|
+
kind: string;
|
|
50
|
+
points: readonly EditorVec3[];
|
|
51
|
+
width?: number;
|
|
52
|
+
color?: string;
|
|
53
|
+
label?: string;
|
|
54
|
+
/** Id of the object this one is parented under; moving the parent moves this with it. */
|
|
55
|
+
parentId?: string;
|
|
56
|
+
meta?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
/** A free-text annotation pinned to a world position for designers. */
|
|
59
|
+
export interface EditorNote {
|
|
60
|
+
id: string;
|
|
61
|
+
text: string;
|
|
62
|
+
position: EditorVec3;
|
|
63
|
+
color?: string;
|
|
64
|
+
/** Id of the object this one is parented under; moving the parent moves this with it. */
|
|
65
|
+
parentId?: string;
|
|
66
|
+
meta?: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A sculpted heightfield authored in the editor: the {@link TerraformSnapshot} of offset deltas
|
|
70
|
+
* over the game's base ground. Serializes with the scene; a game rebuilds the field with
|
|
71
|
+
* `editableTerrainFromSnapshot`.
|
|
72
|
+
*/
|
|
73
|
+
export type EditorTerrain = TerraformSnapshot;
|
|
74
|
+
/** The four placeable-object collections a prefab fragment or clipboard fragment carries. */
|
|
75
|
+
export interface EditorFragmentContent {
|
|
76
|
+
markers: readonly EditorMarker[];
|
|
77
|
+
volumes: readonly EditorVolume[];
|
|
78
|
+
paths: readonly EditorPath[];
|
|
79
|
+
annotations: readonly EditorNote[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A serializable, reusable stamp of authored objects — markers/volumes/paths/notes centered on
|
|
83
|
+
* their own centroid so the same prefab inserts consistently anywhere, in this scene or another
|
|
84
|
+
* game's. `insertPrefab` tags every inserted object's `meta.prefabId`/`meta.prefabInstanceId`;
|
|
85
|
+
* `detachPrefabInstance` strips those tags to break the link without touching the content.
|
|
86
|
+
*/
|
|
87
|
+
export interface EditorPrefab {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
fragment: EditorFragmentContent;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A named, persisted list of object ids — a selection bookmark (restore, add-to) that can also
|
|
94
|
+
* double as a production group: `locked` blocks `translate`/`setTransform`/`remove`/`removeMany`
|
|
95
|
+
* on its members, `color`/`visible` are UI-only hints for the collections panel.
|
|
96
|
+
*/
|
|
97
|
+
export interface EditorCollection {
|
|
98
|
+
id: string;
|
|
99
|
+
name: string;
|
|
100
|
+
memberIds: string[];
|
|
101
|
+
color?: string;
|
|
102
|
+
locked?: boolean;
|
|
103
|
+
visible?: boolean;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* One row in a gameplay data catalog — id + optional label + a meta bag matching the catalog's
|
|
107
|
+
* `ParamSchema`. Values persist on the scene document; the schema lives in the game export.
|
|
108
|
+
* @capability editor-catalogs Persist and load one gameplay catalog entry's tuned params.
|
|
109
|
+
*/
|
|
110
|
+
export interface EditorCatalogEntry {
|
|
111
|
+
id: string;
|
|
112
|
+
label?: string;
|
|
113
|
+
meta?: Record<string, unknown>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Persisted values for one gameplay data catalog (weapons, waves, economy, …). Schemas are not
|
|
117
|
+
* stored here — they come from the game's `editorCatalogs` export and drive SchemaInspector.
|
|
118
|
+
* @capability editor-catalogs Persist gameplay tuning rows on the scene document.
|
|
119
|
+
*/
|
|
120
|
+
export interface EditorCatalogData {
|
|
121
|
+
id: string;
|
|
122
|
+
entries: EditorCatalogEntry[];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Game-exported catalog definition: a `ParamSchema` plus default entries. Schemas stay in code;
|
|
126
|
+
* entry values merge into `document.catalogs` and are what the editor/RPC edits and saves.
|
|
127
|
+
* @capability editor-catalogs Export typed gameplay catalogs for in-editor tuning.
|
|
128
|
+
*/
|
|
129
|
+
export interface EditorCatalogDefinition {
|
|
130
|
+
id: string;
|
|
131
|
+
label: string;
|
|
132
|
+
schema: ParamSchema;
|
|
133
|
+
entries: readonly EditorCatalogEntry[];
|
|
134
|
+
}
|
|
135
|
+
/** Accepted shape for a game's `editorCatalogs` export: definitions, or a factory. */
|
|
136
|
+
export type EditorCatalogsInput = readonly EditorCatalogDefinition[] | (() => readonly EditorCatalogDefinition[]);
|
|
137
|
+
/** The full authored scene: every marker, volume, path, note, and sculpted terrain for a game. */
|
|
138
|
+
export interface EditorDocument {
|
|
139
|
+
version: 1;
|
|
140
|
+
markers: EditorMarker[];
|
|
141
|
+
volumes: EditorVolume[];
|
|
142
|
+
paths: EditorPath[];
|
|
143
|
+
annotations: EditorNote[];
|
|
144
|
+
/** Optional sculpted heightfield overlay; absent until terrain is created in the editor. */
|
|
145
|
+
terrain?: EditorTerrain;
|
|
146
|
+
/** Reusable object stamps authored with "make prefab", inserted anywhere with "insert prefab". */
|
|
147
|
+
prefabs: EditorPrefab[];
|
|
148
|
+
/** Named selection sets / production groups — restore, add-to, lock, color, visibility. */
|
|
149
|
+
collections: EditorCollection[];
|
|
150
|
+
/** Persisted gameplay catalog values; schemas come from the game's `editorCatalogs` export. */
|
|
151
|
+
catalogs: EditorCatalogData[];
|
|
152
|
+
/**
|
|
153
|
+
* Editor-owned grid/tile layers — sparse `col,row` → value-id maps authored in the editor and
|
|
154
|
+
* read by runtime + rendering through `@jgengine/core/editor/grid`. Absent until a game or the
|
|
155
|
+
* editor adds a grid layer, so existing documents load unchanged.
|
|
156
|
+
*/
|
|
157
|
+
grids?: EditorGridLayer[];
|
|
158
|
+
/**
|
|
159
|
+
* HUD layout owned by the scene document — panel id → anchor/offset/size/visibility.
|
|
160
|
+
* Canvas mode (F2+C) and `canvas_move_panel` / `canvas_resize_panel` write here; HudPanel reads it.
|
|
161
|
+
*/
|
|
162
|
+
ui?: EditorUiDocument;
|
|
163
|
+
}
|
|
164
|
+
/** Accepted shape for a game's `editorLayers` export: a document, partial data, or a factory. */
|
|
165
|
+
export type EditorLayersInput = EditorDocument | Partial<Omit<EditorDocument, "version">> | (() => EditorDocument | Partial<Omit<EditorDocument, "version">>);
|
|
166
|
+
/** Per-kind show/hide flags for the editor's layer panel. */
|
|
167
|
+
export interface EditorKindVisibility {
|
|
168
|
+
[kind: string]: boolean;
|
|
169
|
+
}
|
|
170
|
+
/** Standard marker kinds recognized with default colors and behavior. */
|
|
171
|
+
export declare const WELL_KNOWN_MARKER_KINDS: readonly ["player_spawn", "mob", "boss", "vendor", "chest", "travel", "npc", "poi", "prop", "goal", "branch"];
|
|
172
|
+
/** Standard volume kinds recognized with default colors and behavior. */
|
|
173
|
+
export declare const WELL_KNOWN_VOLUME_KINDS: readonly ["zone", "flatten", "cluster", "aggro", "leash", "discover", "capture", "prompt", "poi", "respawn_skip"];
|
|
174
|
+
/** Standard path kinds recognized with default colors and behavior. */
|
|
175
|
+
export declare const WELL_KNOWN_PATH_KINDS: readonly ["road", "corridor", "branch", "route"];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Standard marker kinds recognized with default colors and behavior. */
|
|
2
|
+
export const WELL_KNOWN_MARKER_KINDS = [
|
|
3
|
+
"player_spawn",
|
|
4
|
+
"mob",
|
|
5
|
+
"boss",
|
|
6
|
+
"vendor",
|
|
7
|
+
"chest",
|
|
8
|
+
"travel",
|
|
9
|
+
"npc",
|
|
10
|
+
"poi",
|
|
11
|
+
"prop",
|
|
12
|
+
"goal",
|
|
13
|
+
"branch",
|
|
14
|
+
];
|
|
15
|
+
/** Standard volume kinds recognized with default colors and behavior. */
|
|
16
|
+
export const WELL_KNOWN_VOLUME_KINDS = [
|
|
17
|
+
"zone",
|
|
18
|
+
"flatten",
|
|
19
|
+
"cluster",
|
|
20
|
+
"aggro",
|
|
21
|
+
"leash",
|
|
22
|
+
"discover",
|
|
23
|
+
"capture",
|
|
24
|
+
"prompt",
|
|
25
|
+
"poi",
|
|
26
|
+
"respawn_skip",
|
|
27
|
+
];
|
|
28
|
+
/** Standard path kinds recognized with default colors and behavior. */
|
|
29
|
+
export const WELL_KNOWN_PATH_KINDS = ["road", "corridor", "branch", "route"];
|
|
@@ -5,6 +5,11 @@ export interface ReputationTier {
|
|
|
5
5
|
relation: FactionRelation;
|
|
6
6
|
}
|
|
7
7
|
export declare const DEFAULT_REPUTATION_TIERS: readonly ReputationTier[];
|
|
8
|
+
/**
|
|
9
|
+
* Map a faction standing value to its named reputation tier.
|
|
10
|
+
*
|
|
11
|
+
* @capability reputation faction standing that crosses named reputation tiers
|
|
12
|
+
*/
|
|
8
13
|
export declare function tierForStanding(tiers: readonly ReputationTier[], standing: number): ReputationTier;
|
|
9
14
|
export interface ReputationLedgerConfig {
|
|
10
15
|
tiers?: readonly ReputationTier[];
|
|
@@ -8,6 +8,11 @@ export const DEFAULT_REPUTATION_TIERS = [
|
|
|
8
8
|
{ id: "revered", min: 21000, relation: "friendly" },
|
|
9
9
|
{ id: "exalted", min: 42000, relation: "friendly" },
|
|
10
10
|
];
|
|
11
|
+
/**
|
|
12
|
+
* Map a faction standing value to its named reputation tier.
|
|
13
|
+
*
|
|
14
|
+
* @capability reputation faction standing that crosses named reputation tiers
|
|
15
|
+
*/
|
|
11
16
|
export function tierForStanding(tiers, standing) {
|
|
12
17
|
let match = tiers[0];
|
|
13
18
|
for (const tier of tiers) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Target unit for {@link formatDistance}: meters, kilometers, or `"auto"` (km past 1000m). */
|
|
2
|
+
export type DistanceUnit = "m" | "km" | "auto";
|
|
3
|
+
/** Options for {@link formatDistance}. */
|
|
4
|
+
export interface DistanceFormat {
|
|
5
|
+
/** Target unit. `"auto"` switches to km at 1000m and above. Defaults to `"m"`. */
|
|
6
|
+
unit?: DistanceUnit;
|
|
7
|
+
/** Fractional digits to show. Defaults to 0 for meters, 1 for kilometers. */
|
|
8
|
+
decimals?: 0 | 1 | 2;
|
|
9
|
+
/** Append the unit label. Defaults to true; set false to compose custom unit styling. */
|
|
10
|
+
showUnit?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Format a distance given in meters as a HUD-ready string, switching to km automatically past 1000m when `unit: "auto"`.
|
|
14
|
+
*
|
|
15
|
+
* @capability distance-format render meters as m or km for HUD stats, telemetry, and range readouts
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatDistance(meters: number, options?: DistanceFormat): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const AUTO_KM_THRESHOLD = 1000;
|
|
2
|
+
/**
|
|
3
|
+
* Format a distance given in meters as a HUD-ready string, switching to km automatically past 1000m when `unit: "auto"`.
|
|
4
|
+
*
|
|
5
|
+
* @capability distance-format render meters as m or km for HUD stats, telemetry, and range readouts
|
|
6
|
+
*/
|
|
7
|
+
export function formatDistance(meters, options = {}) {
|
|
8
|
+
const requested = options.unit ?? "m";
|
|
9
|
+
const clamped = Math.max(0, meters);
|
|
10
|
+
const showUnit = options.showUnit ?? true;
|
|
11
|
+
const useKm = requested === "km" || (requested === "auto" && clamped >= AUTO_KM_THRESHOLD);
|
|
12
|
+
if (useKm) {
|
|
13
|
+
const text = (clamped / 1000).toFixed(options.decimals ?? 1);
|
|
14
|
+
return showUnit ? `${text}km` : text;
|
|
15
|
+
}
|
|
16
|
+
const text = clamped.toFixed(options.decimals ?? 0);
|
|
17
|
+
return showUnit ? `${text}m` : text;
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Options for {@link formatDuration}. */
|
|
2
|
+
export interface DurationFormat {
|
|
3
|
+
/** Fractional-second digits to show (0, 1, or 2). Defaults to 0. */
|
|
4
|
+
decimals?: 0 | 1 | 2;
|
|
5
|
+
/** Force an `h:mm:ss` layout even under an hour. Defaults to auto (hours shown only when present). */
|
|
6
|
+
hours?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Left-pad a non-negative integer to `width` digits with leading zeros. */
|
|
9
|
+
export declare function padNumber(value: number, width: number): string;
|
|
10
|
+
/**
|
|
11
|
+
* Format a duration in seconds as a clock string (`m:ss`, `m:ss.ff`, or `h:mm:ss`), the shape every timer and racing HUD needs.
|
|
12
|
+
*
|
|
13
|
+
* @capability clock-format render seconds as m:ss / m:ss.ff / h:mm:ss for timers and race HUDs
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatDuration(seconds: number, options?: DurationFormat): string;
|
|
16
|
+
/**
|
|
17
|
+
* Format a signed time gap as `+m:ss.ff` / `-m:ss.ff`, for race deltas and split times.
|
|
18
|
+
*
|
|
19
|
+
* @capability clock-format format a signed time gap like a race split (+/- m:ss.ff)
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatDelta(seconds: number, decimals?: 0 | 1 | 2): string;
|
|
22
|
+
/**
|
|
23
|
+
* English ordinal for a placement number: 1 → "1st", 2 → "2nd", 3 → "3rd", 11 → "11th".
|
|
24
|
+
*
|
|
25
|
+
* @capability ordinal-format format a placement number as 1st/2nd/3rd for HUD ranks
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatOrdinal(value: number): string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** Left-pad a non-negative integer to `width` digits with leading zeros. */
|
|
2
|
+
export function padNumber(value, width) {
|
|
3
|
+
return Math.trunc(value).toString().padStart(width, "0");
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Format a duration in seconds as a clock string (`m:ss`, `m:ss.ff`, or `h:mm:ss`), the shape every timer and racing HUD needs.
|
|
7
|
+
*
|
|
8
|
+
* @capability clock-format render seconds as m:ss / m:ss.ff / h:mm:ss for timers and race HUDs
|
|
9
|
+
*/
|
|
10
|
+
export function formatDuration(seconds, options = {}) {
|
|
11
|
+
const decimals = options.decimals ?? 0;
|
|
12
|
+
const total = Math.max(0, seconds);
|
|
13
|
+
const whole = Math.floor(total);
|
|
14
|
+
const frac = decimals > 0 ? (total - whole).toFixed(decimals).slice(1) : "";
|
|
15
|
+
const showHours = options.hours ?? total >= 3600;
|
|
16
|
+
if (showHours) {
|
|
17
|
+
const h = Math.floor(whole / 3600);
|
|
18
|
+
const m = Math.floor((whole % 3600) / 60);
|
|
19
|
+
const s = whole % 60;
|
|
20
|
+
return `${h}:${padNumber(m, 2)}:${padNumber(s, 2)}${frac}`;
|
|
21
|
+
}
|
|
22
|
+
const m = Math.floor(whole / 60);
|
|
23
|
+
const s = whole % 60;
|
|
24
|
+
return `${m}:${padNumber(s, 2)}${frac}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Format a signed time gap as `+m:ss.ff` / `-m:ss.ff`, for race deltas and split times.
|
|
28
|
+
*
|
|
29
|
+
* @capability clock-format format a signed time gap like a race split (+/- m:ss.ff)
|
|
30
|
+
*/
|
|
31
|
+
export function formatDelta(seconds, decimals = 2) {
|
|
32
|
+
const sign = seconds < 0 ? "-" : "+";
|
|
33
|
+
return `${sign}${formatDuration(Math.abs(seconds), { decimals })}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* English ordinal for a placement number: 1 → "1st", 2 → "2nd", 3 → "3rd", 11 → "11th".
|
|
37
|
+
*
|
|
38
|
+
* @capability ordinal-format format a placement number as 1st/2nd/3rd for HUD ranks
|
|
39
|
+
*/
|
|
40
|
+
export function formatOrdinal(value) {
|
|
41
|
+
const n = Math.trunc(value);
|
|
42
|
+
const abs = Math.abs(n) % 100;
|
|
43
|
+
const suffix = abs >= 11 && abs <= 13 ? "th" : ["th", "st", "nd", "rd"][Math.abs(n) % 10] ?? "th";
|
|
44
|
+
return `${n}${suffix}`;
|
|
45
|
+
}
|