@jgengine/core 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -2
- package/LICENSE +203 -661
- package/README.md +1 -1
- package/dist/ai/crowd.d.ts +55 -0
- package/dist/ai/crowd.js +114 -0
- package/dist/ai/flock.d.ts +5 -2
- package/dist/ai/flock.js +5 -2
- package/dist/ai/groupAssist.d.ts +1 -0
- package/dist/ai/groupAssist.js +1 -0
- package/dist/ai/heatSystem.d.ts +76 -0
- package/dist/ai/heatSystem.js +97 -0
- package/dist/ai/interestScheduler.d.ts +107 -0
- package/dist/ai/interestScheduler.js +118 -0
- package/dist/ai/jobBoard.d.ts +1 -0
- package/dist/ai/jobBoard.js +1 -0
- package/dist/ai/laneSelect.d.ts +5 -2
- package/dist/ai/laneSelect.js +5 -2
- package/dist/ai/mobBrain.d.ts +1 -0
- package/dist/ai/mobBrain.js +1 -0
- package/dist/ai/populationDirector.d.ts +103 -0
- package/dist/ai/populationDirector.js +190 -0
- package/dist/ai/pursuit.d.ts +56 -0
- package/dist/ai/pursuit.js +53 -0
- package/dist/ai/spawnDirector.d.ts +7 -2
- package/dist/ai/spawnDirector.js +18 -15
- package/dist/ai/spawnPoint.d.ts +3 -1
- package/dist/ai/spawnPoint.js +3 -1
- package/dist/ai/targetAcquisition.d.ts +84 -0
- package/dist/ai/targetAcquisition.js +92 -0
- package/dist/anim/easing.d.ts +19 -0
- package/dist/anim/easing.js +19 -0
- package/dist/anim/oscillator.d.ts +12 -0
- package/dist/anim/oscillator.js +25 -0
- package/dist/area/areaEffectField.d.ts +127 -0
- package/dist/area/areaEffectField.js +175 -0
- package/dist/area/stackPolicy.d.ts +47 -0
- package/dist/area/stackPolicy.js +99 -0
- package/dist/authoring.d.ts +2 -1
- package/dist/authoring.js +2 -1
- package/dist/board/laneBoard.d.ts +13 -0
- package/dist/board/laneBoard.js +13 -0
- package/dist/board/timelineBoard.d.ts +10 -0
- package/dist/board/timelineBoard.js +10 -0
- package/dist/combat/abilityKit.d.ts +18 -0
- package/dist/combat/abilityKit.js +24 -9
- package/dist/combat/animationState.d.ts +5 -0
- package/dist/combat/animationState.js +5 -0
- package/dist/combat/breakMeters.d.ts +10 -0
- package/dist/combat/breakMeters.js +10 -0
- package/dist/combat/castRunner.d.ts +5 -0
- package/dist/combat/castRunner.js +5 -0
- package/dist/combat/comboPoints.d.ts +5 -0
- package/dist/combat/comboPoints.js +5 -0
- package/dist/combat/comboString.d.ts +5 -0
- package/dist/combat/comboString.js +5 -0
- package/dist/combat/damageInterceptors.d.ts +192 -0
- package/dist/combat/damageInterceptors.js +251 -0
- package/dist/combat/damageMatchup.d.ts +68 -0
- package/dist/combat/damageMatchup.js +42 -0
- package/dist/combat/damageResolution.d.ts +63 -0
- package/dist/combat/damageResolution.js +50 -0
- package/dist/combat/death.d.ts +7 -1
- package/dist/combat/death.js +5 -0
- package/dist/combat/deathReason.d.ts +14 -0
- package/dist/combat/deathReason.js +1 -0
- package/dist/combat/defensiveWindow.d.ts +5 -0
- package/dist/combat/defensiveWindow.js +5 -0
- package/dist/combat/dotField.d.ts +5 -1
- package/dist/combat/dotField.js +5 -1
- package/dist/combat/downed.d.ts +5 -0
- package/dist/combat/downed.js +5 -0
- package/dist/combat/effects.d.ts +5 -0
- package/dist/combat/effects.js +5 -0
- package/dist/combat/encounterSequence.d.ts +258 -0
- package/dist/combat/encounterSequence.js +426 -0
- package/dist/combat/hitReaction.d.ts +57 -1
- package/dist/combat/hitReaction.js +45 -5
- package/dist/combat/magazine.d.ts +54 -0
- package/dist/combat/magazine.js +96 -0
- package/dist/combat/projectiles.d.ts +5 -0
- package/dist/combat/projectiles.js +32 -14
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +5 -1
- package/dist/combat/regenShield.js +5 -1
- package/dist/combat/renderCues.d.ts +51 -0
- package/dist/combat/renderCues.js +44 -0
- package/dist/combat/resourcePool.d.ts +5 -0
- package/dist/combat/resourcePool.js +5 -0
- package/dist/combat/rewardAllocation.d.ts +121 -0
- package/dist/combat/rewardAllocation.js +251 -0
- package/dist/combat/shotOrigin.d.ts +18 -1
- package/dist/combat/shotOrigin.js +39 -0
- package/dist/combat/statusApplication.d.ts +96 -0
- package/dist/combat/statusApplication.js +81 -0
- package/dist/combat/telegraph.d.ts +11 -2
- package/dist/combat/telegraph.js +11 -2
- package/dist/combat/thresholdCrossings.d.ts +85 -0
- package/dist/combat/thresholdCrossings.js +116 -0
- package/dist/combat.d.ts +35 -0
- package/dist/combat.js +35 -0
- package/dist/commands/commandRegistry.d.ts +11 -0
- package/dist/commands/commandRegistry.js +9 -2
- package/dist/crafting/crop.d.ts +18 -0
- package/dist/crafting/crop.js +18 -0
- package/dist/crafting/production.d.ts +5 -0
- package/dist/crafting/production.js +5 -0
- package/dist/devtools/controls.d.ts +38 -0
- package/dist/devtools/controls.js +181 -0
- package/dist/devtools/devtools.d.ts +5 -197
- package/dist/devtools/devtools.js +38 -774
- package/dist/devtools/discover.d.ts +32 -0
- package/dist/devtools/discover.js +240 -0
- package/dist/devtools/fallbackSeams.d.ts +50 -0
- package/dist/devtools/fallbackSeams.js +111 -0
- package/dist/devtools/frame.d.ts +15 -0
- package/dist/devtools/frame.js +247 -0
- package/dist/devtools/logs.d.ts +15 -0
- package/dist/devtools/logs.js +86 -0
- package/dist/devtools/overrides.d.ts +16 -0
- package/dist/devtools/overrides.js +66 -0
- package/dist/devtools/rewriteTunables.d.ts +17 -0
- package/dist/devtools/rewriteTunables.js +276 -0
- package/dist/devtools/saveEndpoint.d.ts +46 -0
- package/dist/devtools/saveEndpoint.js +48 -0
- package/dist/devtools/transformTunables.d.ts +3 -0
- package/dist/devtools/transformTunables.js +3 -0
- package/dist/devtools/tunableSchema.d.ts +31 -0
- package/dist/devtools/tunableSchema.js +31 -0
- package/dist/devtools/types.d.ts +212 -0
- package/dist/devtools/types.js +1 -0
- package/dist/economy/auctionBook.d.ts +122 -0
- package/dist/economy/auctionBook.js +213 -0
- package/dist/economy/currency.d.ts +12 -1
- package/dist/economy/currency.js +12 -1
- package/dist/economy/listingBook.d.ts +91 -0
- package/dist/economy/listingBook.js +144 -0
- package/dist/economy/priceHistory.d.ts +44 -0
- package/dist/economy/priceHistory.js +89 -0
- package/dist/economy/resourceLedger.d.ts +222 -0
- package/dist/economy/resourceLedger.js +353 -0
- package/dist/economy/sharedWallet.d.ts +14 -0
- package/dist/economy/sharedWallet.js +14 -0
- package/dist/economy/techTree.d.ts +12 -0
- package/dist/economy/techTree.js +12 -0
- package/dist/economy/unlockPoints.d.ts +92 -0
- package/dist/economy/unlockPoints.js +103 -0
- package/dist/economy/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commandApply.d.ts +5 -0
- package/dist/editor/commandApply.js +755 -0
- package/dist/editor/commands.d.ts +235 -7
- package/dist/editor/commands.js +82 -124
- package/dist/editor/directives.d.ts +94 -0
- package/dist/editor/directives.js +206 -0
- package/dist/editor/document.d.ts +194 -13
- package/dist/editor/document.js +1166 -19
- package/dist/editor/entityCatalog.d.ts +42 -0
- package/dist/editor/entityCatalog.js +101 -0
- package/dist/editor/environment.d.ts +74 -0
- package/dist/editor/environment.js +169 -0
- package/dist/editor/grid.d.ts +229 -0
- package/dist/editor/grid.js +366 -0
- package/dist/editor/gridAdapters.d.ts +80 -0
- package/dist/editor/gridAdapters.js +134 -0
- package/dist/editor/index.d.ts +98 -6
- package/dist/editor/index.js +13 -2
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/minimap.d.ts +31 -0
- package/dist/editor/minimap.js +73 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/streamer.d.ts +66 -0
- package/dist/editor/streamer.js +68 -0
- package/dist/editor/types.d.ts +250 -1
- package/dist/editor/world.d.ts +136 -0
- package/dist/editor/world.js +303 -0
- package/dist/faction/reputation.d.ts +5 -0
- package/dist/faction/reputation.js +5 -0
- package/dist/format/distance.d.ts +17 -0
- package/dist/format/distance.js +18 -0
- package/dist/format/duration.d.ts +27 -0
- package/dist/format/duration.js +45 -0
- package/dist/format/speed.d.ts +17 -0
- package/dist/format/speed.js +25 -0
- package/dist/game/breeding.d.ts +161 -0
- package/dist/game/breeding.js +181 -0
- package/dist/game/cameraConfig.d.ts +451 -0
- package/dist/game/cameraConfig.js +1 -0
- package/dist/game/connectedPlayers.d.ts +6 -4
- package/dist/game/connectedPlayers.js +2 -2
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +110 -5
- package/dist/game/defineGame.js +49 -4
- package/dist/game/defineSystem.d.ts +90 -0
- package/dist/game/defineSystem.js +47 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +63 -13
- package/dist/game/events.js +5 -0
- package/dist/game/feed.d.ts +33 -0
- package/dist/game/feed.js +35 -2
- package/dist/game/gamePhase.d.ts +11 -0
- package/dist/game/gamePhase.js +16 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/loadout.d.ts +5 -0
- package/dist/game/loadout.js +5 -0
- package/dist/game/lootFilter.d.ts +2 -0
- package/dist/game/lootFilter.js +2 -0
- package/dist/game/lootPipeline.d.ts +164 -0
- package/dist/game/lootPipeline.js +216 -0
- package/dist/game/lootTable.d.ts +19 -2
- package/dist/game/lootTable.js +15 -5
- package/dist/game/objectives.d.ts +43 -0
- package/dist/game/objectives.js +36 -0
- package/dist/game/paramLayers.d.ts +148 -0
- package/dist/game/paramLayers.js +185 -0
- package/dist/game/ping.d.ts +5 -0
- package/dist/game/ping.js +5 -0
- package/dist/game/playableGame.d.ts +116 -432
- package/dist/game/playableGame.js +1 -1
- package/dist/game/progression.d.ts +35 -0
- package/dist/game/progression.js +19 -0
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +30 -3
- package/dist/game/race.d.ts +141 -0
- package/dist/game/race.js +169 -0
- package/dist/game/recordBook.d.ts +3 -1
- package/dist/game/recordBook.js +4 -1
- package/dist/game/ruleSelection.d.ts +75 -0
- package/dist/game/ruleSelection.js +127 -0
- package/dist/game/runDraft.d.ts +5 -0
- package/dist/game/runDraft.js +5 -0
- package/dist/game/saveStore.d.ts +111 -0
- package/dist/game/saveStore.js +312 -0
- package/dist/game/snapshotHistory.d.ts +67 -0
- package/dist/game/snapshotHistory.js +95 -0
- package/dist/game/social.d.ts +38 -1
- package/dist/game/social.js +71 -0
- package/dist/game/spawnPoints.d.ts +5 -0
- package/dist/game/spawnPoints.js +5 -0
- package/dist/game/systemRuntime.d.ts +50 -0
- package/dist/game/systemRuntime.js +157 -0
- package/dist/game/systemSchedule.d.ts +72 -0
- package/dist/game/systemSchedule.js +242 -0
- package/dist/game/toasts.d.ts +43 -0
- package/dist/game/toasts.js +44 -0
- package/dist/game/trade.d.ts +10 -0
- package/dist/game/trade.js +10 -0
- package/dist/game/tribe.d.ts +184 -0
- package/dist/game/tribe.js +432 -0
- package/dist/game/unlocks.d.ts +8 -0
- package/dist/game/unlocks.js +16 -0
- package/dist/game/vfxInstance.d.ts +138 -0
- package/dist/game/vfxInstance.js +96 -0
- package/dist/game/worldItem.d.ts +17 -4
- package/dist/game/worldItem.js +17 -4
- package/dist/gameplay.d.ts +93 -0
- package/dist/gameplay.js +93 -0
- package/dist/index.d.ts +5 -14
- package/dist/index.js +5 -14
- package/dist/input/actionBindings.d.ts +23 -6
- package/dist/input/actionBindings.js +23 -6
- package/dist/input/axisInput.d.ts +7 -2
- package/dist/input/axisInput.js +7 -2
- package/dist/input/controlGroups.d.ts +67 -0
- package/dist/input/controlGroups.js +41 -0
- package/dist/input/touchScheme.d.ts +82 -6
- package/dist/input/touchScheme.js +123 -10
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +2 -0
- package/dist/interaction/proximityPrompt.js +2 -0
- package/dist/interaction/qte.d.ts +5 -0
- package/dist/interaction/qte.js +5 -0
- package/dist/interaction/skillCheck.d.ts +5 -0
- package/dist/interaction/skillCheck.js +5 -0
- package/dist/inventory/encumbrance.d.ts +69 -0
- package/dist/inventory/encumbrance.js +68 -0
- package/dist/inventory/inventoryModel.d.ts +12 -0
- package/dist/inventory/inventoryModel.js +12 -0
- package/dist/inventory/shapedGrid.d.ts +16 -0
- package/dist/inventory/shapedGrid.js +16 -0
- package/dist/inventory/slotModel.d.ts +10 -0
- package/dist/inventory/slotModel.js +10 -0
- package/dist/item/durability.d.ts +5 -0
- package/dist/item/durability.js +6 -3
- package/dist/item/itemIdentity.d.ts +171 -0
- package/dist/item/itemIdentity.js +138 -0
- package/dist/item/itemInstanceRegistry.d.ts +32 -0
- package/dist/item/itemInstanceRegistry.js +34 -0
- package/dist/item/itemgen.d.ts +163 -0
- package/dist/item/itemgen.js +151 -0
- package/dist/item/modularItem.d.ts +5 -0
- package/dist/item/modularItem.js +5 -0
- package/dist/item/use.d.ts +5 -0
- package/dist/item/use.js +5 -0
- package/dist/item/useBehavior.d.ts +142 -0
- package/dist/item/useBehavior.js +105 -0
- package/dist/item/weapon.d.ts +5 -0
- package/dist/item/weapon.js +5 -0
- package/dist/math/scalar.d.ts +25 -0
- package/dist/math/scalar.js +47 -0
- package/dist/meta/changelog.d.ts +4 -1
- package/dist/meta/changelog.js +39 -2
- package/dist/movement/avoidance.d.ts +45 -0
- package/dist/movement/avoidance.js +123 -0
- package/dist/movement/cameraRig.d.ts +8 -0
- package/dist/movement/cameraRig.js +8 -0
- package/dist/movement/dash.d.ts +11 -0
- package/dist/movement/dash.js +11 -0
- package/dist/movement/formation.d.ts +135 -0
- package/dist/movement/formation.js +194 -0
- package/dist/movement/glideModel.d.ts +5 -0
- package/dist/movement/glideModel.js +5 -0
- package/dist/movement/grappleSwing.d.ts +5 -0
- package/dist/movement/grappleSwing.js +5 -0
- package/dist/movement/leaderTrail.d.ts +5 -0
- package/dist/movement/leaderTrail.js +5 -0
- package/dist/movement/movementModel.d.ts +50 -9
- package/dist/movement/movementModel.js +75 -29
- package/dist/movement/playerMovement.js +167 -12
- package/dist/movement/poseState.d.ts +13 -0
- package/dist/movement/poseState.js +16 -0
- package/dist/movement/steering.d.ts +8 -0
- package/dist/movement/steering.js +18 -0
- package/dist/multiplayer/combatSnapshot.d.ts +3 -0
- package/dist/multiplayer/combatSnapshot.js +16 -8
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +11 -1
- package/dist/multiplayer/presenceModel.js +17 -1
- package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
- package/dist/multiplayer/simultaneousCommit.js +3 -0
- package/dist/multiplayer.d.ts +11 -0
- package/dist/multiplayer.js +11 -0
- package/dist/nav/pathFollow.d.ts +57 -0
- package/dist/nav/pathFollow.js +109 -0
- package/dist/orders/orderKinds.d.ts +156 -0
- package/dist/orders/orderKinds.js +197 -0
- package/dist/orders/orderQueue.d.ts +208 -0
- package/dist/orders/orderQueue.js +211 -0
- package/dist/physics/drivableVehicle.d.ts +31 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/flightDynamics.d.ts +82 -0
- package/dist/physics/flightDynamics.js +165 -0
- package/dist/physics/gravityField.d.ts +25 -0
- package/dist/physics/gravityField.js +41 -0
- package/dist/physics/kinematicVehicle.d.ts +108 -1
- package/dist/physics/kinematicVehicle.js +212 -15
- package/dist/physics/physicsWorld.d.ts +50 -12
- package/dist/physics/physicsWorld.js +120 -122
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -0
- package/dist/physics/vehicleObstacles.d.ts +44 -0
- package/dist/physics/vehicleObstacles.js +115 -0
- package/dist/procedural.d.ts +3 -0
- package/dist/procedural.js +3 -0
- package/dist/progression/statGraph.d.ts +116 -0
- package/dist/progression/statGraph.js +318 -0
- package/dist/puzzle/cellGrid.d.ts +9 -0
- package/dist/puzzle/cellGrid.js +9 -0
- package/dist/puzzle/fallingPiece.d.ts +9 -0
- package/dist/puzzle/fallingPiece.js +9 -0
- package/dist/puzzle/nonogram.d.ts +39 -0
- package/dist/puzzle/nonogram.js +136 -0
- package/dist/random/nameGen.d.ts +5 -0
- package/dist/random/nameGen.js +5 -0
- package/dist/random/pick.d.ts +8 -0
- package/dist/random/pick.js +31 -0
- package/dist/random/rng.d.ts +26 -1
- package/dist/random/rng.js +32 -9
- package/dist/random/seedLink.d.ts +4 -0
- package/dist/random/seedLink.js +4 -0
- package/dist/relation/keyedValues.d.ts +54 -0
- package/dist/relation/keyedValues.js +115 -0
- package/dist/relation/thresholds.d.ts +62 -0
- package/dist/relation/thresholds.js +62 -0
- package/dist/render/color.d.ts +12 -0
- package/dist/render/color.js +26 -0
- package/dist/render/lookPreset.d.ts +41 -0
- package/dist/render/lookPreset.js +29 -0
- package/dist/render/postProcessing.d.ts +20 -0
- package/dist/render/postProcessing.js +21 -1
- package/dist/rules/predicate.d.ts +53 -0
- package/dist/rules/predicate.js +64 -0
- package/dist/rules/ruleEffects.d.ts +38 -0
- package/dist/rules/ruleEffects.js +37 -0
- package/dist/rules/triggeredRules.d.ts +160 -0
- package/dist/rules/triggeredRules.js +241 -0
- package/dist/runtime/adapter.d.ts +55 -3
- package/dist/runtime/adapter.js +57 -1
- package/dist/runtime/cameraDirector.d.ts +1 -0
- package/dist/runtime/cameraDirector.js +1 -0
- package/dist/runtime/commandRunner.d.ts +1 -0
- package/dist/runtime/commandRunner.js +1 -0
- package/dist/runtime/context/combat.d.ts +51 -0
- package/dist/runtime/context/combat.js +130 -0
- package/dist/runtime/context/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/deathLoot.d.ts +30 -0
- package/dist/runtime/context/deathLoot.js +39 -0
- package/dist/runtime/context/player.d.ts +48 -0
- package/dist/runtime/context/player.js +125 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -0
- package/dist/runtime/context/scene.d.ts +59 -0
- package/dist/runtime/context/scene.js +291 -0
- package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
- package/dist/runtime/context/snapshotCodecs.js +26 -0
- package/dist/runtime/context/worldItems.d.ts +21 -0
- package/dist/runtime/context/worldItems.js +37 -0
- package/dist/runtime/descriptors/baseline.d.ts +48 -0
- package/dist/runtime/descriptors/baseline.js +157 -0
- package/dist/runtime/descriptors/features.d.ts +79 -0
- package/dist/runtime/descriptors/features.js +299 -0
- package/dist/runtime/gameContext.d.ts +2 -327
- package/dist/runtime/gameContext.js +273 -778
- package/dist/runtime/gameContextTypes.d.ts +467 -0
- package/dist/runtime/gameContextTypes.js +1 -0
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +62 -0
- package/dist/runtime/headlessRunner.js +45 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostPolicy.d.ts +51 -0
- package/dist/runtime/hostPolicy.js +68 -0
- package/dist/runtime/hostedGameRunner.d.ts +11 -4
- package/dist/runtime/hostedGameRunner.js +27 -3
- package/dist/runtime/hostedWorldSession.d.ts +15 -5
- package/dist/runtime/hostedWorldSession.js +12 -4
- package/dist/runtime/inputSnapshot.d.ts +8 -3
- package/dist/runtime/inputSnapshot.js +6 -2
- package/dist/runtime/motionIntents.d.ts +11 -2
- package/dist/runtime/motionIntents.js +16 -2
- package/dist/runtime/perContext.d.ts +15 -0
- package/dist/runtime/perContext.js +21 -0
- package/dist/runtime/runtimeSave.d.ts +79 -0
- package/dist/runtime/runtimeSave.js +105 -0
- package/dist/runtime/save.d.ts +4 -0
- package/dist/runtime/save.js +4 -0
- package/dist/runtime/snapshot.d.ts +7 -0
- package/dist/runtime/snapshot.js +7 -0
- package/dist/runtime/visibility.d.ts +2 -1
- package/dist/runtime/visibility.js +2 -1
- package/dist/runtime/worldChannel.d.ts +7 -3
- package/dist/runtime/worldChannel.js +51 -6
- package/dist/runtime/worldMirror.d.ts +14 -2
- package/dist/runtime/worldMirror.js +15 -2
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +30 -7
- package/dist/runtime/worldReplication.js +41 -9
- package/dist/runtime/worldSnapshot.d.ts +42 -3
- package/dist/runtime/worldSnapshot.js +34 -7
- package/dist/scene/assetCatalog.d.ts +26 -0
- package/dist/scene/assetCatalog.js +4 -0
- package/dist/scene/assetDiagnostics.d.ts +69 -0
- package/dist/scene/assetDiagnostics.js +110 -0
- package/dist/scene/assetGenerator.d.ts +65 -0
- package/dist/scene/assetGenerator.js +64 -0
- package/dist/scene/assetSpace.d.ts +137 -0
- package/dist/scene/assetSpace.js +257 -0
- package/dist/scene/authoredTriggers.d.ts +219 -0
- package/dist/scene/authoredTriggers.js +454 -0
- package/dist/scene/behaviorRuntime.d.ts +75 -0
- package/dist/scene/behaviorRuntime.js +217 -0
- package/dist/scene/behaviors.d.ts +14 -2
- package/dist/scene/behaviors.js +7 -2
- package/dist/scene/bodyBind.d.ts +60 -0
- package/dist/scene/bodyBind.js +51 -0
- package/dist/scene/builtinSceneKinds.d.ts +5 -0
- package/dist/scene/builtinSceneKinds.js +67 -0
- package/dist/scene/colliders.d.ts +71 -1
- package/dist/scene/colliders.js +145 -1
- package/dist/scene/collisionMesh.d.ts +94 -0
- package/dist/scene/collisionMesh.js +699 -0
- package/dist/scene/companion.d.ts +147 -0
- package/dist/scene/companion.js +193 -0
- package/dist/scene/entityStats.d.ts +18 -11
- package/dist/scene/entityStats.js +21 -16
- package/dist/scene/entityStore.d.ts +12 -1
- package/dist/scene/entityStore.js +15 -0
- package/dist/scene/facing.d.ts +18 -0
- package/dist/scene/facing.js +26 -0
- package/dist/scene/modelSockets.d.ts +33 -0
- package/dist/scene/modelSockets.js +29 -0
- package/dist/scene/objectQuery.d.ts +2 -0
- package/dist/scene/objectQuery.js +2 -0
- package/dist/scene/objectStore.d.ts +4 -0
- package/dist/scene/objectStore.js +6 -0
- package/dist/scene/possession.d.ts +8 -0
- package/dist/scene/possession.js +14 -0
- package/dist/scene/roster.d.ts +3 -0
- package/dist/scene/roster.js +12 -0
- package/dist/scene/sceneKinds.d.ts +256 -0
- package/dist/scene/sceneKinds.js +218 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -0
- package/dist/scene/sceneRaycast.js +15 -0
- package/dist/scene/selectionBookmarks.d.ts +93 -0
- package/dist/scene/selectionBookmarks.js +122 -0
- package/dist/scene/vehicleSeat.d.ts +68 -0
- package/dist/scene/vehicleSeat.js +59 -0
- package/dist/sensor/concealment.d.ts +3 -0
- package/dist/sensor/concealment.js +3 -0
- package/dist/sensor/freezeMonitor.d.ts +1 -0
- package/dist/sensor/freezeMonitor.js +1 -0
- package/dist/sensor/frustumSensor.d.ts +7 -3
- package/dist/sensor/frustumSensor.js +7 -3
- package/dist/sensor/hiddenStateProbe.d.ts +5 -2
- package/dist/sensor/hiddenStateProbe.js +5 -2
- package/dist/sensor/recordingBuffer.d.ts +2 -1
- package/dist/sensor/recordingBuffer.js +2 -1
- package/dist/sensor/replayLoop.d.ts +6 -2
- package/dist/sensor/replayLoop.js +6 -2
- package/dist/sensor/revealQuery.d.ts +2 -1
- package/dist/sensor/revealQuery.js +2 -1
- package/dist/sensor/visionCone.d.ts +10 -3
- package/dist/sensor/visionCone.js +10 -3
- package/dist/session/contestedChannel.d.ts +1 -0
- package/dist/session/contestedChannel.js +1 -0
- package/dist/session/extraction.d.ts +1 -0
- package/dist/session/extraction.js +1 -0
- package/dist/session/roles.d.ts +6 -0
- package/dist/session/roles.js +6 -0
- package/dist/session/roundState.d.ts +8 -0
- package/dist/session/roundState.js +2 -0
- package/dist/settings/settingsModel.d.ts +1 -0
- package/dist/settings/settingsModel.js +1 -0
- package/dist/stats/accumulatorMeter.d.ts +6 -0
- package/dist/stats/accumulatorMeter.js +6 -0
- package/dist/stats/eventMeter.d.ts +5 -0
- package/dist/stats/eventMeter.js +5 -0
- package/dist/stats/rollCheck.d.ts +5 -0
- package/dist/stats/rollCheck.js +5 -0
- package/dist/stats/spawnLevelStats.d.ts +110 -0
- package/dist/stats/spawnLevelStats.js +140 -0
- package/dist/stats/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -0
- package/dist/stats/statPool.d.ts +70 -0
- package/dist/stats/statPool.js +59 -0
- package/dist/store/changeSignal.d.ts +3 -0
- package/dist/store/changeSignal.js +2 -0
- package/dist/store/defineKeyedStore.d.ts +38 -0
- package/dist/store/defineKeyedStore.js +42 -0
- package/dist/store/defineStore.d.ts +33 -0
- package/dist/store/defineStore.js +35 -0
- package/dist/store/observableKeyedStore.d.ts +7 -0
- package/dist/store/observableKeyedStore.js +35 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -57
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +6 -3
- package/dist/tactics/fallingGrid.d.ts +4 -2
- package/dist/tactics/fallingGrid.js +4 -2
- package/dist/tactics/predictiveQuery.d.ts +3 -0
- package/dist/tactics/predictiveQuery.js +3 -0
- package/dist/tactics/snapshot.d.ts +2 -0
- package/dist/tactics/snapshot.js +2 -0
- package/dist/tactics/surface.d.ts +1 -0
- package/dist/tactics/surface.js +1 -0
- package/dist/tactics/tacticalGrid.d.ts +1 -0
- package/dist/tactics/tacticalGrid.js +1 -0
- package/dist/time/beatClock.d.ts +14 -4
- package/dist/time/beatClock.js +14 -4
- package/dist/time/calendarClock.d.ts +3 -0
- package/dist/time/calendarClock.js +3 -0
- package/dist/time/idleProgress.d.ts +4 -0
- package/dist/time/idleProgress.js +4 -0
- package/dist/time/simClock.d.ts +2 -0
- package/dist/time/simClock.js +20 -5
- package/dist/ui/actionModel.d.ts +110 -0
- package/dist/ui/actionModel.js +159 -0
- package/dist/ui/gameLayout.d.ts +30 -11
- package/dist/ui/gameLayout.js +30 -11
- package/dist/ui/hudDocument.d.ts +114 -0
- package/dist/ui/hudDocument.js +220 -0
- package/dist/ui/hudLayout.d.ts +38 -1
- package/dist/ui/hudLayout.js +220 -17
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/tooltipModel.d.ts +63 -0
- package/dist/ui/tooltipModel.js +82 -0
- package/dist/ui.d.ts +15 -0
- package/dist/ui.js +15 -0
- package/dist/visibility/bounds.d.ts +8 -1
- package/dist/visibility/bounds.js +8 -1
- package/dist/visibility/frustum.d.ts +12 -3
- package/dist/visibility/frustum.js +12 -3
- package/dist/work/jobQueue.d.ts +201 -0
- package/dist/work/jobQueue.js +253 -0
- package/dist/work/unitTraining.d.ts +58 -0
- package/dist/work/unitTraining.js +52 -0
- package/dist/world/authoredEntities.d.ts +29 -0
- package/dist/world/authoredEntities.js +29 -0
- package/dist/world/authoredObjects.d.ts +72 -0
- package/dist/world/authoredObjects.js +81 -0
- package/dist/world/authoredSpawn.d.ts +39 -0
- package/dist/world/authoredSpawn.js +37 -0
- package/dist/world/buildSockets.d.ts +152 -0
- package/dist/world/buildSockets.js +188 -0
- package/dist/world/buildingGenerator.d.ts +18 -0
- package/dist/world/buildingGenerator.js +62 -0
- package/dist/world/buildings.d.ts +5 -0
- package/dist/world/buildings.js +5 -0
- package/dist/world/catenary.d.ts +22 -0
- package/dist/world/catenary.js +69 -0
- package/dist/world/cityBlocks.d.ts +152 -0
- package/dist/world/cityBlocks.js +670 -0
- package/dist/world/cityContent.d.ts +77 -0
- package/dist/world/cityContent.js +261 -0
- package/dist/world/cityGeometry.d.ts +114 -0
- package/dist/world/cityGeometry.js +573 -0
- package/dist/world/cityKind.d.ts +314 -0
- package/dist/world/cityKind.js +1578 -0
- package/dist/world/features.d.ts +133 -10
- package/dist/world/features.js +66 -6
- package/dist/world/footprintGrid.d.ts +59 -0
- package/dist/world/footprintGrid.js +141 -0
- package/dist/world/geometry.d.ts +64 -0
- package/dist/world/geometry.js +94 -0
- package/dist/world/grassKind.d.ts +51 -0
- package/dist/world/grassKind.js +101 -0
- package/dist/world/markers.d.ts +50 -4
- package/dist/world/markers.js +49 -0
- package/dist/world/massing.js +1 -1
- package/dist/world/minimapBake.d.ts +78 -0
- package/dist/world/minimapBake.js +208 -0
- package/dist/world/minimapTrack.d.ts +17 -0
- package/dist/world/minimapTrack.js +22 -0
- package/dist/world/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathNetwork.d.ts +159 -0
- package/dist/world/pathNetwork.js +684 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/place.d.ts +166 -0
- package/dist/world/place.js +96 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +79 -0
- package/dist/world/placement.d.ts +4 -0
- package/dist/world/placement.js +4 -0
- package/dist/world/placementController.d.ts +6 -0
- package/dist/world/placementController.js +6 -0
- package/dist/world/poleLineKind.d.ts +40 -0
- package/dist/world/poleLineKind.js +97 -0
- package/dist/world/polyline.d.ts +34 -0
- package/dist/world/polyline.js +88 -0
- package/dist/world/resourceNode.d.ts +109 -0
- package/dist/world/resourceNode.js +140 -0
- package/dist/world/roads.d.ts +8 -0
- package/dist/world/roads.js +38 -0
- package/dist/world/scatter.js +2 -20
- package/dist/world/scatterRegion.d.ts +164 -0
- package/dist/world/scatterRegion.js +409 -0
- package/dist/world/sceneShapes.d.ts +43 -0
- package/dist/world/sceneShapes.js +1 -0
- package/dist/world/segment.d.ts +27 -0
- package/dist/world/segment.js +43 -0
- package/dist/world/soilKind.d.ts +48 -0
- package/dist/world/soilKind.js +92 -0
- package/dist/world/spatialSample.d.ts +241 -0
- package/dist/world/spatialSample.js +465 -0
- package/dist/world/streets.d.ts +29 -0
- package/dist/world/streets.js +55 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +627 -22
- package/dist/world/terrain.d.ts +164 -20
- package/dist/world/terrain.js +325 -41
- package/dist/world/terrainGuides.d.ts +182 -0
- package/dist/world/terrainGuides.js +343 -0
- package/dist/world/vec2.d.ts +81 -0
- package/dist/world/vec2.js +128 -0
- package/dist/world/vec3.d.ts +49 -0
- package/dist/world/vec3.js +76 -0
- package/dist/world/vegetation.d.ts +71 -0
- package/dist/world/vegetation.js +151 -0
- package/dist/world/visibilityField.d.ts +154 -0
- package/dist/world/visibilityField.js +271 -0
- package/dist/world/volumetricClouds.d.ts +52 -0
- package/dist/world/volumetricClouds.js +43 -0
- package/dist/world/walls.d.ts +9 -0
- package/dist/world/walls.js +9 -0
- package/dist/world/waterKind.d.ts +55 -0
- package/dist/world/waterKind.js +99 -0
- package/dist/world.d.ts +141 -0
- package/dist/world.js +141 -0
- package/package.json +32 -8
- package/skills/game-design/SKILL.md +28 -0
- package/skills/game-design/agents/openai.yaml +4 -0
- package/skills/game-design/references/application-playbook.md +170 -0
- package/skills/game-design/references/field-guide.md +288 -0
- package/skills/jgengine/SKILL.md +54 -0
- package/skills/jgengine/api.md +527 -0
- package/skills/jgengine/capabilities.md +131 -0
- package/skills/jgengine/recipes/minimal-game.md +88 -0
- package/skills/jgengine-combat/SKILL.md +38 -0
- package/skills/jgengine-combat/api.md +585 -0
- package/skills/jgengine-combat/capabilities.md +213 -0
- package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
- package/skills/jgengine-combat/reference.md +108 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1920 -0
- package/skills/jgengine-gameplay/capabilities.md +454 -0
- package/skills/jgengine-gameplay/reference-systems.md +56 -0
- package/skills/jgengine-world/SKILL.md +51 -0
- package/skills/jgengine-world/api.md +3056 -0
- package/skills/jgengine-world/capabilities.md +476 -0
- package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
- package/skills/jgengine-world/reference.md +261 -0
- package/dist/cartridge/runtime.d.ts +0 -15
- package/dist/cartridge/runtime.js +0 -556
- package/dist/cartridge/spec.d.ts +0 -188
- package/dist/cartridge/spec.js +0 -19
- package/dist/cartridge/validate.d.ts +0 -2
- package/dist/cartridge/validate.js +0 -78
- package/dist/store/engineStore.d.ts +0 -22
- package/dist/store/engineStore.js +0 -50
- package/dist/store/features.d.ts +0 -10
- package/dist/store/features.js +0 -23
- package/llms.txt +0 -5389
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getCurrentGameTimestamp, sanitizeGameTimeScale } from "@jgengine/core/time/gameClock";
|
|
2
2
|
const MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
3
3
|
const MONTH_NAMES_FULL = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
4
|
+
/** @internal */
|
|
4
5
|
export function computeGameTime(gameTimestamp) {
|
|
5
6
|
const d = new Date(gameTimestamp);
|
|
6
7
|
const year = d.getFullYear();
|
|
@@ -33,9 +34,11 @@ export function computeGameTime(gameTimestamp) {
|
|
|
33
34
|
formatted,
|
|
34
35
|
};
|
|
35
36
|
}
|
|
37
|
+
/** @internal */
|
|
36
38
|
export function computeClientServerOffset(serverNow, clientNow) {
|
|
37
39
|
return serverNow - clientNow;
|
|
38
40
|
}
|
|
41
|
+
/** @internal */
|
|
39
42
|
export function getGameClockTimestamp(createdAt, serverNow, clientNow, gameTimeScale) {
|
|
40
43
|
const clientOffsetMs = computeClientServerOffset(serverNow, clientNow);
|
|
41
44
|
return getCurrentGameTimestamp(createdAt, clientNow + clientOffsetMs, sanitizeGameTimeScale(gameTimeScale));
|
|
@@ -7,6 +7,7 @@ export interface IdleWindow {
|
|
|
7
7
|
effectiveSeconds: number;
|
|
8
8
|
capped: boolean;
|
|
9
9
|
}
|
|
10
|
+
/** @internal */
|
|
10
11
|
export declare function idleWindow(lastSeenMs: number, nowMs: number, config?: IdleWindowConfig): IdleWindow;
|
|
11
12
|
export interface LinearCatchUpInput {
|
|
12
13
|
current: number;
|
|
@@ -14,6 +15,7 @@ export interface LinearCatchUpInput {
|
|
|
14
15
|
min?: number;
|
|
15
16
|
max?: number;
|
|
16
17
|
}
|
|
18
|
+
/** @internal */
|
|
17
19
|
export declare function linearCatchUp(seconds: number, input: LinearCatchUpInput): number;
|
|
18
20
|
export interface ExponentialCatchUpInput {
|
|
19
21
|
current: number;
|
|
@@ -21,9 +23,11 @@ export interface ExponentialCatchUpInput {
|
|
|
21
23
|
min?: number;
|
|
22
24
|
max?: number;
|
|
23
25
|
}
|
|
26
|
+
/** @internal */
|
|
24
27
|
export declare function exponentialCatchUp(seconds: number, input: ExponentialCatchUpInput): number;
|
|
25
28
|
export interface SteppedCatchUpResult {
|
|
26
29
|
steps: number;
|
|
27
30
|
remainderSeconds: number;
|
|
28
31
|
}
|
|
32
|
+
/** @internal */
|
|
29
33
|
export declare function steppedCatchUp(seconds: number, stepSeconds: number, step: (index: number) => void, maxSteps?: number): SteppedCatchUpResult;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export function idleWindow(lastSeenMs, nowMs, config = {}) {
|
|
2
3
|
const elapsedSeconds = Math.max(0, (nowMs - lastSeenMs) / 1000);
|
|
3
4
|
const capped = config.maxSeconds !== undefined && elapsedSeconds > config.maxSeconds;
|
|
@@ -9,17 +10,20 @@ export function idleWindow(lastSeenMs, nowMs, config = {}) {
|
|
|
9
10
|
capped,
|
|
10
11
|
};
|
|
11
12
|
}
|
|
13
|
+
/** @internal */
|
|
12
14
|
export function linearCatchUp(seconds, input) {
|
|
13
15
|
const clampedSeconds = Math.max(0, seconds);
|
|
14
16
|
const value = input.current + input.ratePerSecond * clampedSeconds;
|
|
15
17
|
return Math.min(input.max ?? Number.POSITIVE_INFINITY, Math.max(input.min ?? Number.NEGATIVE_INFINITY, value));
|
|
16
18
|
}
|
|
19
|
+
/** @internal */
|
|
17
20
|
export function exponentialCatchUp(seconds, input) {
|
|
18
21
|
const clampedSeconds = Math.max(0, seconds);
|
|
19
22
|
const factor = Math.max(0, input.factorPerSecond);
|
|
20
23
|
const value = input.current * factor ** clampedSeconds;
|
|
21
24
|
return Math.min(input.max ?? Number.POSITIVE_INFINITY, Math.max(input.min ?? Number.NEGATIVE_INFINITY, value));
|
|
22
25
|
}
|
|
26
|
+
/** @internal */
|
|
23
27
|
export function steppedCatchUp(seconds, stepSeconds, step, maxSteps) {
|
|
24
28
|
if (stepSeconds <= 0 || seconds <= 0) {
|
|
25
29
|
return { steps: 0, remainderSeconds: Math.max(0, seconds) };
|
package/dist/time/simClock.d.ts
CHANGED
|
@@ -51,6 +51,8 @@ export interface SimClock {
|
|
|
51
51
|
advance(realDt: number): number;
|
|
52
52
|
now(): number;
|
|
53
53
|
snapshot(): ClockSnapshot;
|
|
54
|
+
/** Restore clock position — game-time, pause state, and speed multipliers — from a {@link ClockSnapshot} for whole-world save/load. Live timers registered via `after`/`every`/`at` are unaffected. */
|
|
55
|
+
hydrate(snapshot: ClockSnapshot): void;
|
|
54
56
|
calendar(): CalendarTime;
|
|
55
57
|
isPaused(): boolean;
|
|
56
58
|
speed(): number;
|
package/dist/time/simClock.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { SECONDS_PER_GAME_DAY } from "./gameClock.js";
|
|
2
|
-
const
|
|
2
|
+
const MAX_TIMER_FIRES_PER_ADVANCE = 10_000;
|
|
3
|
+
function requireFiniteTimerValue(label, value) {
|
|
4
|
+
if (!Number.isFinite(value)) {
|
|
5
|
+
throw new Error(`SimClock ${label} must be finite, got ${value}`);
|
|
6
|
+
}
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
3
9
|
export function createSimClock(options = {}) {
|
|
4
10
|
const config = options.config ?? {};
|
|
5
11
|
const onChange = options.onChange ?? (() => { });
|
|
@@ -62,7 +68,7 @@ export function createSimClock(options = {}) {
|
|
|
62
68
|
}
|
|
63
69
|
timer.callback();
|
|
64
70
|
fires += 1;
|
|
65
|
-
if (fires >=
|
|
71
|
+
if (fires >= MAX_TIMER_FIRES_PER_ADVANCE)
|
|
66
72
|
return;
|
|
67
73
|
}
|
|
68
74
|
}
|
|
@@ -121,10 +127,19 @@ export function createSimClock(options = {}) {
|
|
|
121
127
|
timers.delete(id);
|
|
122
128
|
};
|
|
123
129
|
}
|
|
130
|
+
function hydrate(state) {
|
|
131
|
+
now = state.now;
|
|
132
|
+
paused = state.paused;
|
|
133
|
+
playSpeed = state.playSpeed;
|
|
134
|
+
timescale = state.timescale;
|
|
135
|
+
displayMinute = minuteIndex(now, dayLength);
|
|
136
|
+
onChange();
|
|
137
|
+
}
|
|
124
138
|
return {
|
|
125
139
|
advance,
|
|
126
140
|
now: () => now,
|
|
127
141
|
calendar,
|
|
142
|
+
hydrate,
|
|
128
143
|
snapshot: () => ({
|
|
129
144
|
now,
|
|
130
145
|
paused,
|
|
@@ -144,12 +159,12 @@ export function createSimClock(options = {}) {
|
|
|
144
159
|
cycleSpeed,
|
|
145
160
|
timescale: () => timescale,
|
|
146
161
|
setTimescale,
|
|
147
|
-
after: (seconds, callback) => register(now + Math.max(0, seconds), null, callback),
|
|
162
|
+
after: (seconds, callback) => register(now + Math.max(0, requireFiniteTimerValue("after(seconds)", seconds)), null, callback),
|
|
148
163
|
every: (seconds, callback) => {
|
|
149
|
-
const interval = Math.max(Number.EPSILON, seconds);
|
|
164
|
+
const interval = Math.max(Number.EPSILON, requireFiniteTimerValue("every(seconds)", seconds));
|
|
150
165
|
return register(now + interval, interval, callback);
|
|
151
166
|
},
|
|
152
|
-
at: (time, callback) => register(time, null, callback),
|
|
167
|
+
at: (time, callback) => register(requireFiniteTimerValue("at(time)", time), null, callback),
|
|
153
168
|
};
|
|
154
169
|
}
|
|
155
170
|
function minuteIndex(seconds, dayLength) {
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless view model for a contextual action collection — the data layer behind an RTS command
|
|
3
|
+
* card, an ability action bar, a build menu, or a radial. It carries *what the buttons mean*
|
|
4
|
+
* (label, hotkey, cost, cooldown, disabled reasons, toggle state) with zero rendering opinion, so a
|
|
5
|
+
* game keeps layout, dimensions, hotkeys, catalog-id mapping, renderer, and chrome caller-owned. The
|
|
6
|
+
* React renderers in `@jgengine/react/actionHud` consume this; a game can swap either without
|
|
7
|
+
* forking the logic here.
|
|
8
|
+
*/
|
|
9
|
+
/** A spendable-resource line on an action (e.g. `40` mana). `met` is false only when `available` is known and short. */
|
|
10
|
+
export interface ActionCost {
|
|
11
|
+
resourceId: string;
|
|
12
|
+
amount: number;
|
|
13
|
+
/** Current pool, when the caller knows it — drives {@link ActionCost.met}. Omit when unknown. */
|
|
14
|
+
available?: number;
|
|
15
|
+
/** True unless `available` is known and below `amount`. */
|
|
16
|
+
met: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Cooldown state for an action, expressed so a radial sweep or countdown can render directly. */
|
|
19
|
+
export interface ActionCooldown {
|
|
20
|
+
remainingMs: number;
|
|
21
|
+
totalMs: number;
|
|
22
|
+
/** Remaining share of the cooldown, `0..1` — the fraction a radial wipe should still cover. */
|
|
23
|
+
fraction: number;
|
|
24
|
+
ready: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** A single blocking reason: a stable machine `code` plus caller-facing `message`. */
|
|
27
|
+
export interface ActionReason {
|
|
28
|
+
/** Stable tag for styling/branching, e.g. `"cooldown" | "cost" | "range" | "disabled"`. */
|
|
29
|
+
code: string;
|
|
30
|
+
message: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A caller-authored contextual action — the DATA input to the model. Every field except `id` is
|
|
34
|
+
* optional so a build button, a stance toggle, and a cooldown ability all use the same shape.
|
|
35
|
+
* Catalog-id mapping (turning `icon`/`label` into art and copy) stays caller-owned.
|
|
36
|
+
*/
|
|
37
|
+
export interface ActionDef {
|
|
38
|
+
id: string;
|
|
39
|
+
label?: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
/** Icon id / glyph the caller maps to a catalog; the model only carries it through. */
|
|
42
|
+
icon?: string;
|
|
43
|
+
/** Human hotkey label (e.g. `"Q"`, `"1"`). Matched case-insensitively by {@link actionByHotkey}. */
|
|
44
|
+
hotkey?: string;
|
|
45
|
+
/** Section id for grouping a large card into rows/tabs; caller-owned. */
|
|
46
|
+
group?: string;
|
|
47
|
+
cooldown?: ActionCooldown;
|
|
48
|
+
costs?: readonly ActionCost[];
|
|
49
|
+
/** Toggle/stance state — a mode that is currently on. */
|
|
50
|
+
active?: boolean;
|
|
51
|
+
/** Hard-disable regardless of cost/cooldown (not yet researched, no valid target). */
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
/** Extra caller reasons (out of range, needs tech). Merged after the derived cost/cooldown ones. */
|
|
54
|
+
reasons?: readonly ActionReason[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A resolved action view model — availability computed once from cooldown, cost, `disabled`, and any
|
|
58
|
+
* caller reasons. `enabled` is the single truth a renderer gates interaction on; `reasons` is the
|
|
59
|
+
* ordered explanation (cooldown, then unmet costs, then caller reasons, then a generic disable).
|
|
60
|
+
*/
|
|
61
|
+
export interface ResolvedAction {
|
|
62
|
+
id: string;
|
|
63
|
+
label: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
icon?: string;
|
|
66
|
+
hotkey?: string;
|
|
67
|
+
group?: string;
|
|
68
|
+
active: boolean;
|
|
69
|
+
enabled: boolean;
|
|
70
|
+
cooldown: ActionCooldown | null;
|
|
71
|
+
costs: readonly ActionCost[];
|
|
72
|
+
reasons: readonly ActionReason[];
|
|
73
|
+
}
|
|
74
|
+
/** Build an {@link ActionCooldown} from remaining/total milliseconds. `ready` when nothing remains. */
|
|
75
|
+
export declare function actionCooldown(remainingMs: number, totalMs: number): ActionCooldown;
|
|
76
|
+
/**
|
|
77
|
+
* Build an {@link ActionCooldown} from remaining milliseconds and a known remaining fraction — the
|
|
78
|
+
* shape adapters get from sources (like an ability snapshot) that report a fraction but not a total.
|
|
79
|
+
*/
|
|
80
|
+
export declare function actionCooldownFromFraction(remainingMs: number, fraction: number): ActionCooldown;
|
|
81
|
+
/** Build an {@link ActionCost}. `met` is true unless `available` is provided and below `amount`. */
|
|
82
|
+
export declare function actionCost(resourceId: string, amount: number, available?: number): ActionCost;
|
|
83
|
+
/**
|
|
84
|
+
* Resolve one {@link ActionDef} into a {@link ResolvedAction}: normalize label, compute `enabled`,
|
|
85
|
+
* and order the blocking `reasons`. Pure — the same input always yields the same view model.
|
|
86
|
+
*/
|
|
87
|
+
export declare function resolveAction(def: ActionDef): ResolvedAction;
|
|
88
|
+
/** Resolve an ordered list of actions, preserving input order. */
|
|
89
|
+
export declare function resolveActionCollection(defs: readonly ActionDef[]): ResolvedAction[];
|
|
90
|
+
/**
|
|
91
|
+
* Find the action whose `hotkey` matches `key`, case-insensitively — the keyboard-shortcut router for
|
|
92
|
+
* an action bar. Returns the first match's id, or null. Matching by hotkey does not consider
|
|
93
|
+
* `enabled`; the caller decides whether to fire a disabled action's feedback.
|
|
94
|
+
*/
|
|
95
|
+
export declare function actionByHotkey(actions: readonly ResolvedAction[], key: string): string | null;
|
|
96
|
+
/** A focus move for keyboard/controller grid navigation over an action collection. */
|
|
97
|
+
export type FocusDirection = "left" | "right" | "up" | "down" | "next" | "prev" | "first" | "last";
|
|
98
|
+
/** Options for {@link moveGridFocus}. */
|
|
99
|
+
export interface GridFocusOptions {
|
|
100
|
+
/** Wrap around edges instead of clamping (default false). */
|
|
101
|
+
wrap?: boolean;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Pure grid focus math for keyboard and controller navigation of an action card laid out in
|
|
105
|
+
* `columns`-wide rows. Given the current index (`-1` for none) it returns the next index, clamped to
|
|
106
|
+
* `[0, count)` — or wrapped when `wrap` is set. `left/right` move within/across columns, `up/down`
|
|
107
|
+
* across rows, `next/prev` walk the flat order, `first/last` jump to the ends. Renderer-agnostic:
|
|
108
|
+
* radial and list layouts pass `columns: 1` (or `count`) to get sensible 1-D stepping.
|
|
109
|
+
*/
|
|
110
|
+
export declare function moveGridFocus(current: number, count: number, columns: number, dir: FocusDirection, options?: GridFocusOptions): number;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless view model for a contextual action collection — the data layer behind an RTS command
|
|
3
|
+
* card, an ability action bar, a build menu, or a radial. It carries *what the buttons mean*
|
|
4
|
+
* (label, hotkey, cost, cooldown, disabled reasons, toggle state) with zero rendering opinion, so a
|
|
5
|
+
* game keeps layout, dimensions, hotkeys, catalog-id mapping, renderer, and chrome caller-owned. The
|
|
6
|
+
* React renderers in `@jgengine/react/actionHud` consume this; a game can swap either without
|
|
7
|
+
* forking the logic here.
|
|
8
|
+
*/
|
|
9
|
+
const clamp01 = (value) => (value < 0 ? 0 : value > 1 ? 1 : value);
|
|
10
|
+
/** Build an {@link ActionCooldown} from remaining/total milliseconds. `ready` when nothing remains. */
|
|
11
|
+
export function actionCooldown(remainingMs, totalMs) {
|
|
12
|
+
const remaining = Math.max(0, remainingMs);
|
|
13
|
+
const total = Math.max(0, totalMs);
|
|
14
|
+
return {
|
|
15
|
+
remainingMs: remaining,
|
|
16
|
+
totalMs: total,
|
|
17
|
+
fraction: total <= 0 ? 0 : clamp01(remaining / total),
|
|
18
|
+
ready: remaining <= 0,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build an {@link ActionCooldown} from remaining milliseconds and a known remaining fraction — the
|
|
23
|
+
* shape adapters get from sources (like an ability snapshot) that report a fraction but not a total.
|
|
24
|
+
*/
|
|
25
|
+
export function actionCooldownFromFraction(remainingMs, fraction) {
|
|
26
|
+
const remaining = Math.max(0, remainingMs);
|
|
27
|
+
const frac = clamp01(fraction);
|
|
28
|
+
return {
|
|
29
|
+
remainingMs: remaining,
|
|
30
|
+
totalMs: frac > 0 ? Math.round(remaining / frac) : remaining,
|
|
31
|
+
fraction: frac,
|
|
32
|
+
ready: remaining <= 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Build an {@link ActionCost}. `met` is true unless `available` is provided and below `amount`. */
|
|
36
|
+
export function actionCost(resourceId, amount, available) {
|
|
37
|
+
const cost = {
|
|
38
|
+
resourceId,
|
|
39
|
+
amount,
|
|
40
|
+
met: available === undefined ? true : available >= amount,
|
|
41
|
+
};
|
|
42
|
+
if (available !== undefined)
|
|
43
|
+
cost.available = available;
|
|
44
|
+
return cost;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve one {@link ActionDef} into a {@link ResolvedAction}: normalize label, compute `enabled`,
|
|
48
|
+
* and order the blocking `reasons`. Pure — the same input always yields the same view model.
|
|
49
|
+
*/
|
|
50
|
+
export function resolveAction(def) {
|
|
51
|
+
const costs = def.costs ?? [];
|
|
52
|
+
const reasons = [];
|
|
53
|
+
const cooldown = def.cooldown ?? null;
|
|
54
|
+
if (cooldown !== null && !cooldown.ready) {
|
|
55
|
+
reasons.push({ code: "cooldown", message: cooldownMessage(cooldown) });
|
|
56
|
+
}
|
|
57
|
+
for (const cost of costs) {
|
|
58
|
+
if (!cost.met)
|
|
59
|
+
reasons.push({ code: "cost", message: costMessage(cost) });
|
|
60
|
+
}
|
|
61
|
+
for (const reason of def.reasons ?? [])
|
|
62
|
+
reasons.push(reason);
|
|
63
|
+
if (def.disabled === true && reasons.length === 0) {
|
|
64
|
+
reasons.push({ code: "disabled", message: "Unavailable" });
|
|
65
|
+
}
|
|
66
|
+
const enabled = def.disabled !== true && reasons.length === 0;
|
|
67
|
+
const resolved = {
|
|
68
|
+
id: def.id,
|
|
69
|
+
label: def.label ?? def.id,
|
|
70
|
+
active: def.active === true,
|
|
71
|
+
enabled,
|
|
72
|
+
cooldown,
|
|
73
|
+
costs,
|
|
74
|
+
reasons,
|
|
75
|
+
};
|
|
76
|
+
if (def.description !== undefined)
|
|
77
|
+
resolved.description = def.description;
|
|
78
|
+
if (def.icon !== undefined)
|
|
79
|
+
resolved.icon = def.icon;
|
|
80
|
+
if (def.hotkey !== undefined)
|
|
81
|
+
resolved.hotkey = def.hotkey;
|
|
82
|
+
if (def.group !== undefined)
|
|
83
|
+
resolved.group = def.group;
|
|
84
|
+
return resolved;
|
|
85
|
+
}
|
|
86
|
+
/** Resolve an ordered list of actions, preserving input order. */
|
|
87
|
+
export function resolveActionCollection(defs) {
|
|
88
|
+
return defs.map(resolveAction);
|
|
89
|
+
}
|
|
90
|
+
/** @internal Default cooldown reason copy: `Ready in 2.4s`. */
|
|
91
|
+
function cooldownMessage(cooldown) {
|
|
92
|
+
return `Ready in ${(cooldown.remainingMs / 1000).toFixed(1)}s`;
|
|
93
|
+
}
|
|
94
|
+
/** @internal Default unmet-cost reason copy: `Needs 40 mana`. */
|
|
95
|
+
function costMessage(cost) {
|
|
96
|
+
return `Needs ${cost.amount} ${cost.resourceId}`;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Find the action whose `hotkey` matches `key`, case-insensitively — the keyboard-shortcut router for
|
|
100
|
+
* an action bar. Returns the first match's id, or null. Matching by hotkey does not consider
|
|
101
|
+
* `enabled`; the caller decides whether to fire a disabled action's feedback.
|
|
102
|
+
*/
|
|
103
|
+
export function actionByHotkey(actions, key) {
|
|
104
|
+
const needle = key.toLowerCase();
|
|
105
|
+
for (const action of actions) {
|
|
106
|
+
if (action.hotkey !== undefined && action.hotkey.toLowerCase() === needle)
|
|
107
|
+
return action.id;
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Pure grid focus math for keyboard and controller navigation of an action card laid out in
|
|
113
|
+
* `columns`-wide rows. Given the current index (`-1` for none) it returns the next index, clamped to
|
|
114
|
+
* `[0, count)` — or wrapped when `wrap` is set. `left/right` move within/across columns, `up/down`
|
|
115
|
+
* across rows, `next/prev` walk the flat order, `first/last` jump to the ends. Renderer-agnostic:
|
|
116
|
+
* radial and list layouts pass `columns: 1` (or `count`) to get sensible 1-D stepping.
|
|
117
|
+
*/
|
|
118
|
+
export function moveGridFocus(current, count, columns, dir, options) {
|
|
119
|
+
if (count <= 0)
|
|
120
|
+
return -1;
|
|
121
|
+
const cols = Math.max(1, Math.floor(columns));
|
|
122
|
+
const wrap = options?.wrap === true;
|
|
123
|
+
if (dir === "first")
|
|
124
|
+
return 0;
|
|
125
|
+
if (dir === "last")
|
|
126
|
+
return count - 1;
|
|
127
|
+
if (current < 0) {
|
|
128
|
+
return dir === "prev" || dir === "left" || dir === "up" ? count - 1 : 0;
|
|
129
|
+
}
|
|
130
|
+
const clampIndex = (index) => Math.max(0, Math.min(count - 1, index));
|
|
131
|
+
if (dir === "next")
|
|
132
|
+
return current + 1 >= count ? (wrap ? 0 : count - 1) : current + 1;
|
|
133
|
+
if (dir === "prev")
|
|
134
|
+
return current - 1 < 0 ? (wrap ? count - 1 : 0) : current - 1;
|
|
135
|
+
const row = Math.floor(current / cols);
|
|
136
|
+
const col = current % cols;
|
|
137
|
+
if (dir === "right" || dir === "left") {
|
|
138
|
+
const rowStart = row * cols;
|
|
139
|
+
const rowEnd = Math.min(count - 1, rowStart + cols - 1);
|
|
140
|
+
const width = rowEnd - rowStart + 1;
|
|
141
|
+
if (width <= 1)
|
|
142
|
+
return current;
|
|
143
|
+
const nextCol = dir === "right" ? col + 1 : col - 1;
|
|
144
|
+
if (nextCol < 0)
|
|
145
|
+
return wrap ? rowEnd : current;
|
|
146
|
+
if (nextCol > rowEnd - rowStart)
|
|
147
|
+
return wrap ? rowStart : current;
|
|
148
|
+
return rowStart + nextCol;
|
|
149
|
+
}
|
|
150
|
+
// up / down
|
|
151
|
+
const nextRow = dir === "down" ? row + 1 : row - 1;
|
|
152
|
+
const rowCount = Math.ceil(count / cols);
|
|
153
|
+
if (nextRow < 0)
|
|
154
|
+
return wrap ? clampIndex((rowCount - 1) * cols + col) : current;
|
|
155
|
+
if (nextRow > rowCount - 1)
|
|
156
|
+
return wrap ? col : current;
|
|
157
|
+
const target = nextRow * cols + col;
|
|
158
|
+
return target >= count ? (dir === "down" ? current : clampIndex(target)) : target;
|
|
159
|
+
}
|
package/dist/ui/gameLayout.d.ts
CHANGED
|
@@ -23,17 +23,29 @@ export interface LayoutRect {
|
|
|
23
23
|
right: number;
|
|
24
24
|
bottom: number;
|
|
25
25
|
}
|
|
26
|
-
/** Width of a rect (clamped to ≥0).
|
|
26
|
+
/** Width of a rect (clamped to ≥0).
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
27
29
|
export declare function rectWidth(rect: LayoutRect): number;
|
|
28
|
-
/** Height of a rect (clamped to ≥0).
|
|
30
|
+
/** Height of a rect (clamped to ≥0).
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
29
33
|
export declare function rectHeight(rect: LayoutRect): number;
|
|
30
|
-
/** Area of a rect in px².
|
|
34
|
+
/** Area of a rect in px².
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
31
37
|
export declare function rectArea(rect: LayoutRect): number;
|
|
32
|
-
/** Do the two rectangles share any interior area? Touching edges do not count.
|
|
38
|
+
/** Do the two rectangles share any interior area? Touching edges do not count.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
33
41
|
export declare function intersects(a: LayoutRect, b: LayoutRect): boolean;
|
|
34
|
-
/** Overlapping area in px²; 0 when the rectangles don't intersect.
|
|
42
|
+
/** Overlapping area in px²; 0 when the rectangles don't intersect.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
35
45
|
export declare function overlapArea(a: LayoutRect, b: LayoutRect): number;
|
|
36
|
-
/** Portrait when taller than wide, else landscape.
|
|
46
|
+
/** Portrait when taller than wide, else landscape.
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
37
49
|
export declare function orientationOf(width: number, height: number): LayoutOrientation;
|
|
38
50
|
/** Inputs to `resolveLayoutMode`. */
|
|
39
51
|
export interface LayoutModeInput {
|
|
@@ -52,9 +64,12 @@ export interface LayoutModeInput {
|
|
|
52
64
|
* desktop layout: a coarse-pointer device on a game that supports mobile is
|
|
53
65
|
* always a `mobile-*` mode, split by live orientation; everything else is a
|
|
54
66
|
* desktop mode split by width.
|
|
55
|
-
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
56
69
|
export declare function resolveLayoutMode(input: LayoutModeInput): GameLayoutMode;
|
|
57
|
-
/** Whether a mode is one of the phone modes.
|
|
70
|
+
/** Whether a mode is one of the phone modes.
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
58
73
|
export declare function isMobileMode(mode: GameLayoutMode): boolean;
|
|
59
74
|
/** What kind of UI a registered region belongs to. */
|
|
60
75
|
export type LayoutRegionKind = "hud" | "control" | "system" | "screen";
|
|
@@ -97,15 +112,19 @@ export interface DetectCollisionsOptions {
|
|
|
97
112
|
* regions. A pair is skipped when either side's policy is `allow`, when either
|
|
98
113
|
* opts into the other via `allowOverlapWith`, when they share a
|
|
99
114
|
* `collisionGroup`, or when the overlap is below `minArea`.
|
|
100
|
-
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
101
117
|
export declare function detectLayoutCollisions(regions: readonly LayoutRegion[], options?: DetectCollisionsOptions): LayoutCollision[];
|
|
102
|
-
/** Human-readable diagnostic block for a set of collisions (empty string when there are none).
|
|
118
|
+
/** Human-readable diagnostic block for a set of collisions (empty string when there are none).
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
103
121
|
export declare function formatLayoutCollisions(collisions: readonly LayoutCollision[]): string;
|
|
104
122
|
/**
|
|
105
123
|
* The usable gameplay rectangle after reserving physical zones for touch
|
|
106
124
|
* controls and system UI. Starts from the safe-area-inset viewport and carves
|
|
107
125
|
* each reserved zone from whichever edge it hugs.
|
|
108
|
-
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
109
128
|
export declare function computeGameplayRect(viewport: LayoutRect, safeArea: Insets, reserved: readonly LayoutRect[]): LayoutRect;
|
|
110
129
|
/** The shared live geometry the engine allocates once and every UI subsystem reads. */
|
|
111
130
|
export interface GameViewportLayout {
|
package/dist/ui/gameLayout.js
CHANGED
|
@@ -6,29 +6,41 @@
|
|
|
6
6
|
*/
|
|
7
7
|
/** All-zero insets. */
|
|
8
8
|
export const ZERO_INSETS = { top: 0, right: 0, bottom: 0, left: 0 };
|
|
9
|
-
/** Width of a rect (clamped to ≥0).
|
|
9
|
+
/** Width of a rect (clamped to ≥0).
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
10
12
|
export function rectWidth(rect) {
|
|
11
13
|
return Math.max(0, rect.right - rect.left);
|
|
12
14
|
}
|
|
13
|
-
/** Height of a rect (clamped to ≥0).
|
|
15
|
+
/** Height of a rect (clamped to ≥0).
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
14
18
|
export function rectHeight(rect) {
|
|
15
19
|
return Math.max(0, rect.bottom - rect.top);
|
|
16
20
|
}
|
|
17
|
-
/** Area of a rect in px².
|
|
21
|
+
/** Area of a rect in px².
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
18
24
|
export function rectArea(rect) {
|
|
19
25
|
return rectWidth(rect) * rectHeight(rect);
|
|
20
26
|
}
|
|
21
|
-
/** Do the two rectangles share any interior area? Touching edges do not count.
|
|
27
|
+
/** Do the two rectangles share any interior area? Touching edges do not count.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
22
30
|
export function intersects(a, b) {
|
|
23
31
|
return a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top;
|
|
24
32
|
}
|
|
25
|
-
/** Overlapping area in px²; 0 when the rectangles don't intersect.
|
|
33
|
+
/** Overlapping area in px²; 0 when the rectangles don't intersect.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
26
36
|
export function overlapArea(a, b) {
|
|
27
37
|
const w = Math.min(a.right, b.right) - Math.max(a.left, b.left);
|
|
28
38
|
const h = Math.min(a.bottom, b.bottom) - Math.max(a.top, b.top);
|
|
29
39
|
return w > 0 && h > 0 ? w * h : 0;
|
|
30
40
|
}
|
|
31
|
-
/** Portrait when taller than wide, else landscape.
|
|
41
|
+
/** Portrait when taller than wide, else landscape.
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
32
44
|
export function orientationOf(width, height) {
|
|
33
45
|
return height > width ? "portrait" : "landscape";
|
|
34
46
|
}
|
|
@@ -38,7 +50,8 @@ const DEFAULT_COMPACT_WIDTH = 900;
|
|
|
38
50
|
* desktop layout: a coarse-pointer device on a game that supports mobile is
|
|
39
51
|
* always a `mobile-*` mode, split by live orientation; everything else is a
|
|
40
52
|
* desktop mode split by width.
|
|
41
|
-
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
42
55
|
export function resolveLayoutMode(input) {
|
|
43
56
|
const orientation = orientationOf(input.width, input.height);
|
|
44
57
|
const mobile = input.coarsePointer && (input.mobileSupported ?? true);
|
|
@@ -47,7 +60,9 @@ export function resolveLayoutMode(input) {
|
|
|
47
60
|
const compactWidth = input.compactWidth ?? DEFAULT_COMPACT_WIDTH;
|
|
48
61
|
return input.width < compactWidth ? "desktop-compact" : "desktop-wide";
|
|
49
62
|
}
|
|
50
|
-
/** Whether a mode is one of the phone modes.
|
|
63
|
+
/** Whether a mode is one of the phone modes.
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
51
66
|
export function isMobileMode(mode) {
|
|
52
67
|
return mode === "mobile-portrait" || mode === "mobile-landscape";
|
|
53
68
|
}
|
|
@@ -66,7 +81,8 @@ const DEFAULT_MIN_AREA = 64;
|
|
|
66
81
|
* regions. A pair is skipped when either side's policy is `allow`, when either
|
|
67
82
|
* opts into the other via `allowOverlapWith`, when they share a
|
|
68
83
|
* `collisionGroup`, or when the overlap is below `minArea`.
|
|
69
|
-
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
70
86
|
export function detectLayoutCollisions(regions, options) {
|
|
71
87
|
const minArea = options?.minArea ?? DEFAULT_MIN_AREA;
|
|
72
88
|
const out = [];
|
|
@@ -92,7 +108,9 @@ function withThousands(n) {
|
|
|
92
108
|
.toString()
|
|
93
109
|
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
94
110
|
}
|
|
95
|
-
/** Human-readable diagnostic block for a set of collisions (empty string when there are none).
|
|
111
|
+
/** Human-readable diagnostic block for a set of collisions (empty string when there are none).
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
96
114
|
export function formatLayoutCollisions(collisions) {
|
|
97
115
|
if (collisions.length === 0)
|
|
98
116
|
return "";
|
|
@@ -103,7 +121,8 @@ export function formatLayoutCollisions(collisions) {
|
|
|
103
121
|
* The usable gameplay rectangle after reserving physical zones for touch
|
|
104
122
|
* controls and system UI. Starts from the safe-area-inset viewport and carves
|
|
105
123
|
* each reserved zone from whichever edge it hugs.
|
|
106
|
-
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
107
126
|
export function computeGameplayRect(viewport, safeArea, reserved) {
|
|
108
127
|
let top = viewport.top + safeArea.top;
|
|
109
128
|
let bottom = viewport.bottom - safeArea.bottom;
|