@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,116 @@
|
|
|
1
|
+
import type { StatModifierSet } from "../stats/statModifiers.js";
|
|
2
|
+
/**
|
|
3
|
+
* A game-owned named input value. The engine ships no attribute vocabulary — ids,
|
|
4
|
+
* bounds, defaults, and metadata are entirely caller data, so the same graph can
|
|
5
|
+
* model STR/AGI/INT, SPECIAL scores, skills, difficulty knobs, or anything else.
|
|
6
|
+
*/
|
|
7
|
+
export interface StatInputDef {
|
|
8
|
+
id: string;
|
|
9
|
+
/** Default base value a fresh sheet starts at. Defaults to `min ?? 0`. */
|
|
10
|
+
base?: number;
|
|
11
|
+
/** Lower bound applied to the resolved value. */
|
|
12
|
+
min?: number;
|
|
13
|
+
/** Upper bound applied to the resolved value. */
|
|
14
|
+
max?: number;
|
|
15
|
+
/** Free-form, engine-ignored metadata (labels, descriptions, UI hints). */
|
|
16
|
+
meta?: Readonly<Record<string, unknown>>;
|
|
17
|
+
}
|
|
18
|
+
/** How a single contribution folds into a running value. */
|
|
19
|
+
export type StatOp = "add" | "mul" | "override" | "clampMin" | "clampMax";
|
|
20
|
+
/**
|
|
21
|
+
* One folded contribution to a value, retained so a sheet can explain
|
|
22
|
+
* "why is this value 42?" — every step carries the source that produced it.
|
|
23
|
+
*/
|
|
24
|
+
export interface StatContribution {
|
|
25
|
+
/** Provenance label — who/what produced this contribution. */
|
|
26
|
+
source: string;
|
|
27
|
+
op: StatOp;
|
|
28
|
+
value: number;
|
|
29
|
+
}
|
|
30
|
+
/** A modifier entry targeting one stat: a single contribution or an ordered list. */
|
|
31
|
+
export type StatModEntry = StatContribution | readonly StatContribution[];
|
|
32
|
+
/** The read-only view a derived formula gets: resolved values of its declared dependencies. */
|
|
33
|
+
export interface StatDeriveContext {
|
|
34
|
+
/** Resolved (fully modified) value of a declared dependency (input or derived). */
|
|
35
|
+
value(id: string): number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A derived value whose formula and dependencies are caller-owned. `compute` may
|
|
39
|
+
* return a scalar (shorthand for a single `add`) or an ordered list of contributions
|
|
40
|
+
* folded left-to-right, so additive/multiplicative/clamped and conditional modifiers
|
|
41
|
+
* are all expressed as plain data or branches inside the function.
|
|
42
|
+
*/
|
|
43
|
+
export interface StatDerivedDef {
|
|
44
|
+
id: string;
|
|
45
|
+
/** ids (inputs or other derived) this formula reads — drives ordering, cycle detection, and selective recompute. */
|
|
46
|
+
deps?: readonly string[];
|
|
47
|
+
min?: number;
|
|
48
|
+
max?: number;
|
|
49
|
+
round?: "floor" | "ceil" | "round";
|
|
50
|
+
meta?: Readonly<Record<string, unknown>>;
|
|
51
|
+
compute(ctx: StatDeriveContext): number | readonly StatContribution[];
|
|
52
|
+
}
|
|
53
|
+
/** The full schema of a stat graph: its named inputs and caller-authored derived formulas. */
|
|
54
|
+
export interface StatGraphDef {
|
|
55
|
+
inputs: readonly StatInputDef[];
|
|
56
|
+
derived?: readonly StatDerivedDef[];
|
|
57
|
+
}
|
|
58
|
+
/** Plain-data, JSON-safe sheet state: input base values plus registered modifier sources. */
|
|
59
|
+
export interface StatSheetState {
|
|
60
|
+
base: Record<string, number>;
|
|
61
|
+
sources: Record<string, Record<string, StatContribution[]>>;
|
|
62
|
+
}
|
|
63
|
+
/** One line of a provenance trace: a contribution plus the running total after it folds in. */
|
|
64
|
+
export interface StatContributionStep extends StatContribution {
|
|
65
|
+
/** Running total after this contribution folds in. */
|
|
66
|
+
subtotal: number;
|
|
67
|
+
}
|
|
68
|
+
/** A full provenance trace for one stat: the ordered steps that produced its value. */
|
|
69
|
+
export interface StatExplanation {
|
|
70
|
+
id: string;
|
|
71
|
+
value: number;
|
|
72
|
+
steps: StatContributionStep[];
|
|
73
|
+
}
|
|
74
|
+
/** A live per-entity instance of a {@link StatGraph}: mutable base values and modifier sources over a shared schema. */
|
|
75
|
+
export interface StatSheet {
|
|
76
|
+
/** Resolve the fully modified value of an input or derived stat. */
|
|
77
|
+
get(id: string): number;
|
|
78
|
+
/** The stored base of an input stat (before modifiers/clamping). */
|
|
79
|
+
getBase(id: string): number;
|
|
80
|
+
setBase(id: string, value: number): void;
|
|
81
|
+
/** Register (or replace) a named modifier source targeting one or more stats. */
|
|
82
|
+
addSource(sourceId: string, mods: Record<string, StatModEntry>): void;
|
|
83
|
+
removeSource(sourceId: string): boolean;
|
|
84
|
+
hasSource(sourceId: string): boolean;
|
|
85
|
+
sources(): string[];
|
|
86
|
+
/** Resolve every input and derived stat into a plain record. */
|
|
87
|
+
values(): Record<string, number>;
|
|
88
|
+
/** Ordered contribution trace explaining a stat's current value. */
|
|
89
|
+
explain(id: string): StatExplanation;
|
|
90
|
+
/** Resolve values under a proposed, uncommitted mutation (e.g. a previewed allocation). */
|
|
91
|
+
preview(mutate: (draft: StatSheet) => void): Record<string, number>;
|
|
92
|
+
toJSON(): StatSheetState;
|
|
93
|
+
}
|
|
94
|
+
/** A compiled, immutable stat-graph schema that mints per-entity {@link StatSheet}s from base values or saved state. */
|
|
95
|
+
export interface StatGraph {
|
|
96
|
+
readonly inputIds: readonly string[];
|
|
97
|
+
readonly derivedIds: readonly string[];
|
|
98
|
+
create(base?: Record<string, number>): StatSheet;
|
|
99
|
+
restore(state: StatSheetState): StatSheet;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A data-driven stat graph: game-owned named inputs feed caller-authored derived
|
|
103
|
+
* formulas, with contribution provenance, uncommitted previews, cycle detection, and
|
|
104
|
+
* selective recomputation. Formula semantics and numeric tables stay entirely game-defined.
|
|
105
|
+
*
|
|
106
|
+
* @capability stat-graph derive game-defined stats from named inputs with provenance and preview
|
|
107
|
+
*/
|
|
108
|
+
export declare function createStatGraph(def: StatGraphDef): StatGraph;
|
|
109
|
+
/**
|
|
110
|
+
* Bridge the shared {@link StatModifierSet} shape (add/multiply, used by talents, items,
|
|
111
|
+
* and buffs) into stat-graph contributions, so a ranked talent tree or gear roll feeds
|
|
112
|
+
* the graph as one named source instead of a parallel store.
|
|
113
|
+
*
|
|
114
|
+
* @capability stat-graph-bridge feed an existing StatModifierSet into a stat-graph source
|
|
115
|
+
*/
|
|
116
|
+
export declare function statModifierContributions<TStat extends string>(source: string, set: StatModifierSet<TStat>): Record<string, StatContribution[]>;
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
const OP_ORDER = { override: 0, add: 1, mul: 2, clampMin: 3, clampMax: 4 };
|
|
2
|
+
function applyOp(acc, op, value) {
|
|
3
|
+
switch (op) {
|
|
4
|
+
case "add":
|
|
5
|
+
return acc + value;
|
|
6
|
+
case "mul":
|
|
7
|
+
return acc * value;
|
|
8
|
+
case "override":
|
|
9
|
+
return value;
|
|
10
|
+
case "clampMin":
|
|
11
|
+
return Math.max(acc, value);
|
|
12
|
+
case "clampMax":
|
|
13
|
+
return Math.min(acc, value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function normalizeEntry(entry) {
|
|
17
|
+
return Array.isArray(entry) ? [...entry] : [entry];
|
|
18
|
+
}
|
|
19
|
+
function applyBounds(value, bounds) {
|
|
20
|
+
let out = value;
|
|
21
|
+
if (bounds.min !== undefined)
|
|
22
|
+
out = Math.max(bounds.min, out);
|
|
23
|
+
if (bounds.max !== undefined)
|
|
24
|
+
out = Math.min(bounds.max, out);
|
|
25
|
+
switch (bounds.round) {
|
|
26
|
+
case "floor":
|
|
27
|
+
return Math.floor(out);
|
|
28
|
+
case "ceil":
|
|
29
|
+
return Math.ceil(out);
|
|
30
|
+
case "round":
|
|
31
|
+
return Math.round(out);
|
|
32
|
+
default:
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A data-driven stat graph: game-owned named inputs feed caller-authored derived
|
|
38
|
+
* formulas, with contribution provenance, uncommitted previews, cycle detection, and
|
|
39
|
+
* selective recomputation. Formula semantics and numeric tables stay entirely game-defined.
|
|
40
|
+
*
|
|
41
|
+
* @capability stat-graph derive game-defined stats from named inputs with provenance and preview
|
|
42
|
+
*/
|
|
43
|
+
export function createStatGraph(def) {
|
|
44
|
+
const inputs = new Map();
|
|
45
|
+
for (const input of def.inputs) {
|
|
46
|
+
if (inputs.has(input.id))
|
|
47
|
+
throw new Error(`duplicate stat input id: ${input.id}`);
|
|
48
|
+
inputs.set(input.id, input);
|
|
49
|
+
}
|
|
50
|
+
const derived = new Map();
|
|
51
|
+
for (const node of def.derived ?? []) {
|
|
52
|
+
if (inputs.has(node.id) || derived.has(node.id))
|
|
53
|
+
throw new Error(`duplicate stat id: ${node.id}`);
|
|
54
|
+
derived.set(node.id, node);
|
|
55
|
+
}
|
|
56
|
+
// Validate dependencies and topologically order derived nodes (cycle detection).
|
|
57
|
+
for (const node of derived.values()) {
|
|
58
|
+
for (const dep of node.deps ?? []) {
|
|
59
|
+
if (!inputs.has(dep) && !derived.has(dep)) {
|
|
60
|
+
throw new Error(`stat "${node.id}" depends on unknown stat "${dep}"`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const order = [];
|
|
65
|
+
const visiting = new Set();
|
|
66
|
+
const done = new Set();
|
|
67
|
+
const visit = (id) => {
|
|
68
|
+
if (done.has(id) || inputs.has(id))
|
|
69
|
+
return;
|
|
70
|
+
if (visiting.has(id))
|
|
71
|
+
throw new Error(`stat dependency cycle through "${id}"`);
|
|
72
|
+
visiting.add(id);
|
|
73
|
+
for (const dep of derived.get(id)?.deps ?? [])
|
|
74
|
+
visit(dep);
|
|
75
|
+
visiting.delete(id);
|
|
76
|
+
done.add(id);
|
|
77
|
+
order.push(id);
|
|
78
|
+
};
|
|
79
|
+
for (const id of derived.keys())
|
|
80
|
+
visit(id);
|
|
81
|
+
// Transitive dependents: changing X invalidates X and everything downstream of it.
|
|
82
|
+
const dependents = new Map();
|
|
83
|
+
for (const node of derived.values()) {
|
|
84
|
+
for (const dep of node.deps ?? []) {
|
|
85
|
+
let set = dependents.get(dep);
|
|
86
|
+
if (!set)
|
|
87
|
+
dependents.set(dep, (set = new Set()));
|
|
88
|
+
set.add(node.id);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const affected = (id) => {
|
|
92
|
+
const out = new Set([id]);
|
|
93
|
+
const stack = [id];
|
|
94
|
+
while (stack.length > 0) {
|
|
95
|
+
const cur = stack.pop();
|
|
96
|
+
for (const dep of dependents.get(cur) ?? []) {
|
|
97
|
+
if (!out.has(dep)) {
|
|
98
|
+
out.add(dep);
|
|
99
|
+
stack.push(dep);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
};
|
|
105
|
+
const inputIds = Array.from(inputs.keys());
|
|
106
|
+
const derivedIds = Array.from(derived.keys());
|
|
107
|
+
const allIds = [...inputIds, ...order];
|
|
108
|
+
function makeSheet(baseState, sourceState) {
|
|
109
|
+
const baseValues = new Map(Object.entries(baseState));
|
|
110
|
+
const sources = sourceState;
|
|
111
|
+
const valueCache = new Map();
|
|
112
|
+
const stepCache = new Map();
|
|
113
|
+
const knows = (id) => inputs.has(id) || derived.has(id);
|
|
114
|
+
function externalSteps(id) {
|
|
115
|
+
const collected = [];
|
|
116
|
+
for (const mods of sources.values()) {
|
|
117
|
+
const list = mods.get(id);
|
|
118
|
+
if (list)
|
|
119
|
+
collected.push(...list);
|
|
120
|
+
}
|
|
121
|
+
// Stable sort by op precedence; registration order is preserved within an op.
|
|
122
|
+
return collected
|
|
123
|
+
.map((c, index) => ({ c, index }))
|
|
124
|
+
.sort((a, b) => OP_ORDER[a.c.op] - OP_ORDER[b.c.op] || a.index - b.index)
|
|
125
|
+
.map((entry) => entry.c);
|
|
126
|
+
}
|
|
127
|
+
function resolveSteps(id) {
|
|
128
|
+
const cached = stepCache.get(id);
|
|
129
|
+
if (cached)
|
|
130
|
+
return cached;
|
|
131
|
+
const inputDef = inputs.get(id);
|
|
132
|
+
const steps = [];
|
|
133
|
+
let acc;
|
|
134
|
+
if (inputDef) {
|
|
135
|
+
acc = baseValues.get(id) ?? inputDef.base ?? inputDef.min ?? 0;
|
|
136
|
+
steps.push({ source: "base", op: "add", value: acc, subtotal: acc });
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const node = derived.get(id);
|
|
140
|
+
if (!node)
|
|
141
|
+
throw new Error(`unknown stat: ${id}`);
|
|
142
|
+
const deps = new Set(node.deps ?? []);
|
|
143
|
+
const ctx = {
|
|
144
|
+
value: (dep) => {
|
|
145
|
+
if (!deps.has(dep))
|
|
146
|
+
throw new Error(`stat "${id}" read undeclared dependency "${dep}"`);
|
|
147
|
+
return resolveValue(dep);
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
const out = node.compute(ctx);
|
|
151
|
+
const contribs = typeof out === "number" ? [{ source: "formula", op: "add", value: out }] : out;
|
|
152
|
+
acc = 0;
|
|
153
|
+
for (const c of contribs) {
|
|
154
|
+
acc = applyOp(acc, c.op, c.value);
|
|
155
|
+
steps.push({ ...c, subtotal: acc });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
for (const c of externalSteps(id)) {
|
|
159
|
+
acc = applyOp(acc, c.op, c.value);
|
|
160
|
+
steps.push({ ...c, subtotal: acc });
|
|
161
|
+
}
|
|
162
|
+
const bounds = inputDef ?? derived.get(id);
|
|
163
|
+
const bounded = applyBounds(acc, bounds);
|
|
164
|
+
if (bounded !== acc) {
|
|
165
|
+
steps.push({ source: "bounds", op: "override", value: bounded, subtotal: bounded });
|
|
166
|
+
}
|
|
167
|
+
stepCache.set(id, steps);
|
|
168
|
+
return steps;
|
|
169
|
+
}
|
|
170
|
+
function resolveValue(id) {
|
|
171
|
+
const cached = valueCache.get(id);
|
|
172
|
+
if (cached !== undefined)
|
|
173
|
+
return cached;
|
|
174
|
+
const steps = resolveSteps(id);
|
|
175
|
+
const value = steps.length === 0 ? 0 : steps[steps.length - 1].subtotal;
|
|
176
|
+
valueCache.set(id, value);
|
|
177
|
+
return value;
|
|
178
|
+
}
|
|
179
|
+
function invalidate(ids) {
|
|
180
|
+
for (const id of ids) {
|
|
181
|
+
for (const target of affected(id)) {
|
|
182
|
+
valueCache.delete(target);
|
|
183
|
+
stepCache.delete(target);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function cloneBase() {
|
|
188
|
+
const out = {};
|
|
189
|
+
for (const [id, value] of baseValues)
|
|
190
|
+
out[id] = value;
|
|
191
|
+
return out;
|
|
192
|
+
}
|
|
193
|
+
function cloneSourceMaps() {
|
|
194
|
+
const clone = new Map();
|
|
195
|
+
for (const [sourceId, mods] of sources) {
|
|
196
|
+
const inner = new Map();
|
|
197
|
+
for (const [statId, list] of mods)
|
|
198
|
+
inner.set(statId, list.map((c) => ({ ...c })));
|
|
199
|
+
clone.set(sourceId, inner);
|
|
200
|
+
}
|
|
201
|
+
return clone;
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
get(id) {
|
|
205
|
+
if (!knows(id))
|
|
206
|
+
throw new Error(`unknown stat: ${id}`);
|
|
207
|
+
return resolveValue(id);
|
|
208
|
+
},
|
|
209
|
+
getBase(id) {
|
|
210
|
+
const inputDef = inputs.get(id);
|
|
211
|
+
if (!inputDef)
|
|
212
|
+
throw new Error(`not an input stat: ${id}`);
|
|
213
|
+
return baseValues.get(id) ?? inputDef.base ?? inputDef.min ?? 0;
|
|
214
|
+
},
|
|
215
|
+
setBase(id, value) {
|
|
216
|
+
if (!inputs.has(id))
|
|
217
|
+
throw new Error(`not an input stat: ${id}`);
|
|
218
|
+
baseValues.set(id, value);
|
|
219
|
+
invalidate([id]);
|
|
220
|
+
},
|
|
221
|
+
addSource(sourceId, mods) {
|
|
222
|
+
const map = new Map();
|
|
223
|
+
for (const [statId, entry] of Object.entries(mods)) {
|
|
224
|
+
if (!knows(statId))
|
|
225
|
+
throw new Error(`source "${sourceId}" targets unknown stat "${statId}"`);
|
|
226
|
+
map.set(statId, normalizeEntry(entry));
|
|
227
|
+
}
|
|
228
|
+
// Replacing a source must invalidate stats it USED to target, not just its new targets.
|
|
229
|
+
const touched = new Set(map.keys());
|
|
230
|
+
for (const statId of sources.get(sourceId)?.keys() ?? [])
|
|
231
|
+
touched.add(statId);
|
|
232
|
+
sources.set(sourceId, map);
|
|
233
|
+
invalidate(touched);
|
|
234
|
+
},
|
|
235
|
+
removeSource(sourceId) {
|
|
236
|
+
const map = sources.get(sourceId);
|
|
237
|
+
if (!map)
|
|
238
|
+
return false;
|
|
239
|
+
sources.delete(sourceId);
|
|
240
|
+
invalidate(map.keys());
|
|
241
|
+
return true;
|
|
242
|
+
},
|
|
243
|
+
hasSource(sourceId) {
|
|
244
|
+
return sources.has(sourceId);
|
|
245
|
+
},
|
|
246
|
+
sources() {
|
|
247
|
+
return Array.from(sources.keys());
|
|
248
|
+
},
|
|
249
|
+
values() {
|
|
250
|
+
const out = {};
|
|
251
|
+
for (const id of allIds)
|
|
252
|
+
out[id] = resolveValue(id);
|
|
253
|
+
return out;
|
|
254
|
+
},
|
|
255
|
+
explain(id) {
|
|
256
|
+
if (!knows(id))
|
|
257
|
+
throw new Error(`unknown stat: ${id}`);
|
|
258
|
+
const steps = resolveSteps(id).map((step) => ({ ...step }));
|
|
259
|
+
return { id, value: resolveValue(id), steps };
|
|
260
|
+
},
|
|
261
|
+
preview(mutate) {
|
|
262
|
+
const draft = makeSheet(cloneBase(), cloneSourceMaps());
|
|
263
|
+
mutate(draft);
|
|
264
|
+
return draft.values();
|
|
265
|
+
},
|
|
266
|
+
toJSON() {
|
|
267
|
+
const sourcesOut = {};
|
|
268
|
+
for (const [sourceId, mods] of sources) {
|
|
269
|
+
const inner = {};
|
|
270
|
+
for (const [statId, list] of mods)
|
|
271
|
+
inner[statId] = list.map((c) => ({ ...c }));
|
|
272
|
+
sourcesOut[sourceId] = inner;
|
|
273
|
+
}
|
|
274
|
+
return { base: cloneBase(), sources: sourcesOut };
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
inputIds,
|
|
280
|
+
derivedIds,
|
|
281
|
+
create(base) {
|
|
282
|
+
return makeSheet({ ...(base ?? {}) }, new Map());
|
|
283
|
+
},
|
|
284
|
+
restore(state) {
|
|
285
|
+
const sources = new Map();
|
|
286
|
+
for (const [sourceId, mods] of Object.entries(state.sources ?? {})) {
|
|
287
|
+
const inner = new Map();
|
|
288
|
+
for (const [statId, list] of Object.entries(mods))
|
|
289
|
+
inner.set(statId, list.map((c) => ({ ...c })));
|
|
290
|
+
sources.set(sourceId, inner);
|
|
291
|
+
}
|
|
292
|
+
return makeSheet({ ...(state.base ?? {}) }, sources);
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Bridge the shared {@link StatModifierSet} shape (add/multiply, used by talents, items,
|
|
298
|
+
* and buffs) into stat-graph contributions, so a ranked talent tree or gear roll feeds
|
|
299
|
+
* the graph as one named source instead of a parallel store.
|
|
300
|
+
*
|
|
301
|
+
* @capability stat-graph-bridge feed an existing StatModifierSet into a stat-graph source
|
|
302
|
+
*/
|
|
303
|
+
export function statModifierContributions(source, set) {
|
|
304
|
+
const out = {};
|
|
305
|
+
for (const stat of Object.keys(set)) {
|
|
306
|
+
const modifier = set[stat];
|
|
307
|
+
if (!modifier)
|
|
308
|
+
continue;
|
|
309
|
+
const list = [];
|
|
310
|
+
if (modifier.add !== undefined)
|
|
311
|
+
list.push({ source, op: "add", value: modifier.add });
|
|
312
|
+
if (modifier.multiply !== undefined)
|
|
313
|
+
list.push({ source, op: "mul", value: modifier.multiply });
|
|
314
|
+
if (list.length > 0)
|
|
315
|
+
out[stat] = list;
|
|
316
|
+
}
|
|
317
|
+
return out;
|
|
318
|
+
}
|
|
@@ -11,16 +11,25 @@ export interface CellRun<T> {
|
|
|
11
11
|
}[];
|
|
12
12
|
readonly direction: "row" | "column";
|
|
13
13
|
}
|
|
14
|
+
/** @internal */
|
|
14
15
|
export declare function createCellGrid<T>(width: number, height: number): CellGrid<T>;
|
|
16
|
+
/** @internal */
|
|
15
17
|
export declare function inGridBounds<T>(grid: CellGrid<T>, x: number, y: number): boolean;
|
|
18
|
+
/** @internal */
|
|
16
19
|
export declare function cellAt<T>(grid: CellGrid<T>, x: number, y: number): T | null;
|
|
20
|
+
/** @internal */
|
|
17
21
|
export declare function withCell<T>(grid: CellGrid<T>, x: number, y: number, value: T | null): CellGrid<T>;
|
|
22
|
+
/** @internal */
|
|
18
23
|
export declare function withCells<T>(grid: CellGrid<T>, entries: readonly {
|
|
19
24
|
readonly x: number;
|
|
20
25
|
readonly y: number;
|
|
21
26
|
readonly value: T | null;
|
|
22
27
|
}[]): CellGrid<T>;
|
|
28
|
+
/** @internal */
|
|
23
29
|
export declare function fullRows<T>(grid: CellGrid<T>): number[];
|
|
30
|
+
/** @internal */
|
|
24
31
|
export declare function clearRows<T>(grid: CellGrid<T>, rows: readonly number[]): CellGrid<T>;
|
|
32
|
+
/** @internal */
|
|
25
33
|
export declare function collapseColumns<T>(grid: CellGrid<T>): CellGrid<T>;
|
|
34
|
+
/** @internal */
|
|
26
35
|
export declare function findRuns<T>(grid: CellGrid<T>, minLength: number, matches?: (a: T, b: T) => boolean): CellRun<T>[];
|
package/dist/puzzle/cellGrid.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export function createCellGrid(width, height) {
|
|
2
3
|
return { width, height, cells: new Array(width * height).fill(null) };
|
|
3
4
|
}
|
|
5
|
+
/** @internal */
|
|
4
6
|
export function inGridBounds(grid, x, y) {
|
|
5
7
|
return x >= 0 && x < grid.width && y >= 0 && y < grid.height;
|
|
6
8
|
}
|
|
9
|
+
/** @internal */
|
|
7
10
|
export function cellAt(grid, x, y) {
|
|
8
11
|
if (!inGridBounds(grid, x, y))
|
|
9
12
|
return null;
|
|
10
13
|
return grid.cells[y * grid.width + x] ?? null;
|
|
11
14
|
}
|
|
15
|
+
/** @internal */
|
|
12
16
|
export function withCell(grid, x, y, value) {
|
|
13
17
|
if (!inGridBounds(grid, x, y))
|
|
14
18
|
return grid;
|
|
@@ -16,6 +20,7 @@ export function withCell(grid, x, y, value) {
|
|
|
16
20
|
cells[y * grid.width + x] = value;
|
|
17
21
|
return { width: grid.width, height: grid.height, cells };
|
|
18
22
|
}
|
|
23
|
+
/** @internal */
|
|
19
24
|
export function withCells(grid, entries) {
|
|
20
25
|
const cells = grid.cells.slice();
|
|
21
26
|
for (const entry of entries) {
|
|
@@ -24,6 +29,7 @@ export function withCells(grid, entries) {
|
|
|
24
29
|
}
|
|
25
30
|
return { width: grid.width, height: grid.height, cells };
|
|
26
31
|
}
|
|
32
|
+
/** @internal */
|
|
27
33
|
export function fullRows(grid) {
|
|
28
34
|
const rows = [];
|
|
29
35
|
for (let y = 0; y < grid.height; y += 1) {
|
|
@@ -39,6 +45,7 @@ export function fullRows(grid) {
|
|
|
39
45
|
}
|
|
40
46
|
return rows;
|
|
41
47
|
}
|
|
48
|
+
/** @internal */
|
|
42
49
|
export function clearRows(grid, rows) {
|
|
43
50
|
const removed = new Set(rows);
|
|
44
51
|
const kept = [];
|
|
@@ -55,6 +62,7 @@ export function clearRows(grid, rows) {
|
|
|
55
62
|
cells.push(...row);
|
|
56
63
|
return { width: grid.width, height: grid.height, cells };
|
|
57
64
|
}
|
|
65
|
+
/** @internal */
|
|
58
66
|
export function collapseColumns(grid) {
|
|
59
67
|
const cells = grid.cells.slice();
|
|
60
68
|
for (let x = 0; x < grid.width; x += 1) {
|
|
@@ -88,6 +96,7 @@ function scanRuns(length, cellAtIndex, minLength, matches) {
|
|
|
88
96
|
}
|
|
89
97
|
return runs;
|
|
90
98
|
}
|
|
99
|
+
/** @internal */
|
|
91
100
|
export function findRuns(grid, minLength, matches = (a, b) => a === b) {
|
|
92
101
|
const runs = [];
|
|
93
102
|
for (let y = 0; y < grid.height; y += 1) {
|
|
@@ -6,18 +6,27 @@ export interface FallingPiece<TShape extends string = string> {
|
|
|
6
6
|
readonly y: number;
|
|
7
7
|
}
|
|
8
8
|
export type ShapeTable<TShape extends string = string> = Record<TShape, readonly (readonly (readonly [number, number])[])[]>;
|
|
9
|
+
/** @internal */
|
|
9
10
|
export declare function pieceCells<TShape extends string>(table: ShapeTable<TShape>, piece: FallingPiece<TShape>): readonly (readonly [number, number])[];
|
|
11
|
+
/** @internal */
|
|
10
12
|
export declare function pieceCollides<T, TShape extends string>(grid: CellGrid<T>, table: ShapeTable<TShape>, piece: FallingPiece<TShape>): boolean;
|
|
13
|
+
/** @internal */
|
|
11
14
|
export declare function mergePiece<T, TShape extends string>(grid: CellGrid<T>, table: ShapeTable<TShape>, piece: FallingPiece<TShape>, value: T): CellGrid<T>;
|
|
15
|
+
/** @internal */
|
|
12
16
|
export declare function dropDistance<T, TShape extends string>(grid: CellGrid<T>, table: ShapeTable<TShape>, piece: FallingPiece<TShape>): number;
|
|
17
|
+
/** @internal */
|
|
13
18
|
export declare function gravityInterval(level: number, base?: number, perLevel?: number, min?: number): number;
|
|
19
|
+
/** @internal */
|
|
14
20
|
export declare function levelForLines(lines: number, linesPerLevel?: number): number;
|
|
21
|
+
/** @internal */
|
|
15
22
|
export declare function lineScore(cleared: number, level: number, table?: readonly number[]): number;
|
|
16
23
|
export interface LockDelayState {
|
|
17
24
|
readonly delaySeconds: number;
|
|
18
25
|
readonly elapsed: number;
|
|
19
26
|
}
|
|
27
|
+
/** @internal */
|
|
20
28
|
export declare function createLockDelay(delaySeconds: number): LockDelayState;
|
|
29
|
+
/** @internal */
|
|
21
30
|
export declare function stepLockDelay(state: LockDelayState, grounded: boolean, dt: number): {
|
|
22
31
|
state: LockDelayState;
|
|
23
32
|
locked: boolean;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { cellAt } from "./cellGrid.js";
|
|
2
|
+
/** @internal */
|
|
2
3
|
export function pieceCells(table, piece) {
|
|
3
4
|
const rotations = table[piece.shape];
|
|
4
5
|
const index = ((piece.rotation % rotations.length) + rotations.length) % rotations.length;
|
|
5
6
|
const state = rotations[index];
|
|
6
7
|
return state.map(([ox, oy]) => [piece.x + ox, piece.y + oy]);
|
|
7
8
|
}
|
|
9
|
+
/** @internal */
|
|
8
10
|
export function pieceCollides(grid, table, piece) {
|
|
9
11
|
for (const [x, y] of pieceCells(table, piece)) {
|
|
10
12
|
if (x < 0 || x >= grid.width || y >= grid.height)
|
|
@@ -14,6 +16,7 @@ export function pieceCollides(grid, table, piece) {
|
|
|
14
16
|
}
|
|
15
17
|
return false;
|
|
16
18
|
}
|
|
19
|
+
/** @internal */
|
|
17
20
|
export function mergePiece(grid, table, piece, value) {
|
|
18
21
|
const cells = grid.cells.slice();
|
|
19
22
|
for (const [x, y] of pieceCells(table, piece)) {
|
|
@@ -22,25 +25,31 @@ export function mergePiece(grid, table, piece, value) {
|
|
|
22
25
|
}
|
|
23
26
|
return { width: grid.width, height: grid.height, cells };
|
|
24
27
|
}
|
|
28
|
+
/** @internal */
|
|
25
29
|
export function dropDistance(grid, table, piece) {
|
|
26
30
|
let distance = 0;
|
|
27
31
|
while (!pieceCollides(grid, table, { ...piece, y: piece.y + distance + 1 }))
|
|
28
32
|
distance += 1;
|
|
29
33
|
return distance;
|
|
30
34
|
}
|
|
35
|
+
/** @internal */
|
|
31
36
|
export function gravityInterval(level, base = 0.8, perLevel = 0.07, min = 0.05) {
|
|
32
37
|
return Math.max(min, base - level * perLevel);
|
|
33
38
|
}
|
|
39
|
+
/** @internal */
|
|
34
40
|
export function levelForLines(lines, linesPerLevel = 10) {
|
|
35
41
|
return Math.floor(lines / linesPerLevel);
|
|
36
42
|
}
|
|
37
43
|
const CLASSIC_LINE_SCORE = [0, 40, 100, 300, 1200];
|
|
44
|
+
/** @internal */
|
|
38
45
|
export function lineScore(cleared, level, table = CLASSIC_LINE_SCORE) {
|
|
39
46
|
return (table[cleared] ?? 0) * (level + 1);
|
|
40
47
|
}
|
|
48
|
+
/** @internal */
|
|
41
49
|
export function createLockDelay(delaySeconds) {
|
|
42
50
|
return { delaySeconds, elapsed: 0 };
|
|
43
51
|
}
|
|
52
|
+
/** @internal */
|
|
44
53
|
export function stepLockDelay(state, grounded, dt) {
|
|
45
54
|
if (!grounded)
|
|
46
55
|
return { state: { ...state, elapsed: 0 }, locked: false };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** A cell in a nonogram line: not yet determined, painted, or ruled out. */
|
|
2
|
+
export type NonogramCell = "unknown" | "filled" | "empty";
|
|
3
|
+
/** A line clue — the lengths of its consecutive filled runs, in order. */
|
|
4
|
+
export type NonogramClue = readonly number[];
|
|
5
|
+
/** A solved grid, row-major; `true` is a filled cell. */
|
|
6
|
+
export type NonogramSolution = readonly (readonly boolean[])[];
|
|
7
|
+
/** Run lengths of the filled cells in a boolean line — the clue a solved line yields.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare function runLengths(line: readonly boolean[]): number[];
|
|
11
|
+
/** Row and column clues derived from a solution grid — the puzzle a solved board poses.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export declare function deriveClues(solution: NonogramSolution): {
|
|
15
|
+
rows: number[][];
|
|
16
|
+
cols: number[][];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Constraint-propagate one line against its `clue`: intersect every clue-consistent arrangement, forcing a
|
|
20
|
+
* cell `filled` when it is filled in all of them and `empty` when empty in all, leaving the rest `unknown`.
|
|
21
|
+
* Returns the tightened line, or `null` on contradiction (no arrangement fits the current cells) — the
|
|
22
|
+
* per-line deduction step at the heart of every nonogram/picross solver.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export declare function solveLine(line: readonly NonogramCell[], clue: NonogramClue): NonogramCell[] | null;
|
|
26
|
+
/** Outcome of {@link solveNonogram}: the deduced board and whether propagation fully determined it. */
|
|
27
|
+
export interface NonogramSolveResult {
|
|
28
|
+
/** True when every cell is decided by line propagation alone (the puzzle is uniquely line-solvable). */
|
|
29
|
+
solved: boolean;
|
|
30
|
+
/** The board after propagation stalls — `unknown` cells remain when solving needs guessing. */
|
|
31
|
+
board: NonogramCell[][];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Solve a nonogram from its row and column clues by iterated line propagation until the board stops
|
|
35
|
+
* changing. `solved` is true iff the board is fully determined without guessing — the standard test for
|
|
36
|
+
* whether a nonogram is fair. Returns `solved: false` with a partial board on contradiction or ambiguity.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export declare function solveNonogram(rows: readonly NonogramClue[], cols: readonly NonogramClue[]): NonogramSolveResult;
|