@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
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { applyEditorDocumentOverlay, createEmptyEditorDocument, editorDocumentExtras, extractEditorFragment, mergeEditorDocuments, } from "./document.js";
|
|
2
|
+
/**
|
|
3
|
+
* A sharded **world**: a scene that is no longer one monolithic `editor.scene.json` but a manifest
|
|
4
|
+
* plus spatially-partitioned shard documents. A single-file game is the degenerate one-shard case,
|
|
5
|
+
* so nothing pays for scale it does not have. The shard/overlay documents are the exact
|
|
6
|
+
* {@link EditorDocument} format loaders already consume — this module is composition over
|
|
7
|
+
* `mergeEditorDocuments` / `extractEditorFragment` / `editorDocumentBounds`, not a new format.
|
|
8
|
+
*/
|
|
9
|
+
/** The manifest `kind` discriminator — a world folder's `world.json`. */
|
|
10
|
+
export const WORLD_MANIFEST_KIND = "world";
|
|
11
|
+
/** True when a shard is resident regardless of any spatial query (unbounded or explicitly `"always"`). */
|
|
12
|
+
function isAlwaysResident(shard) {
|
|
13
|
+
return shard.residency === "always" || shard.bounds === undefined;
|
|
14
|
+
}
|
|
15
|
+
/** Closest-point disc↔AABB overlap test on the XZ plane. */
|
|
16
|
+
function discIntersectsBounds(cx, cz, radius, bounds) {
|
|
17
|
+
const qx = Math.max(bounds.min[0], Math.min(cx, bounds.max[0]));
|
|
18
|
+
const qz = Math.max(bounds.min[1], Math.min(cz, bounds.max[1]));
|
|
19
|
+
const dx = cx - qx;
|
|
20
|
+
const dz = cz - qz;
|
|
21
|
+
return dx * dx + dz * dz <= radius * radius;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* True when a shard should be resident for a query: always-resident shards always, bounded shards
|
|
25
|
+
* only when the query disc (`center` ± `radius`) overlaps their footprint.
|
|
26
|
+
* @capability world-shards select shards for a neighborhood by spatial query
|
|
27
|
+
*/
|
|
28
|
+
export function shardMatchesQuery(shard, query) {
|
|
29
|
+
if (isAlwaysResident(shard))
|
|
30
|
+
return true;
|
|
31
|
+
return discIntersectsBounds(query.center.x, query.center.z, query.radius ?? 0, shard.bounds);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The shards a query needs — always-resident shards plus every bounded shard whose footprint the
|
|
35
|
+
* query disc overlaps, in manifest order. With no query every shard is selected (load the planet),
|
|
36
|
+
* so a one-shard game and an unqueried load behave exactly as a monolithic document does today.
|
|
37
|
+
* @capability world-shards select shards for a neighborhood by spatial query
|
|
38
|
+
*/
|
|
39
|
+
export function selectWorldShards(manifest, query) {
|
|
40
|
+
if (query === undefined)
|
|
41
|
+
return [...manifest.shards];
|
|
42
|
+
return manifest.shards.filter((shard) => shardMatchesQuery(shard, query));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Loads the live neighborhood document for a query: reads each selected shard through `resolve`,
|
|
46
|
+
* applies its overlay (if any) on top, then merges them into one {@link EditorDocument} downstream
|
|
47
|
+
* consumers (`placeAuthoredObjects`, `collectAuthoredTriggers`, scatter, …) read unchanged. The
|
|
48
|
+
* monolith becomes an internal detail of the loader; a one-shard world yields exactly that shard.
|
|
49
|
+
* @capability world-shards merge the shards for a neighborhood into one live document
|
|
50
|
+
*/
|
|
51
|
+
export function loadWorldDocument(manifest, resolve, query) {
|
|
52
|
+
const shards = selectWorldShards(manifest, query);
|
|
53
|
+
const docs = [];
|
|
54
|
+
for (const shard of shards) {
|
|
55
|
+
const base = resolve(shard.file);
|
|
56
|
+
if (base === null)
|
|
57
|
+
continue;
|
|
58
|
+
if (shard.overlay === undefined) {
|
|
59
|
+
docs.push(base);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const overlay = resolve(shard.overlay);
|
|
63
|
+
docs.push(overlay === null ? base : applyEditorDocumentOverlay(base, overlay));
|
|
64
|
+
}
|
|
65
|
+
if (docs.length === 0)
|
|
66
|
+
return createEmptyEditorDocument();
|
|
67
|
+
return mergeEditorDocuments(...docs);
|
|
68
|
+
}
|
|
69
|
+
/** The always-resident base shard id used by {@link splitEditorDocumentIntoShards}. */
|
|
70
|
+
export const WORLD_BASE_SHARD_ID = "base";
|
|
71
|
+
/** Representative XZ point for an object, used to assign it to a grid cell. */
|
|
72
|
+
function objectCell(x, z, cellSize) {
|
|
73
|
+
return { gx: Math.floor(x / cellSize), gz: Math.floor(z / cellSize) };
|
|
74
|
+
}
|
|
75
|
+
function pathCentroid(points) {
|
|
76
|
+
if (points.length === 0)
|
|
77
|
+
return { x: 0, z: 0 };
|
|
78
|
+
let x = 0;
|
|
79
|
+
let z = 0;
|
|
80
|
+
for (const point of points) {
|
|
81
|
+
x += point.x;
|
|
82
|
+
z += point.z;
|
|
83
|
+
}
|
|
84
|
+
return { x: x / points.length, z: z / points.length };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Splits a monolithic document into a sharded world: placeable objects (markers, volumes, paths,
|
|
88
|
+
* notes) are bucketed into `cellSize`-meter grid cells by a representative point and extracted into
|
|
89
|
+
* per-cell shard documents; the non-placeable extras (terrain, catalogs, prefabs, collections,
|
|
90
|
+
* grids, HUD layout) go into one always-resident `base` shard. Round-trips through
|
|
91
|
+
* {@link loadWorldDocument} to the same object set — the reverse of monolith authoring, so a large
|
|
92
|
+
* scene can be sharded once and streamed thereafter. Cell shards carry their exact object footprint
|
|
93
|
+
* as bounds; empty cells are omitted; order is deterministic (row-major by grid coordinate).
|
|
94
|
+
* @capability world-shards split a monolithic scene document into spatial shards
|
|
95
|
+
*/
|
|
96
|
+
export function splitEditorDocumentIntoShards(doc, options = {}) {
|
|
97
|
+
const cellSize = options.cellSize !== undefined && options.cellSize > 0 ? options.cellSize : 256;
|
|
98
|
+
const shardDir = options.shardDir ?? "shards";
|
|
99
|
+
// Bucket every placeable object id by the grid cell containing its representative point.
|
|
100
|
+
const cellIds = new Map();
|
|
101
|
+
const addToCell = (gx, gz, id) => {
|
|
102
|
+
const key = `${gx}:${gz}`;
|
|
103
|
+
const bucket = cellIds.get(key);
|
|
104
|
+
if (bucket === undefined)
|
|
105
|
+
cellIds.set(key, [id]);
|
|
106
|
+
else
|
|
107
|
+
bucket.push(id);
|
|
108
|
+
};
|
|
109
|
+
for (const marker of doc.markers) {
|
|
110
|
+
const { gx, gz } = objectCell(marker.position.x, marker.position.z, cellSize);
|
|
111
|
+
addToCell(gx, gz, marker.id);
|
|
112
|
+
}
|
|
113
|
+
for (const volume of doc.volumes) {
|
|
114
|
+
const { gx, gz } = objectCell(volume.center.x, volume.center.z, cellSize);
|
|
115
|
+
addToCell(gx, gz, volume.id);
|
|
116
|
+
}
|
|
117
|
+
for (const path of doc.paths) {
|
|
118
|
+
const c = pathCentroid(path.points);
|
|
119
|
+
const { gx, gz } = objectCell(c.x, c.z, cellSize);
|
|
120
|
+
addToCell(gx, gz, path.id);
|
|
121
|
+
}
|
|
122
|
+
for (const note of doc.annotations) {
|
|
123
|
+
const { gx, gz } = objectCell(note.position.x, note.position.z, cellSize);
|
|
124
|
+
addToCell(gx, gz, note.id);
|
|
125
|
+
}
|
|
126
|
+
// Always-resident base shard carries the non-placeable extras verbatim.
|
|
127
|
+
const baseFile = `${shardDir}/${WORLD_BASE_SHARD_ID}.json`;
|
|
128
|
+
const baseDoc = {
|
|
129
|
+
...createEmptyEditorDocument(),
|
|
130
|
+
...editorDocumentExtras(doc),
|
|
131
|
+
};
|
|
132
|
+
const shards = { [baseFile]: baseDoc };
|
|
133
|
+
const manifestShards = [
|
|
134
|
+
{ id: WORLD_BASE_SHARD_ID, file: baseFile, residency: "always" },
|
|
135
|
+
];
|
|
136
|
+
const sortedKeys = [...cellIds.keys()].sort((a, b) => {
|
|
137
|
+
const [ax, az] = a.split(":").map(Number);
|
|
138
|
+
const [bx, bz] = b.split(":").map(Number);
|
|
139
|
+
return az === bz ? ax - bx : az - bz;
|
|
140
|
+
});
|
|
141
|
+
for (const key of sortedKeys) {
|
|
142
|
+
const [gx, gz] = key.split(":").map(Number);
|
|
143
|
+
const ids = cellIds.get(key);
|
|
144
|
+
const shardDoc = extractEditorFragment(doc, ids);
|
|
145
|
+
const id = `cell_${gx}_${gz}`;
|
|
146
|
+
const file = `${shardDir}/${id}.json`;
|
|
147
|
+
shards[file] = shardDoc;
|
|
148
|
+
manifestShards.push({
|
|
149
|
+
id,
|
|
150
|
+
file,
|
|
151
|
+
residency: "streamed",
|
|
152
|
+
bounds: {
|
|
153
|
+
min: [gx * cellSize, gz * cellSize],
|
|
154
|
+
max: [(gx + 1) * cellSize, (gz + 1) * cellSize],
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
manifest: {
|
|
160
|
+
kind: WORLD_MANIFEST_KIND,
|
|
161
|
+
version: 1,
|
|
162
|
+
grid: { cellSize },
|
|
163
|
+
shards: manifestShards,
|
|
164
|
+
},
|
|
165
|
+
shards,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The backward-compatible degenerate manifest: one always-resident shard pointing at a single scene
|
|
170
|
+
* document file. `loadWorldDocument(singleShardWorldManifest(file), resolve)` returns exactly that
|
|
171
|
+
* document — the migration path for a game that has one `editor.scene.json` and wants the world API
|
|
172
|
+
* without sharding yet.
|
|
173
|
+
* @capability world-shards wrap a single scene document as a one-shard world
|
|
174
|
+
*/
|
|
175
|
+
export function singleShardWorldManifest(file, shardId = WORLD_BASE_SHARD_ID) {
|
|
176
|
+
return {
|
|
177
|
+
kind: WORLD_MANIFEST_KIND,
|
|
178
|
+
version: 1,
|
|
179
|
+
shards: [{ id: shardId, file, residency: "always" }],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function isPlainObject(value) {
|
|
183
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
184
|
+
}
|
|
185
|
+
function decodeBounds(value, path, errors) {
|
|
186
|
+
if (value === undefined)
|
|
187
|
+
return undefined;
|
|
188
|
+
if (!isPlainObject(value)) {
|
|
189
|
+
errors.push({ path, message: "expected an object" });
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
const pair = (v, p) => {
|
|
193
|
+
if (!Array.isArray(v) || v.length !== 2 || typeof v[0] !== "number" || typeof v[1] !== "number") {
|
|
194
|
+
errors.push({ path: p, message: "expected [number, number]" });
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return [v[0], v[1]];
|
|
198
|
+
};
|
|
199
|
+
const min = pair(value.min, `${path}.min`);
|
|
200
|
+
const max = pair(value.max, `${path}.max`);
|
|
201
|
+
if (min === null || max === null)
|
|
202
|
+
return undefined;
|
|
203
|
+
return { min, max };
|
|
204
|
+
}
|
|
205
|
+
function decodeShard(value, path, errors) {
|
|
206
|
+
if (!isPlainObject(value)) {
|
|
207
|
+
errors.push({ path, message: "expected an object" });
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
if (typeof value.id !== "string")
|
|
211
|
+
errors.push({ path: `${path}.id`, message: "expected a string" });
|
|
212
|
+
if (typeof value.file !== "string")
|
|
213
|
+
errors.push({ path: `${path}.file`, message: "expected a string" });
|
|
214
|
+
const bounds = decodeBounds(value.bounds, `${path}.bounds`, errors);
|
|
215
|
+
let residency;
|
|
216
|
+
if (value.residency !== undefined) {
|
|
217
|
+
if (value.residency === "always" || value.residency === "streamed")
|
|
218
|
+
residency = value.residency;
|
|
219
|
+
else
|
|
220
|
+
errors.push({ path: `${path}.residency`, message: "expected \"always\" | \"streamed\"" });
|
|
221
|
+
}
|
|
222
|
+
if (value.overlay !== undefined && typeof value.overlay !== "string") {
|
|
223
|
+
errors.push({ path: `${path}.overlay`, message: "expected a string" });
|
|
224
|
+
}
|
|
225
|
+
if (typeof value.id !== "string" || typeof value.file !== "string")
|
|
226
|
+
return null;
|
|
227
|
+
const shard = { id: value.id, file: value.file };
|
|
228
|
+
if (bounds !== undefined)
|
|
229
|
+
shard.bounds = bounds;
|
|
230
|
+
if (residency !== undefined)
|
|
231
|
+
shard.residency = residency;
|
|
232
|
+
if (typeof value.overlay === "string")
|
|
233
|
+
shard.overlay = value.overlay;
|
|
234
|
+
return shard;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The authoritative decoder for a `world.json` manifest arriving from disk or an agent: validates
|
|
238
|
+
* `kind`, the shard list, and each shard's fields with a path-specific diagnostic on failure, so a
|
|
239
|
+
* malformed manifest fails loudly at the boundary instead of streaming a broken world.
|
|
240
|
+
* @capability world-shards decode an untrusted world manifest with per-field diagnostics
|
|
241
|
+
*/
|
|
242
|
+
export function decodeWorldManifest(raw) {
|
|
243
|
+
if (!isPlainObject(raw)) {
|
|
244
|
+
return { ok: false, errors: [{ path: "$", message: "world manifest must be an object" }] };
|
|
245
|
+
}
|
|
246
|
+
const errors = [];
|
|
247
|
+
if (raw.kind !== WORLD_MANIFEST_KIND) {
|
|
248
|
+
errors.push({ path: "$.kind", message: `expected "${WORLD_MANIFEST_KIND}"` });
|
|
249
|
+
}
|
|
250
|
+
if (raw.version !== undefined && typeof raw.version !== "number") {
|
|
251
|
+
errors.push({ path: "$.version", message: "expected a number" });
|
|
252
|
+
}
|
|
253
|
+
let grid;
|
|
254
|
+
if (raw.grid !== undefined) {
|
|
255
|
+
if (isPlainObject(raw.grid) && typeof raw.grid.cellSize === "number")
|
|
256
|
+
grid = { cellSize: raw.grid.cellSize };
|
|
257
|
+
else
|
|
258
|
+
errors.push({ path: "$.grid", message: "expected { cellSize: number }" });
|
|
259
|
+
}
|
|
260
|
+
let streaming;
|
|
261
|
+
if (raw.streaming !== undefined) {
|
|
262
|
+
if (isPlainObject(raw.streaming) &&
|
|
263
|
+
typeof raw.streaming.loadRadius === "number" &&
|
|
264
|
+
typeof raw.streaming.keepRadius === "number") {
|
|
265
|
+
streaming = { loadRadius: raw.streaming.loadRadius, keepRadius: raw.streaming.keepRadius };
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
errors.push({ path: "$.streaming", message: "expected { loadRadius: number, keepRadius: number }" });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const shards = [];
|
|
272
|
+
if (!Array.isArray(raw.shards)) {
|
|
273
|
+
errors.push({ path: "$.shards", message: "expected an array" });
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
raw.shards.forEach((item, index) => {
|
|
277
|
+
const shard = decodeShard(item, `$.shards[${index}]`, errors);
|
|
278
|
+
if (shard !== null)
|
|
279
|
+
shards.push(shard);
|
|
280
|
+
});
|
|
281
|
+
const seen = new Set();
|
|
282
|
+
shards.forEach((shard, index) => {
|
|
283
|
+
if (seen.has(shard.id))
|
|
284
|
+
errors.push({ path: `$.shards[${index}].id`, message: `duplicate shard id "${shard.id}"` });
|
|
285
|
+
else
|
|
286
|
+
seen.add(shard.id);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
if (errors.length > 0)
|
|
290
|
+
return { ok: false, errors };
|
|
291
|
+
const manifest = { kind: WORLD_MANIFEST_KIND, shards };
|
|
292
|
+
if (typeof raw.version === "number")
|
|
293
|
+
manifest.version = raw.version;
|
|
294
|
+
if (grid !== undefined)
|
|
295
|
+
manifest.grid = grid;
|
|
296
|
+
if (streaming !== undefined)
|
|
297
|
+
manifest.streaming = streaming;
|
|
298
|
+
return { ok: true, manifest };
|
|
299
|
+
}
|
|
300
|
+
/** Serializes a world manifest to pretty JSON for writing `world.json`. */
|
|
301
|
+
export function exportWorldManifestJson(manifest, pretty = true) {
|
|
302
|
+
return JSON.stringify(manifest, null, pretty ? 2 : undefined);
|
|
303
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Target unit for {@link formatSpeed}: km/h, mph, knots, or raw m/s. */
|
|
2
|
+
export type SpeedUnit = "kmh" | "mph" | "knots" | "ms";
|
|
3
|
+
/** Options for {@link formatSpeed}. */
|
|
4
|
+
export interface SpeedFormat {
|
|
5
|
+
/** Target unit to convert into from the m/s input. Defaults to `"kmh"`. */
|
|
6
|
+
unit?: SpeedUnit;
|
|
7
|
+
/** Fractional digits to show. Defaults to 0. */
|
|
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 speed given in meters/second as a HUD-ready string in km/h, mph, knots, or m/s — the one conversion table every speedometer and telemetry readout should share.
|
|
14
|
+
*
|
|
15
|
+
* @capability speed-format render a m/s speed as km/h, mph, knots, or m/s for speedometers and telemetry HUDs
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatSpeed(metersPerSecond: number, options?: SpeedFormat): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const SPEED_UNIT_FACTOR = {
|
|
2
|
+
kmh: 3.6,
|
|
3
|
+
mph: 2.2369362920544025,
|
|
4
|
+
knots: 1.9438444924406046,
|
|
5
|
+
ms: 1,
|
|
6
|
+
};
|
|
7
|
+
const SPEED_UNIT_LABEL = {
|
|
8
|
+
kmh: "km/h",
|
|
9
|
+
mph: "mph",
|
|
10
|
+
knots: "kn",
|
|
11
|
+
ms: "m/s",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Format a speed given in meters/second as a HUD-ready string in km/h, mph, knots, or m/s — the one conversion table every speedometer and telemetry readout should share.
|
|
15
|
+
*
|
|
16
|
+
* @capability speed-format render a m/s speed as km/h, mph, knots, or m/s for speedometers and telemetry HUDs
|
|
17
|
+
*/
|
|
18
|
+
export function formatSpeed(metersPerSecond, options = {}) {
|
|
19
|
+
const unit = options.unit ?? "kmh";
|
|
20
|
+
const decimals = options.decimals ?? 0;
|
|
21
|
+
const showUnit = options.showUnit ?? true;
|
|
22
|
+
const converted = Math.max(0, metersPerSecond) * SPEED_UNIT_FACTOR[unit];
|
|
23
|
+
const text = converted.toFixed(decimals);
|
|
24
|
+
return showUnit ? `${text} ${SPEED_UNIT_LABEL[unit]}` : text;
|
|
25
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic creature breeding & genetics — a genre-agnostic engine primitive for
|
|
3
|
+
* taming/husbandry games. Everything here operates over plain serializable records so a
|
|
4
|
+
* genome round-trips through save/load and multiplayer sync, and every random decision is
|
|
5
|
+
* driven by an injected `rng: () => number` (values in `[0, 1)`) so identical inputs and an
|
|
6
|
+
* identical rng stream always produce the identical offspring.
|
|
7
|
+
*
|
|
8
|
+
* The lifecycle it models:
|
|
9
|
+
* - **inheritance** — each stat is drawn independently from the higher or lower parent,
|
|
10
|
+
* - **mutation** — a bounded number of rolls that boost a stat, bump a heritable lineage
|
|
11
|
+
* counter, and optionally flag a cosmetic/color mutation, gated by a soft cap,
|
|
12
|
+
* - **imprint** — a rearing bonus accrued by fulfilling care requests over maturation,
|
|
13
|
+
* - **incubation & maturation** — temperature-gated gestation viability and stage resolution.
|
|
14
|
+
*
|
|
15
|
+
* No species tables, coordinates, or game content live here; callers supply their own stat
|
|
16
|
+
* ids and tuning.
|
|
17
|
+
*/
|
|
18
|
+
/** A stat block: stat id → numeric point value. Plain serializable record, no ordering assumed. */
|
|
19
|
+
export type StatBlock = Record<string, number>;
|
|
20
|
+
/**
|
|
21
|
+
* A creature's heritable genome. `stats` are the inherited/mutated point values;
|
|
22
|
+
* `mutationCount` and `colorMutationCount` are the lineage counters that carry across
|
|
23
|
+
* generations and drive the mutation soft cap. Fully serializable — no methods or closures.
|
|
24
|
+
*/
|
|
25
|
+
export interface Genome {
|
|
26
|
+
stats: StatBlock;
|
|
27
|
+
/** Accumulated point mutations in this creature's lineage. Heritable, monotonic. */
|
|
28
|
+
mutationCount: number;
|
|
29
|
+
/** Accumulated cosmetic/color mutations in this creature's lineage. Heritable, monotonic. */
|
|
30
|
+
colorMutationCount: number;
|
|
31
|
+
}
|
|
32
|
+
/** One mutation that occurred while breeding a single offspring. */
|
|
33
|
+
export interface MutationEvent {
|
|
34
|
+
/** Stat id that received the point delta. */
|
|
35
|
+
stat: string;
|
|
36
|
+
/** Points added to that stat (the configured `mutationDelta`). */
|
|
37
|
+
delta: number;
|
|
38
|
+
/** True when this mutation was also flagged cosmetic/color. */
|
|
39
|
+
color: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Soft-cap rule for mutation eligibility. When a parent's `mutationCount` exceeds
|
|
43
|
+
* `threshold` its lineage is considered "capped"; the per-roll mutation chance is then
|
|
44
|
+
* either zeroed (`mode: "block"`) or scaled by `reducedFactor` (`mode: "reduce"`).
|
|
45
|
+
* `scope` decides whether it takes `both` parents capped, or `either` one, to trigger.
|
|
46
|
+
*/
|
|
47
|
+
export interface MutationSoftCap {
|
|
48
|
+
/** Counter value a parent must exceed to count as capped. Default `20`. */
|
|
49
|
+
threshold?: number;
|
|
50
|
+
/** Trigger when `both` parents are capped (default) or `either` one is. */
|
|
51
|
+
scope?: "both" | "either";
|
|
52
|
+
/** Zero the chance (`block`, default) or scale it by `reducedFactor` (`reduce`). */
|
|
53
|
+
mode?: "block" | "reduce";
|
|
54
|
+
/** Multiplier applied to the base chance when `mode: "reduce"` and capped. Default `0.5`. */
|
|
55
|
+
reducedFactor?: number;
|
|
56
|
+
}
|
|
57
|
+
/** Tuning for {@link breedOffspring}. Every field has an ARK-style default; all are optional. */
|
|
58
|
+
export interface BreedConfig {
|
|
59
|
+
/** Per-stat probability the offspring inherits the higher parent's value. Default `0.55`. */
|
|
60
|
+
higherStatChance?: number;
|
|
61
|
+
/** Number of independent mutation rolls per offspring. Default `3`. */
|
|
62
|
+
mutationRolls?: number;
|
|
63
|
+
/** Probability each mutation roll succeeds (before the soft cap). Default `0.025`. */
|
|
64
|
+
mutationChance?: number;
|
|
65
|
+
/** Points added to a random stat by a successful mutation. Default `2`. */
|
|
66
|
+
mutationDelta?: number;
|
|
67
|
+
/** Probability a successful mutation is additionally flagged cosmetic. Default `0.5`. */
|
|
68
|
+
colorMutationChance?: number;
|
|
69
|
+
/** Mutation-count soft cap rule. Defaults to `{ threshold: 20, scope: "both", mode: "block" }`. */
|
|
70
|
+
mutationSoftCap?: MutationSoftCap;
|
|
71
|
+
}
|
|
72
|
+
/** Result of {@link breedOffspring}: the new genome plus the mutations that produced it. */
|
|
73
|
+
export interface BreedResult {
|
|
74
|
+
genome: Genome;
|
|
75
|
+
mutations: readonly MutationEvent[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Breed one offspring from two parents. For each stat present in either parent (iterated in
|
|
79
|
+
* sorted id order for a stable rng stream) the offspring independently inherits the higher
|
|
80
|
+
* parent's value with probability `higherStatChance` (default `0.55`), else the lower — a
|
|
81
|
+
* per-stat coin flip, so a strong parent does not guarantee a strong child. Then up to
|
|
82
|
+
* `mutationRolls` mutation rolls fire at the soft-capped chance; each success adds
|
|
83
|
+
* `mutationDelta` to a random stat, bumps the heritable `mutationCount`, and is flagged
|
|
84
|
+
* cosmetic with probability `colorMutationChance`. Lineage counters carry as the max of the
|
|
85
|
+
* two parents plus the new mutations, keeping them monotonic and heritable.
|
|
86
|
+
*
|
|
87
|
+
* Deterministic: the same parents, config, and rng sequence yield byte-identical results.
|
|
88
|
+
*
|
|
89
|
+
* @capability creature-breeding deterministic stat inheritance, mutation, and lineage genetics for taming games
|
|
90
|
+
*/
|
|
91
|
+
export declare function breedOffspring(parentA: Genome, parentB: Genome, rng: () => number, config?: BreedConfig): BreedResult;
|
|
92
|
+
/** Options controlling how an imprint bonus is applied. */
|
|
93
|
+
export interface ImprintBonusConfig {
|
|
94
|
+
/** Stat multiplier at full imprint, applied to everyone. Default `0.20` (+20%). */
|
|
95
|
+
statBonusAtFull?: number;
|
|
96
|
+
/** Extra multiplier at full imprint, applied only for the imprinting owner. Default `0.30` (+30%). */
|
|
97
|
+
handlerBonusAtFull?: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Imprint gained per fulfilled care request when `requestCount` requests are scheduled over
|
|
101
|
+
* the maturation window: `1 / requestCount`, so fulfilling every request reaches full (1.0)
|
|
102
|
+
* imprint. Returns `0` for a non-positive request count.
|
|
103
|
+
*
|
|
104
|
+
* @capability imprint-increment per-care-request imprint gain across a maturation schedule
|
|
105
|
+
*/
|
|
106
|
+
export declare function imprintIncrementPerRequest(requestCount: number): number;
|
|
107
|
+
/**
|
|
108
|
+
* Apply the imprint rearing bonus to a stat block. Every stat is scaled by
|
|
109
|
+
* `1 + statBonusAtFull * imprint`; when `asOwner` is set, the imprinting handler additionally
|
|
110
|
+
* gets `1 + handlerBonusAtFull * imprint`. `imprint` is a 0..1 fraction (clamped) and scales
|
|
111
|
+
* both bonuses linearly, so half-imprint yields half the bonus. Returns a fresh stat block.
|
|
112
|
+
*
|
|
113
|
+
* @capability imprint-bonus apply imprint stat and handler bonuses at an imprint fraction
|
|
114
|
+
*/
|
|
115
|
+
export declare function applyImprintBonus(stats: StatBlock, imprint: number, config?: ImprintBonusConfig, options?: {
|
|
116
|
+
asOwner?: boolean;
|
|
117
|
+
}): StatBlock;
|
|
118
|
+
/** Serializable incubation/gestation state advanced by {@link tickIncubation}. */
|
|
119
|
+
export interface IncubationState {
|
|
120
|
+
/** Remaining egg/embryo health; incubation fails at `0`. */
|
|
121
|
+
health: number;
|
|
122
|
+
/** Accumulated in-range incubation time; only advances while temperature is viable. */
|
|
123
|
+
elapsed: number;
|
|
124
|
+
}
|
|
125
|
+
/** Temperature gate for {@link tickIncubation}. */
|
|
126
|
+
export interface IncubationConfig {
|
|
127
|
+
minTemp: number;
|
|
128
|
+
maxTemp: number;
|
|
129
|
+
/** Health lost per unit `dt` while temperature is outside `[minTemp, maxTemp]`. Default `1`. */
|
|
130
|
+
healthLossPerTick?: number;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Advance incubation one tick. While `temperature` is within `[minTemp, maxTemp]` the embryo
|
|
134
|
+
* makes progress (`elapsed += dt`) and keeps its health; outside the range it makes no
|
|
135
|
+
* progress and loses `healthLossPerTick * dt` health (clamped at `0`). Pure — returns a new
|
|
136
|
+
* state, never mutates the input.
|
|
137
|
+
*
|
|
138
|
+
* @capability incubation-tick advance egg incubation health inside/outside its temperature range
|
|
139
|
+
*/
|
|
140
|
+
export declare function tickIncubation(state: IncubationState, temperature: number, dt: number, config: IncubationConfig): IncubationState;
|
|
141
|
+
/**
|
|
142
|
+
* True while the incubation still has health to hatch.
|
|
143
|
+
*
|
|
144
|
+
* @capability incubation-viability test whether an egg incubation still has health to hatch
|
|
145
|
+
*/
|
|
146
|
+
export declare function incubationViable(state: IncubationState): boolean;
|
|
147
|
+
/** A maturation stage keyed by the elapsed fraction (0..1) at which it begins. */
|
|
148
|
+
export interface MaturationStage {
|
|
149
|
+
id: string;
|
|
150
|
+
/** Fraction of the maturation duration at which this stage starts (inclusive). */
|
|
151
|
+
at: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Resolve the maturation stage for an elapsed time against a duration. Computes the clamped
|
|
155
|
+
* `elapsed / duration` fraction and returns the id of the last stage whose `at` threshold has
|
|
156
|
+
* been reached (boundaries inclusive). Stages need not be pre-sorted. Returns `""` when no
|
|
157
|
+
* stage qualifies (e.g. an empty list or all thresholds above the current fraction).
|
|
158
|
+
*
|
|
159
|
+
* @capability maturation-stage resolve the baby/juvenile/adolescent/adult stage from elapsed maturation
|
|
160
|
+
*/
|
|
161
|
+
export declare function maturationStage(elapsed: number, duration: number, stages: readonly MaturationStage[]): string;
|