@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
|
@@ -102,6 +102,7 @@ function resolveCandidates(source, origin, direction, maxDistance, halfExtents)
|
|
|
102
102
|
const bounds = raySegmentBounds(origin, direction, maxDistance, halfExtents);
|
|
103
103
|
return source.inBox(bounds.min, bounds.max);
|
|
104
104
|
}
|
|
105
|
+
/** @internal */
|
|
105
106
|
export function raycastObjects(source, input) {
|
|
106
107
|
const direction = normalize(input.direction);
|
|
107
108
|
if (direction[0] === 0 && direction[1] === 0 && direction[2] === 0)
|
|
@@ -120,6 +121,7 @@ export function raycastObjects(source, input) {
|
|
|
120
121
|
}
|
|
121
122
|
return nearest;
|
|
122
123
|
}
|
|
124
|
+
/** @internal */
|
|
123
125
|
export function raycastObjectsAll(source, input) {
|
|
124
126
|
const direction = normalize(input.direction);
|
|
125
127
|
if (direction[0] === 0 && direction[1] === 0 && direction[2] === 0)
|
|
@@ -31,10 +31,14 @@ export interface ObjectStore {
|
|
|
31
31
|
setVisual(instanceId: string, visual: ObjectVisual | undefined): boolean;
|
|
32
32
|
get(instanceId: string): SceneObject | null;
|
|
33
33
|
list(filter?: ObjectListFilter): readonly SceneObject[];
|
|
34
|
+
/** Stable-identity list of all placed object ids; identity changes only on place/remove, not on move/rotate/setVisual. Pair with {@link subscribeMembership} for membership-only React subscriptions (#625). */
|
|
35
|
+
ids(): readonly string[];
|
|
34
36
|
at(x: number, y: number, z: number, tolerance?: number): SceneObject[];
|
|
35
37
|
inBox(min: EntityPosition, max: EntityPosition): readonly SceneObject[];
|
|
36
38
|
clear(): void;
|
|
37
39
|
subscribe(listener: () => void): () => void;
|
|
40
|
+
/** Notified only when the object set changes (place/remove), never on move/rotate/setVisual — markers read live poses imperatively. */
|
|
41
|
+
subscribeMembership(listener: () => void): () => void;
|
|
38
42
|
snapshot(): readonly SceneObject[];
|
|
39
43
|
}
|
|
40
44
|
export declare function createObjectStore(): ObjectStore;
|
|
@@ -112,6 +112,9 @@ export function createObjectStore() {
|
|
|
112
112
|
return all;
|
|
113
113
|
return all.filter((object) => object.parentSpace === filter.parentSpace);
|
|
114
114
|
},
|
|
115
|
+
ids() {
|
|
116
|
+
return store.keysSnapshot();
|
|
117
|
+
},
|
|
115
118
|
at(x, y, z, tolerance = 0) {
|
|
116
119
|
const minCx = cellIndexOf(x - tolerance);
|
|
117
120
|
const maxCx = cellIndexOf(x + tolerance);
|
|
@@ -180,6 +183,9 @@ export function createObjectStore() {
|
|
|
180
183
|
subscribe(listener) {
|
|
181
184
|
return store.subscribe(listener);
|
|
182
185
|
},
|
|
186
|
+
subscribeMembership(listener) {
|
|
187
|
+
return store.subscribeMembership(listener);
|
|
188
|
+
},
|
|
183
189
|
snapshot() {
|
|
184
190
|
return store.arraySnapshot();
|
|
185
191
|
},
|
|
@@ -17,6 +17,10 @@ export interface PossessionDeps {
|
|
|
17
17
|
entities: PossessionEntities;
|
|
18
18
|
events?: PossessionEvents;
|
|
19
19
|
}
|
|
20
|
+
export interface PossessionSnapshot {
|
|
21
|
+
owned: Record<string, readonly string[]>;
|
|
22
|
+
active: Record<string, string>;
|
|
23
|
+
}
|
|
20
24
|
export interface Possession {
|
|
21
25
|
own(userId: string, entityId: string): void;
|
|
22
26
|
disown(userId: string, entityId: string): void;
|
|
@@ -26,5 +30,9 @@ export interface Possession {
|
|
|
26
30
|
possess(userId: string, entityId: string): {
|
|
27
31
|
reason: string;
|
|
28
32
|
} | null;
|
|
33
|
+
/** Snapshot every user's owned entities and active pawn for a whole-world save. */
|
|
34
|
+
snapshotAll(): PossessionSnapshot;
|
|
35
|
+
/** Restore every user's owned entities and active pawn from a {@link snapshotAll} payload. Entity roles are restored by the entity snapshot, not re-applied here. */
|
|
36
|
+
hydrateAll(state: PossessionSnapshot): void;
|
|
29
37
|
}
|
|
30
38
|
export declare function createPossession(deps: PossessionDeps): Possession;
|
package/dist/scene/possession.js
CHANGED
|
@@ -47,5 +47,19 @@ export function createPossession(deps) {
|
|
|
47
47
|
deps.events?.emit("possession.swapped", { userId, entityId, previousEntityId });
|
|
48
48
|
return null;
|
|
49
49
|
},
|
|
50
|
+
snapshotAll() {
|
|
51
|
+
const ownedOut = {};
|
|
52
|
+
for (const [userId, set] of owned)
|
|
53
|
+
ownedOut[userId] = Array.from(set);
|
|
54
|
+
return { owned: ownedOut, active: Object.fromEntries(activeByUser) };
|
|
55
|
+
},
|
|
56
|
+
hydrateAll(state) {
|
|
57
|
+
owned.clear();
|
|
58
|
+
for (const [userId, ids] of Object.entries(state.owned))
|
|
59
|
+
owned.set(userId, new Set(ids));
|
|
60
|
+
activeByUser.clear();
|
|
61
|
+
for (const [userId, entityId] of Object.entries(state.active))
|
|
62
|
+
activeByUser.set(userId, entityId);
|
|
63
|
+
},
|
|
50
64
|
};
|
|
51
65
|
}
|
package/dist/scene/roster.d.ts
CHANGED
|
@@ -18,6 +18,9 @@ export interface Roster {
|
|
|
18
18
|
setEquipped(userId: string, entryId: string, equipped: boolean): RosterEntry | null;
|
|
19
19
|
snapshot(userId: string): readonly RosterEntry[];
|
|
20
20
|
hydrate(userId: string, entries: readonly RosterEntry[]): void;
|
|
21
|
+
/** Whole-store capture across every owner — the world-save/replication seam (per-owner `snapshot` can't enumerate owners). */
|
|
22
|
+
snapshotAll(): Record<string, readonly RosterEntry[]>;
|
|
23
|
+
hydrateAll(data: Record<string, readonly RosterEntry[]>): void;
|
|
21
24
|
}
|
|
22
25
|
export interface RosterDeps {
|
|
23
26
|
now?: () => number;
|
package/dist/scene/roster.js
CHANGED
|
@@ -53,5 +53,17 @@ export function createRoster(deps = {}) {
|
|
|
53
53
|
hydrate(userId, entries) {
|
|
54
54
|
rosters.set(userId, new Map(entries.map((entry) => [entry.id, entry])));
|
|
55
55
|
},
|
|
56
|
+
snapshotAll() {
|
|
57
|
+
const out = {};
|
|
58
|
+
for (const [userId, entries] of rosters)
|
|
59
|
+
out[userId] = Array.from(entries.values());
|
|
60
|
+
return out;
|
|
61
|
+
},
|
|
62
|
+
hydrateAll(data) {
|
|
63
|
+
rosters.clear();
|
|
64
|
+
for (const [userId, entries] of Object.entries(data)) {
|
|
65
|
+
rosters.set(userId, new Map(entries.map((entry) => [entry.id, entry])));
|
|
66
|
+
}
|
|
67
|
+
},
|
|
56
68
|
};
|
|
57
69
|
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parametric-studio seam: a registry that maps an editor object `kind` to a typed parameter
|
|
3
|
+
* schema (drives the inspector + `meta` parse/validation), an optional pure-data `resolve` (turns a
|
|
4
|
+
* document object into renderable data), and `+ Add` menu metadata. Registering a kind lets a third
|
|
5
|
+
* party ship a new authorable "studio" (pole line, water, bookcase) — schema + resolver here, a
|
|
6
|
+
* matching renderer in `shell` — without editing editor or engine files. Scatter is the proof adopter.
|
|
7
|
+
*/
|
|
8
|
+
/** Which document collection a scene kind lives in. Drives placement + which `meta` bag holds params. */
|
|
9
|
+
export type SceneKindTarget = "path" | "marker" | "volume";
|
|
10
|
+
/** A closed-polygon area vs an open polyline, for path-target kinds. Ignored for marker/volume kinds. */
|
|
11
|
+
export type ScenePathShape = "area" | "line";
|
|
12
|
+
/** One weighted entry in a `weightedList` param — an item id and its relative spawn weight. */
|
|
13
|
+
export interface WeightedParamEntry {
|
|
14
|
+
item: string;
|
|
15
|
+
weight: number;
|
|
16
|
+
}
|
|
17
|
+
/** A numeric slider row: bounded range with a live readout. */
|
|
18
|
+
export interface RangeParamField {
|
|
19
|
+
type: "range";
|
|
20
|
+
key: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
23
|
+
group?: string;
|
|
24
|
+
min: number;
|
|
25
|
+
max: number;
|
|
26
|
+
step?: number;
|
|
27
|
+
default: number;
|
|
28
|
+
/** Suffix shown next to the readout, e.g. "m" or "/m²". */
|
|
29
|
+
unit?: string;
|
|
30
|
+
}
|
|
31
|
+
/** A free numeric input, optionally clamped. */
|
|
32
|
+
export interface NumberParamField {
|
|
33
|
+
type: "number";
|
|
34
|
+
key: string;
|
|
35
|
+
label?: string;
|
|
36
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
37
|
+
group?: string;
|
|
38
|
+
step?: number;
|
|
39
|
+
default: number;
|
|
40
|
+
min?: number;
|
|
41
|
+
max?: number;
|
|
42
|
+
}
|
|
43
|
+
/** A checkbox. */
|
|
44
|
+
export interface BoolParamField {
|
|
45
|
+
type: "bool";
|
|
46
|
+
key: string;
|
|
47
|
+
label?: string;
|
|
48
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
49
|
+
group?: string;
|
|
50
|
+
default: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** A dropdown of fixed string options. */
|
|
53
|
+
export interface SelectParamField {
|
|
54
|
+
type: "select";
|
|
55
|
+
key: string;
|
|
56
|
+
label?: string;
|
|
57
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
58
|
+
group?: string;
|
|
59
|
+
options: readonly {
|
|
60
|
+
value: string;
|
|
61
|
+
label?: string;
|
|
62
|
+
}[];
|
|
63
|
+
default: string;
|
|
64
|
+
}
|
|
65
|
+
/** A hex color picker. */
|
|
66
|
+
export interface ColorParamField {
|
|
67
|
+
type: "color";
|
|
68
|
+
key: string;
|
|
69
|
+
label?: string;
|
|
70
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
71
|
+
group?: string;
|
|
72
|
+
default: string;
|
|
73
|
+
}
|
|
74
|
+
/** A free string input. */
|
|
75
|
+
export interface TextParamField {
|
|
76
|
+
type: "text";
|
|
77
|
+
key: string;
|
|
78
|
+
label?: string;
|
|
79
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
80
|
+
group?: string;
|
|
81
|
+
default: string;
|
|
82
|
+
}
|
|
83
|
+
/** A seed string with a reroll button — same seed reproduces the same generated result. */
|
|
84
|
+
export interface SeedParamField {
|
|
85
|
+
type: "seed";
|
|
86
|
+
key: string;
|
|
87
|
+
label?: string;
|
|
88
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
89
|
+
group?: string;
|
|
90
|
+
default: string;
|
|
91
|
+
}
|
|
92
|
+
/** A repeatable list of weighted `{ item, weight }` rows (species palette, book set, …). */
|
|
93
|
+
export interface WeightedListParamField {
|
|
94
|
+
type: "weightedList";
|
|
95
|
+
key: string;
|
|
96
|
+
label?: string;
|
|
97
|
+
/** Optional group id — the inspector renders fields sharing a group under one collapsible section. */
|
|
98
|
+
group?: string;
|
|
99
|
+
/** Placeholder for the item id input. */
|
|
100
|
+
itemLabel?: string;
|
|
101
|
+
default: readonly WeightedParamEntry[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A button row that runs a built-in inspector action on its group — currently `"randomize"` (reroll
|
|
105
|
+
* the group's numeric/seed/bool/select fields within their bounds) or `"reset"` (restore group
|
|
106
|
+
* defaults). Carries no persisted value; purely a control.
|
|
107
|
+
*/
|
|
108
|
+
export interface ActionParamField {
|
|
109
|
+
type: "action";
|
|
110
|
+
key: string;
|
|
111
|
+
label?: string;
|
|
112
|
+
group?: string;
|
|
113
|
+
action: "randomize" | "reset";
|
|
114
|
+
}
|
|
115
|
+
/** One row in a kind's parameter schema — the union the generic inspector knows how to render. */
|
|
116
|
+
export type ParamField = RangeParamField | NumberParamField | BoolParamField | SelectParamField | ColorParamField | TextParamField | SeedParamField | WeightedListParamField | ActionParamField;
|
|
117
|
+
/** A named, optionally-collapsed section the inspector groups fields under (by `field.group === id`). */
|
|
118
|
+
export interface ParamGroup {
|
|
119
|
+
id: string;
|
|
120
|
+
label: string;
|
|
121
|
+
/** Start collapsed. Default expanded. */
|
|
122
|
+
collapsed?: boolean;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A named slider/weight bundle for a kind — a saved set of field values the inspector (or the
|
|
126
|
+
* `apply_preset` verb) writes into an object's `meta` in one patch, ready to tweak afterwards.
|
|
127
|
+
* Presets are plain data on the schema, so kinds ship archetypes and games can override the
|
|
128
|
+
* registration with their own.
|
|
129
|
+
*/
|
|
130
|
+
export interface ParamPreset {
|
|
131
|
+
id: string;
|
|
132
|
+
label?: string;
|
|
133
|
+
/** Field values the preset writes; fields not listed keep their current values. */
|
|
134
|
+
values: Readonly<Record<string, unknown>>;
|
|
135
|
+
}
|
|
136
|
+
/** A kind's full parameter surface: an ordered list of fields the inspector renders top-to-bottom. */
|
|
137
|
+
export interface ParamSchema {
|
|
138
|
+
fields: readonly ParamField[];
|
|
139
|
+
/** Optional named sections; fields reference one by `group`. Ungrouped fields render first, headerless. */
|
|
140
|
+
groups?: readonly ParamGroup[];
|
|
141
|
+
/** Optional named field-value bundles the inspector offers as one-click applies. */
|
|
142
|
+
presets?: readonly ParamPreset[];
|
|
143
|
+
}
|
|
144
|
+
/** Look up a schema preset by id, or undefined — the seam `apply_preset` and games resolve bundles through. */
|
|
145
|
+
export declare function findSchemaPreset(schema: ParamSchema, id: string): ParamPreset | undefined;
|
|
146
|
+
/** Parsed params after `parseParams`: every schema field present with a validated, defaulted value. */
|
|
147
|
+
export type ParsedParams = Record<string, number | boolean | string | WeightedParamEntry[]>;
|
|
148
|
+
/**
|
|
149
|
+
* Parse a raw `meta` bag against a schema into typed params — every field present, invalid/missing
|
|
150
|
+
* values replaced by the field default, numbers clamped to their range. The single parser every
|
|
151
|
+
* studio shares instead of hand-writing its own `metaNumber`/`metaBool` ladder.
|
|
152
|
+
*/
|
|
153
|
+
export declare function parseParams(schema: ParamSchema, meta: Record<string, unknown> | undefined): ParsedParams;
|
|
154
|
+
/** One validation problem found by {@link validateParams}: which field and why. */
|
|
155
|
+
export interface ParamIssue {
|
|
156
|
+
key: string;
|
|
157
|
+
message: string;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check a raw `meta` bag against a schema without mutating it — reports out-of-range numbers, unknown
|
|
161
|
+
* select values, and wrong types. Empty array means valid. Used by `set_meta` to reject bad agent
|
|
162
|
+
* patches before they land in the document.
|
|
163
|
+
* @internal
|
|
164
|
+
*/
|
|
165
|
+
export declare function validateParams(schema: ParamSchema, meta: Record<string, unknown> | undefined): ParamIssue[];
|
|
166
|
+
/**
|
|
167
|
+
* A `meta` patch that randomizes every field in `groupId` within its bounds — the "randomize" button's
|
|
168
|
+
* behavior, pure and injectable so it's deterministic in tests. Ranges/numbers land in `[min, max]`
|
|
169
|
+
* (integer-rounded when `step >= 1`), bools/selects pick uniformly, seeds get a fresh token, colors a
|
|
170
|
+
* random mid-tone. Text and weighted lists are left untouched.
|
|
171
|
+
* @internal
|
|
172
|
+
*/
|
|
173
|
+
export declare function randomizeGroupParams(schema: ParamSchema, groupId: string | undefined, random: () => number): Record<string, unknown>;
|
|
174
|
+
/** A `meta` patch restoring every field in `groupId` to its schema default — the "reset" button. @internal */
|
|
175
|
+
export declare function resetGroupParams(schema: ParamSchema, groupId: string | undefined): Record<string, unknown>;
|
|
176
|
+
/** The `meta` patch that fills a fresh object of a kind with its schema defaults. @internal */
|
|
177
|
+
export declare function defaultParamMeta(schema: ParamSchema): Record<string, unknown>;
|
|
178
|
+
/**
|
|
179
|
+
* A registered scene kind — everything the editor/engine need to author and render a studio without
|
|
180
|
+
* bespoke code. `schema` drives the inspector + parse; `resolve` (optional) turns one document object
|
|
181
|
+
* into pure renderable data a matching `shell` renderer consumes; `add*` fields build the `+ Add` menu.
|
|
182
|
+
* @typeParam TResolved — the kind's renderable payload (scatter instances, pole+cable set, …).
|
|
183
|
+
*/
|
|
184
|
+
export interface SceneKindDefinition<TResolved = unknown> {
|
|
185
|
+
kind: string;
|
|
186
|
+
target: SceneKindTarget;
|
|
187
|
+
/** Human label for the inspector header and `+ Add` entry. */
|
|
188
|
+
label: string;
|
|
189
|
+
schema: ParamSchema;
|
|
190
|
+
/** For path kinds: closed area (default) or open line. Ignored for markers/volumes. */
|
|
191
|
+
pathShape?: ScenePathShape;
|
|
192
|
+
/** `+ Add` menu section this kind lists under (e.g. "Studios"). Omit to hide from the menu. */
|
|
193
|
+
addCategory?: string;
|
|
194
|
+
/** Accent color for the inspector panel + `+ Add` entry, as a hex string. */
|
|
195
|
+
accent?: string;
|
|
196
|
+
/**
|
|
197
|
+
* Turn one document object (its geometry + parsed params) into pure renderable data. Pure — no
|
|
198
|
+
* three.js/DOM. Omitted for kinds whose renderer reads the object directly. `object` is the raw
|
|
199
|
+
* marker/volume/path; `params` is `parseParams(schema, object.meta)`.
|
|
200
|
+
*/
|
|
201
|
+
resolve?: (object: SceneKindObject, params: ParsedParams, context: SceneKindResolveContext) => TResolved;
|
|
202
|
+
/** Optional one-line readout under the inspector fields (estimate, dimensions) — owned by the studio. */
|
|
203
|
+
note?: (object: SceneKindObject, params: ParsedParams) => string;
|
|
204
|
+
}
|
|
205
|
+
/** The raw document object a resolver receives — shape shared by markers, volumes, and paths. */
|
|
206
|
+
export interface SceneKindObject {
|
|
207
|
+
id: string;
|
|
208
|
+
kind: string;
|
|
209
|
+
meta?: Record<string, unknown>;
|
|
210
|
+
/** Present for path targets: the polyline/polygon points (XZ used). */
|
|
211
|
+
points?: readonly {
|
|
212
|
+
x: number;
|
|
213
|
+
y: number;
|
|
214
|
+
z: number;
|
|
215
|
+
}[];
|
|
216
|
+
/** Present for marker targets: the placed position. */
|
|
217
|
+
position?: {
|
|
218
|
+
x: number;
|
|
219
|
+
y: number;
|
|
220
|
+
z: number;
|
|
221
|
+
};
|
|
222
|
+
/** Present for volume targets: the region center. */
|
|
223
|
+
center?: {
|
|
224
|
+
x: number;
|
|
225
|
+
y: number;
|
|
226
|
+
z: number;
|
|
227
|
+
};
|
|
228
|
+
/** Present for volume targets: box half-extents. */
|
|
229
|
+
halfExtents?: {
|
|
230
|
+
x: number;
|
|
231
|
+
y: number;
|
|
232
|
+
z: number;
|
|
233
|
+
};
|
|
234
|
+
/** Present for volume targets: sphere/cylinder radius. */
|
|
235
|
+
radius?: number;
|
|
236
|
+
rotationY?: number;
|
|
237
|
+
}
|
|
238
|
+
/** Ground sampler + options a resolver may read (terrain height/normal snap). */
|
|
239
|
+
export interface SceneKindResolveContext {
|
|
240
|
+
sampleHeight?: (x: number, z: number) => number;
|
|
241
|
+
sampleNormal?: (x: number, z: number) => readonly [number, number, number];
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Register a scene kind — the plug-in point for a new parametric studio. Idempotent per `kind` (last
|
|
245
|
+
* registration wins), so a game's registration overrides a default. Call at module load; the editor
|
|
246
|
+
* inspector, `+ Add` menu, and `AuthoredScene` renderer lookup all read this registry.
|
|
247
|
+
*/
|
|
248
|
+
export declare function registerSceneKind<TResolved>(definition: SceneKindDefinition<TResolved>): void;
|
|
249
|
+
/** The registered definition for a kind, or undefined if the kind is a plain (non-studio) kind. @internal */
|
|
250
|
+
export declare function getSceneKind(kind: string): SceneKindDefinition | undefined;
|
|
251
|
+
/** True when a kind has a registered studio definition (schema/inspector/renderer). @internal */
|
|
252
|
+
export declare function isSceneKind(kind: string): boolean;
|
|
253
|
+
/** Every registered kind, optionally filtered by target, in registration order. @internal */
|
|
254
|
+
export declare function listSceneKinds(target?: SceneKindTarget): SceneKindDefinition[];
|
|
255
|
+
/** Parse a document object's `meta` against its registered kind schema, or `null` if unregistered. @internal */
|
|
256
|
+
export declare function parseSceneKindParams(object: SceneKindObject): ParsedParams | null;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parametric-studio seam: a registry that maps an editor object `kind` to a typed parameter
|
|
3
|
+
* schema (drives the inspector + `meta` parse/validation), an optional pure-data `resolve` (turns a
|
|
4
|
+
* document object into renderable data), and `+ Add` menu metadata. Registering a kind lets a third
|
|
5
|
+
* party ship a new authorable "studio" (pole line, water, bookcase) — schema + resolver here, a
|
|
6
|
+
* matching renderer in `shell` — without editing editor or engine files. Scatter is the proof adopter.
|
|
7
|
+
*/
|
|
8
|
+
/** Look up a schema preset by id, or undefined — the seam `apply_preset` and games resolve bundles through. */
|
|
9
|
+
export function findSchemaPreset(schema, id) {
|
|
10
|
+
return schema.presets?.find((preset) => preset.id === id);
|
|
11
|
+
}
|
|
12
|
+
function num(value, fallback, min, max) {
|
|
13
|
+
let n = typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
14
|
+
if (min !== undefined)
|
|
15
|
+
n = Math.max(min, n);
|
|
16
|
+
if (max !== undefined)
|
|
17
|
+
n = Math.min(max, n);
|
|
18
|
+
return n;
|
|
19
|
+
}
|
|
20
|
+
function readWeightedList(value, fallback) {
|
|
21
|
+
if (!Array.isArray(value))
|
|
22
|
+
return fallback.map((entry) => ({ ...entry }));
|
|
23
|
+
const entries = value
|
|
24
|
+
.filter((entry) => typeof entry === "object" && entry !== null)
|
|
25
|
+
.map((entry) => ({
|
|
26
|
+
item: typeof entry.item === "string" ? entry.item : "",
|
|
27
|
+
weight: num(entry.weight, 1, 0),
|
|
28
|
+
}))
|
|
29
|
+
.filter((entry) => entry.item.length > 0);
|
|
30
|
+
return entries.length > 0 ? entries : fallback.map((entry) => ({ ...entry }));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse a raw `meta` bag against a schema into typed params — every field present, invalid/missing
|
|
34
|
+
* values replaced by the field default, numbers clamped to their range. The single parser every
|
|
35
|
+
* studio shares instead of hand-writing its own `metaNumber`/`metaBool` ladder.
|
|
36
|
+
*/
|
|
37
|
+
export function parseParams(schema, meta) {
|
|
38
|
+
const out = {};
|
|
39
|
+
for (const field of schema.fields) {
|
|
40
|
+
const raw = meta?.[field.key];
|
|
41
|
+
switch (field.type) {
|
|
42
|
+
case "range":
|
|
43
|
+
out[field.key] = num(raw, field.default, field.min, field.max);
|
|
44
|
+
break;
|
|
45
|
+
case "number":
|
|
46
|
+
out[field.key] = num(raw, field.default, field.min, field.max);
|
|
47
|
+
break;
|
|
48
|
+
case "bool":
|
|
49
|
+
out[field.key] = typeof raw === "boolean" ? raw : field.default;
|
|
50
|
+
break;
|
|
51
|
+
case "select": {
|
|
52
|
+
const allowed = field.options.some((option) => option.value === raw);
|
|
53
|
+
out[field.key] = allowed ? raw : field.default;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "color":
|
|
57
|
+
case "text":
|
|
58
|
+
case "seed":
|
|
59
|
+
out[field.key] = typeof raw === "string" ? raw : field.default;
|
|
60
|
+
break;
|
|
61
|
+
case "weightedList":
|
|
62
|
+
out[field.key] = readWeightedList(raw, field.default);
|
|
63
|
+
break;
|
|
64
|
+
case "action":
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Check a raw `meta` bag against a schema without mutating it — reports out-of-range numbers, unknown
|
|
72
|
+
* select values, and wrong types. Empty array means valid. Used by `set_meta` to reject bad agent
|
|
73
|
+
* patches before they land in the document.
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
export function validateParams(schema, meta) {
|
|
77
|
+
const issues = [];
|
|
78
|
+
if (meta === undefined)
|
|
79
|
+
return issues;
|
|
80
|
+
for (const field of schema.fields) {
|
|
81
|
+
const raw = meta[field.key];
|
|
82
|
+
if (raw === undefined)
|
|
83
|
+
continue;
|
|
84
|
+
switch (field.type) {
|
|
85
|
+
case "range":
|
|
86
|
+
if (typeof raw !== "number" || !Number.isFinite(raw))
|
|
87
|
+
issues.push({ key: field.key, message: "expected a number" });
|
|
88
|
+
else if (raw < field.min || raw > field.max)
|
|
89
|
+
issues.push({ key: field.key, message: `out of range ${field.min}..${field.max}` });
|
|
90
|
+
break;
|
|
91
|
+
case "number":
|
|
92
|
+
if (typeof raw !== "number" || !Number.isFinite(raw))
|
|
93
|
+
issues.push({ key: field.key, message: "expected a number" });
|
|
94
|
+
else if ((field.min !== undefined && raw < field.min) || (field.max !== undefined && raw > field.max))
|
|
95
|
+
issues.push({ key: field.key, message: "out of range" });
|
|
96
|
+
break;
|
|
97
|
+
case "bool":
|
|
98
|
+
if (typeof raw !== "boolean")
|
|
99
|
+
issues.push({ key: field.key, message: "expected a boolean" });
|
|
100
|
+
break;
|
|
101
|
+
case "select":
|
|
102
|
+
if (!field.options.some((option) => option.value === raw))
|
|
103
|
+
issues.push({ key: field.key, message: "not an allowed option" });
|
|
104
|
+
break;
|
|
105
|
+
case "color":
|
|
106
|
+
case "text":
|
|
107
|
+
case "seed":
|
|
108
|
+
if (typeof raw !== "string")
|
|
109
|
+
issues.push({ key: field.key, message: "expected a string" });
|
|
110
|
+
break;
|
|
111
|
+
case "weightedList":
|
|
112
|
+
if (!Array.isArray(raw))
|
|
113
|
+
issues.push({ key: field.key, message: "expected an array" });
|
|
114
|
+
break;
|
|
115
|
+
case "action":
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return issues;
|
|
120
|
+
}
|
|
121
|
+
function randomHex(random) {
|
|
122
|
+
const channel = () => Math.floor(60 + random() * 180)
|
|
123
|
+
.toString(16)
|
|
124
|
+
.padStart(2, "0");
|
|
125
|
+
return `#${channel()}${channel()}${channel()}`;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A `meta` patch that randomizes every field in `groupId` within its bounds — the "randomize" button's
|
|
129
|
+
* behavior, pure and injectable so it's deterministic in tests. Ranges/numbers land in `[min, max]`
|
|
130
|
+
* (integer-rounded when `step >= 1`), bools/selects pick uniformly, seeds get a fresh token, colors a
|
|
131
|
+
* random mid-tone. Text and weighted lists are left untouched.
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
134
|
+
export function randomizeGroupParams(schema, groupId, random) {
|
|
135
|
+
const patch = {};
|
|
136
|
+
for (const field of schema.fields) {
|
|
137
|
+
if (field.group !== groupId)
|
|
138
|
+
continue;
|
|
139
|
+
switch (field.type) {
|
|
140
|
+
case "range": {
|
|
141
|
+
const value = field.min + random() * (field.max - field.min);
|
|
142
|
+
patch[field.key] = field.step !== undefined && field.step >= 1 ? Math.round(value) : Math.round(value * 1000) / 1000;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case "number": {
|
|
146
|
+
if (field.min !== undefined && field.max !== undefined)
|
|
147
|
+
patch[field.key] = Math.round((field.min + random() * (field.max - field.min)) * 1000) / 1000;
|
|
148
|
+
else
|
|
149
|
+
patch[field.key] = Math.round(field.default * (0.5 + random()) * 1000) / 1000;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "bool":
|
|
153
|
+
patch[field.key] = random() < 0.5;
|
|
154
|
+
break;
|
|
155
|
+
case "select":
|
|
156
|
+
patch[field.key] = field.options[Math.floor(random() * field.options.length)].value;
|
|
157
|
+
break;
|
|
158
|
+
case "seed":
|
|
159
|
+
patch[field.key] = `r${Math.floor(random() * 1_000_000).toString(36)}`;
|
|
160
|
+
break;
|
|
161
|
+
case "color":
|
|
162
|
+
patch[field.key] = randomHex(random);
|
|
163
|
+
break;
|
|
164
|
+
case "text":
|
|
165
|
+
case "weightedList":
|
|
166
|
+
case "action":
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return patch;
|
|
171
|
+
}
|
|
172
|
+
/** A `meta` patch restoring every field in `groupId` to its schema default — the "reset" button. @internal */
|
|
173
|
+
export function resetGroupParams(schema, groupId) {
|
|
174
|
+
const patch = {};
|
|
175
|
+
for (const field of schema.fields) {
|
|
176
|
+
if (field.group !== groupId || field.type === "action")
|
|
177
|
+
continue;
|
|
178
|
+
patch[field.key] = field.type === "weightedList" ? field.default.map((entry) => ({ ...entry })) : field.default;
|
|
179
|
+
}
|
|
180
|
+
return patch;
|
|
181
|
+
}
|
|
182
|
+
/** The `meta` patch that fills a fresh object of a kind with its schema defaults. @internal */
|
|
183
|
+
export function defaultParamMeta(schema) {
|
|
184
|
+
const out = {};
|
|
185
|
+
for (const field of schema.fields) {
|
|
186
|
+
if (field.type === "action")
|
|
187
|
+
continue;
|
|
188
|
+
out[field.key] = field.type === "weightedList" ? field.default.map((entry) => ({ ...entry })) : field.default;
|
|
189
|
+
}
|
|
190
|
+
return out;
|
|
191
|
+
}
|
|
192
|
+
const registry = new Map();
|
|
193
|
+
/**
|
|
194
|
+
* Register a scene kind — the plug-in point for a new parametric studio. Idempotent per `kind` (last
|
|
195
|
+
* registration wins), so a game's registration overrides a default. Call at module load; the editor
|
|
196
|
+
* inspector, `+ Add` menu, and `AuthoredScene` renderer lookup all read this registry.
|
|
197
|
+
*/
|
|
198
|
+
export function registerSceneKind(definition) {
|
|
199
|
+
registry.set(definition.kind, definition);
|
|
200
|
+
}
|
|
201
|
+
/** The registered definition for a kind, or undefined if the kind is a plain (non-studio) kind. @internal */
|
|
202
|
+
export function getSceneKind(kind) {
|
|
203
|
+
return registry.get(kind);
|
|
204
|
+
}
|
|
205
|
+
/** True when a kind has a registered studio definition (schema/inspector/renderer). @internal */
|
|
206
|
+
export function isSceneKind(kind) {
|
|
207
|
+
return registry.has(kind);
|
|
208
|
+
}
|
|
209
|
+
/** Every registered kind, optionally filtered by target, in registration order. @internal */
|
|
210
|
+
export function listSceneKinds(target) {
|
|
211
|
+
const all = [...registry.values()];
|
|
212
|
+
return target === undefined ? all : all.filter((definition) => definition.target === target);
|
|
213
|
+
}
|
|
214
|
+
/** Parse a document object's `meta` against its registered kind schema, or `null` if unregistered. @internal */
|
|
215
|
+
export function parseSceneKindParams(object) {
|
|
216
|
+
const definition = registry.get(object.kind);
|
|
217
|
+
return definition === undefined ? null : parseParams(definition.schema, object.meta);
|
|
218
|
+
}
|