@datamoc/mw_games 0.7.6 → 0.7.8
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 +359 -0
- package/README.md +7 -7
- package/dist/actors/Inventory.d.ts +7 -1
- package/dist/actors/Inventory.d.ts.map +1 -1
- package/dist/actors/Inventory.js.map +1 -1
- package/dist/actors/Shop.d.ts.map +1 -1
- package/dist/actors/Shop.js +4 -1
- package/dist/actors/Shop.js.map +1 -1
- package/dist/actors/craft.d.ts +35 -14
- package/dist/actors/craft.d.ts.map +1 -1
- package/dist/actors/craft.js +56 -24
- package/dist/actors/craft.js.map +1 -1
- package/dist/actors/index.d.ts +1 -1
- package/dist/actors/index.d.ts.map +1 -1
- package/dist/ai/Heuristics.d.ts +240 -0
- package/dist/ai/Heuristics.d.ts.map +1 -0
- package/dist/ai/Heuristics.js +298 -0
- package/dist/ai/Heuristics.js.map +1 -0
- package/dist/ai/index.d.ts +4 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +2 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/lua.d.ts +21 -0
- package/dist/ai/lua.d.ts.map +1 -1
- package/dist/ai/lua.js +21 -0
- package/dist/ai/lua.js.map +1 -1
- package/dist/ai/score.d.ts +162 -0
- package/dist/ai/score.d.ts.map +1 -0
- package/dist/ai/score.js +147 -0
- package/dist/ai/score.js.map +1 -0
- package/dist/assets/loader.d.ts +18 -4
- package/dist/assets/loader.d.ts.map +1 -1
- package/dist/assets/loader.js +40 -11
- package/dist/assets/loader.js.map +1 -1
- package/dist/audio/Positional.d.ts +125 -0
- package/dist/audio/Positional.d.ts.map +1 -0
- package/dist/audio/Positional.js +135 -0
- package/dist/audio/Positional.js.map +1 -0
- package/dist/audio/Sound.d.ts +7 -1
- package/dist/audio/Sound.d.ts.map +1 -1
- package/dist/audio/Sound.js +8 -2
- package/dist/audio/Sound.js.map +1 -1
- package/dist/audio/index.d.ts +2 -0
- package/dist/audio/index.d.ts.map +1 -1
- package/dist/audio/index.js +1 -0
- package/dist/audio/index.js.map +1 -1
- package/dist/battle/AttackDialog.d.ts +75 -0
- package/dist/battle/AttackDialog.d.ts.map +1 -0
- package/dist/battle/AttackDialog.js +115 -0
- package/dist/battle/AttackDialog.js.map +1 -0
- package/dist/battle/AttackPreview.d.ts +70 -0
- package/dist/battle/AttackPreview.d.ts.map +1 -0
- package/dist/battle/AttackPreview.js +78 -0
- package/dist/battle/AttackPreview.js.map +1 -0
- package/dist/battle/BattleStats.d.ts +45 -0
- package/dist/battle/BattleStats.d.ts.map +1 -0
- package/dist/battle/BattleStats.js +63 -0
- package/dist/battle/BattleStats.js.map +1 -0
- package/dist/battle/UnitSelector.d.ts +72 -0
- package/dist/battle/UnitSelector.d.ts.map +1 -0
- package/dist/battle/UnitSelector.js +117 -0
- package/dist/battle/UnitSelector.js.map +1 -0
- package/dist/battle/Whiteboard.d.ts +50 -0
- package/dist/battle/Whiteboard.d.ts.map +1 -0
- package/dist/battle/Whiteboard.js +94 -0
- package/dist/battle/Whiteboard.js.map +1 -0
- package/dist/battle/index.d.ts +10 -0
- package/dist/battle/index.d.ts.map +1 -1
- package/dist/battle/index.js +5 -0
- package/dist/battle/index.js.map +1 -1
- package/dist/board/Classics.d.ts.map +1 -1
- package/dist/board/Classics.js +51 -39
- package/dist/board/Classics.js.map +1 -1
- package/dist/board/FogOfWar.d.ts +32 -2
- package/dist/board/FogOfWar.d.ts.map +1 -1
- package/dist/board/FogOfWar.js +70 -6
- package/dist/board/FogOfWar.js.map +1 -1
- package/dist/board/HexSkirmish.d.ts.map +1 -1
- package/dist/board/HexSkirmish.js +69 -20
- package/dist/board/HexSkirmish.js.map +1 -1
- package/dist/board/Tactics.d.ts +7 -0
- package/dist/board/Tactics.d.ts.map +1 -1
- package/dist/board/Tactics.js +2 -2
- package/dist/board/Tactics.js.map +1 -1
- package/dist/core/Achievements.d.ts +40 -7
- package/dist/core/Achievements.d.ts.map +1 -1
- package/dist/core/Achievements.js +53 -7
- package/dist/core/Achievements.js.map +1 -1
- package/dist/core/Hex.d.ts +26 -6
- package/dist/core/Hex.d.ts.map +1 -1
- package/dist/core/Hex.js +40 -13
- package/dist/core/Hex.js.map +1 -1
- package/dist/core/Input.d.ts +36 -0
- package/dist/core/Input.d.ts.map +1 -1
- package/dist/core/Input.js +63 -1
- package/dist/core/Input.js.map +1 -1
- package/dist/core/Random.d.ts +93 -0
- package/dist/core/Random.d.ts.map +1 -1
- package/dist/core/Random.js +177 -0
- package/dist/core/Random.js.map +1 -1
- package/dist/core/SyncGuard.d.ts +57 -0
- package/dist/core/SyncGuard.d.ts.map +1 -0
- package/dist/core/SyncGuard.js +116 -0
- package/dist/core/SyncGuard.js.map +1 -0
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/i18n/Po.d.ts +51 -0
- package/dist/i18n/Po.d.ts.map +1 -0
- package/dist/i18n/Po.js +176 -0
- package/dist/i18n/Po.js.map +1 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/index.js.map +1 -1
- package/dist/mw_games.global.js +104 -98
- package/dist/mwl/MapFile.d.ts +41 -0
- package/dist/mwl/MapFile.d.ts.map +1 -0
- package/dist/mwl/MapFile.js +43 -0
- package/dist/mwl/MapFile.js.map +1 -0
- package/dist/mwl/actors.d.ts +46 -2
- package/dist/mwl/actors.d.ts.map +1 -1
- package/dist/mwl/actors.js +46 -2
- package/dist/mwl/actors.js.map +1 -1
- package/dist/mwl/campaign.d.ts +51 -0
- package/dist/mwl/campaign.d.ts.map +1 -0
- package/dist/mwl/campaign.js +58 -0
- package/dist/mwl/campaign.js.map +1 -0
- package/dist/mwl/carryover.d.ts +86 -0
- package/dist/mwl/carryover.d.ts.map +1 -0
- package/dist/mwl/carryover.js +70 -0
- package/dist/mwl/carryover.js.map +1 -0
- package/dist/mwl/catalog.d.ts +10 -1
- package/dist/mwl/catalog.d.ts.map +1 -1
- package/dist/mwl/catalog.js +10 -1
- package/dist/mwl/catalog.js.map +1 -1
- package/dist/mwl/compiler.d.ts +70 -3
- package/dist/mwl/compiler.d.ts.map +1 -1
- package/dist/mwl/compiler.js +70 -3
- package/dist/mwl/compiler.js.map +1 -1
- package/dist/mwl/conditions.d.ts +10 -1
- package/dist/mwl/conditions.d.ts.map +1 -1
- package/dist/mwl/conditions.js +10 -1
- package/dist/mwl/conditions.js.map +1 -1
- package/dist/mwl/content.d.ts +21 -0
- package/dist/mwl/content.d.ts.map +1 -1
- package/dist/mwl/content.js +19 -0
- package/dist/mwl/content.js.map +1 -1
- package/dist/mwl/expression.d.ts +21 -0
- package/dist/mwl/expression.d.ts.map +1 -1
- package/dist/mwl/expression.js +21 -0
- package/dist/mwl/expression.js.map +1 -1
- package/dist/mwl/fengari.d.ts +12 -1
- package/dist/mwl/fengari.d.ts.map +1 -1
- package/dist/mwl/fengari.js +12 -1
- package/dist/mwl/fengari.js.map +1 -1
- package/dist/mwl/grammar.d.ts +45 -1
- package/dist/mwl/grammar.d.ts.map +1 -1
- package/dist/mwl/grammar.js +45 -1
- package/dist/mwl/grammar.js.map +1 -1
- package/dist/mwl/hooks.d.ts +51 -6
- package/dist/mwl/hooks.d.ts.map +1 -1
- package/dist/mwl/hooks.js +45 -1
- package/dist/mwl/hooks.js.map +1 -1
- package/dist/mwl/index.d.ts +9 -3
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +5 -2
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/persistence.d.ts +32 -0
- package/dist/mwl/persistence.d.ts.map +1 -1
- package/dist/mwl/persistence.js +32 -0
- package/dist/mwl/persistence.js.map +1 -1
- package/dist/mwl/readers.d.ts +24 -2
- package/dist/mwl/readers.d.ts.map +1 -1
- package/dist/mwl/readers.js +27 -4
- package/dist/mwl/readers.js.map +1 -1
- package/dist/mwl/report.d.ts +21 -2
- package/dist/mwl/report.d.ts.map +1 -1
- package/dist/mwl/report.js +21 -2
- package/dist/mwl/report.js.map +1 -1
- package/dist/mwl/runtime.d.ts +212 -7
- package/dist/mwl/runtime.d.ts.map +1 -1
- package/dist/mwl/runtime.js +682 -90
- package/dist/mwl/runtime.js.map +1 -1
- package/dist/mwl/schema.d.ts +57 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/schema.js +181 -21
- package/dist/mwl/schema.js.map +1 -1
- package/dist/mwl/scripts.d.ts +12 -1
- package/dist/mwl/scripts.d.ts.map +1 -1
- package/dist/mwl/scripts.js +12 -1
- package/dist/mwl/scripts.js.map +1 -1
- package/dist/mwl/utils.d.ts +2 -0
- package/dist/mwl/utils.d.ts.map +1 -1
- package/dist/mwl/utils.js +4 -1
- package/dist/mwl/utils.js.map +1 -1
- package/dist/roguelike/MultiTurnBeam.d.ts +50 -12
- package/dist/roguelike/MultiTurnBeam.d.ts.map +1 -1
- package/dist/roguelike/MultiTurnBeam.js +100 -53
- package/dist/roguelike/MultiTurnBeam.js.map +1 -1
- package/dist/roguelike/Targeting.d.ts +94 -0
- package/dist/roguelike/Targeting.d.ts.map +1 -1
- package/dist/roguelike/Targeting.js +123 -0
- package/dist/roguelike/Targeting.js.map +1 -1
- package/dist/roguelike/index.d.ts +3 -1
- package/dist/roguelike/index.d.ts.map +1 -1
- package/dist/roguelike/index.js +1 -0
- package/dist/roguelike/index.js.map +1 -1
- package/dist/rpg/GameState.d.ts +2 -2
- package/dist/rpg/GameState.js +2 -2
- package/dist/simulation/CampaignSave.d.ts +68 -0
- package/dist/simulation/CampaignSave.d.ts.map +1 -0
- package/dist/simulation/CampaignSave.js +54 -0
- package/dist/simulation/CampaignSave.js.map +1 -0
- package/dist/simulation/EventPresentation.d.ts +111 -0
- package/dist/simulation/EventPresentation.d.ts.map +1 -0
- package/dist/simulation/EventPresentation.js +120 -0
- package/dist/simulation/EventPresentation.js.map +1 -0
- package/dist/simulation/index.d.ts +4 -0
- package/dist/simulation/index.d.ts.map +1 -1
- package/dist/simulation/index.js +2 -0
- package/dist/simulation/index.js.map +1 -1
- package/dist/two-d/pixi-interop.d.ts +18 -6
- package/dist/two-d/pixi-interop.d.ts.map +1 -1
- package/dist/two-d/pixi-interop.js +18 -6
- package/dist/two-d/pixi-interop.js.map +1 -1
- package/dist/two-d/render/AnimatedSprite.d.ts +74 -7
- package/dist/two-d/render/AnimatedSprite.d.ts.map +1 -1
- package/dist/two-d/render/AnimatedSprite.js +88 -26
- package/dist/two-d/render/AnimatedSprite.js.map +1 -1
- package/dist/two-d/render/Camera.d.ts +64 -4
- package/dist/two-d/render/Camera.d.ts.map +1 -1
- package/dist/two-d/render/Camera.js +132 -11
- package/dist/two-d/render/Camera.js.map +1 -1
- package/dist/two-d/render/ColorTransformBatcher.d.ts +7 -1
- package/dist/two-d/render/ColorTransformBatcher.d.ts.map +1 -1
- package/dist/two-d/render/ColorTransformBatcher.js +10 -1
- package/dist/two-d/render/ColorTransformBatcher.js.map +1 -1
- package/dist/two-d/render/Halo.d.ts +58 -0
- package/dist/two-d/render/Halo.d.ts.map +1 -0
- package/dist/two-d/render/Halo.js +48 -0
- package/dist/two-d/render/Halo.js.map +1 -0
- package/dist/two-d/render/ImageModifiers.d.ts +174 -0
- package/dist/two-d/render/ImageModifiers.d.ts.map +1 -1
- package/dist/two-d/render/ImageModifiers.js +454 -1
- package/dist/two-d/render/ImageModifiers.js.map +1 -1
- package/dist/two-d/render/LightningArc.d.ts +57 -0
- package/dist/two-d/render/LightningArc.d.ts.map +1 -0
- package/dist/two-d/render/LightningArc.js +91 -0
- package/dist/two-d/render/LightningArc.js.map +1 -0
- package/dist/two-d/render/PaletteRemap.d.ts +135 -0
- package/dist/two-d/render/PaletteRemap.d.ts.map +1 -0
- package/dist/two-d/render/PaletteRemap.js +181 -0
- package/dist/two-d/render/PaletteRemap.js.map +1 -0
- package/dist/two-d/render/Particles.d.ts +26 -0
- package/dist/two-d/render/Particles.d.ts.map +1 -1
- package/dist/two-d/render/Particles.js +23 -2
- package/dist/two-d/render/Particles.js.map +1 -1
- package/dist/two-d/render/SpriteAttachment.d.ts +55 -0
- package/dist/two-d/render/SpriteAttachment.d.ts.map +1 -0
- package/dist/two-d/render/SpriteAttachment.js +60 -0
- package/dist/two-d/render/SpriteAttachment.js.map +1 -0
- package/dist/two-d/render/TerrainGraphics.d.ts +142 -0
- package/dist/two-d/render/TerrainGraphics.d.ts.map +1 -0
- package/dist/two-d/render/TerrainGraphics.js +161 -0
- package/dist/two-d/render/TerrainGraphics.js.map +1 -0
- package/dist/two-d/render/TerrainGraphicsLayer.d.ts +55 -0
- package/dist/two-d/render/TerrainGraphicsLayer.d.ts.map +1 -0
- package/dist/two-d/render/TerrainGraphicsLayer.js +54 -0
- package/dist/two-d/render/TerrainGraphicsLayer.js.map +1 -0
- package/dist/two-d/render/TintedSprite.js +2 -2
- package/dist/two-d/render/TintedSprite.js.map +1 -1
- package/dist/two-d/render/index.d.ts +15 -3
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +7 -1
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/two-d/stage/StoryScreen.d.ts +110 -0
- package/dist/two-d/stage/StoryScreen.d.ts.map +1 -0
- package/dist/two-d/stage/StoryScreen.js +178 -0
- package/dist/two-d/stage/StoryScreen.js.map +1 -0
- package/dist/two-d/stage/index.d.ts +2 -0
- package/dist/two-d/stage/index.d.ts.map +1 -1
- package/dist/two-d/stage/index.js +1 -0
- package/dist/two-d/stage/index.js.map +1 -1
- package/dist/two-d/ui/Checkbox.d.ts +44 -0
- package/dist/two-d/ui/Checkbox.d.ts.map +1 -0
- package/dist/two-d/ui/Checkbox.js +89 -0
- package/dist/two-d/ui/Checkbox.js.map +1 -0
- package/dist/two-d/ui/DataTable.d.ts +79 -0
- package/dist/two-d/ui/DataTable.d.ts.map +1 -0
- package/dist/two-d/ui/DataTable.js +164 -0
- package/dist/two-d/ui/DataTable.js.map +1 -0
- package/dist/two-d/ui/Dropdown.d.ts +72 -0
- package/dist/two-d/ui/Dropdown.d.ts.map +1 -0
- package/dist/two-d/ui/Dropdown.js +126 -0
- package/dist/two-d/ui/Dropdown.js.map +1 -0
- package/dist/two-d/ui/FloatingText.d.ts +43 -4
- package/dist/two-d/ui/FloatingText.d.ts.map +1 -1
- package/dist/two-d/ui/FloatingText.js +52 -5
- package/dist/two-d/ui/FloatingText.js.map +1 -1
- package/dist/two-d/ui/FloatingTextStack.d.ts +86 -13
- package/dist/two-d/ui/FloatingTextStack.d.ts.map +1 -1
- package/dist/two-d/ui/FloatingTextStack.js +89 -18
- package/dist/two-d/ui/FloatingTextStack.js.map +1 -1
- package/dist/two-d/ui/Layout.d.ts +105 -0
- package/dist/two-d/ui/Layout.d.ts.map +1 -0
- package/dist/two-d/ui/Layout.js +174 -0
- package/dist/two-d/ui/Layout.js.map +1 -0
- package/dist/two-d/ui/MarkupText.d.ts +53 -0
- package/dist/two-d/ui/MarkupText.d.ts.map +1 -0
- package/dist/two-d/ui/MarkupText.js +122 -0
- package/dist/two-d/ui/MarkupText.js.map +1 -0
- package/dist/two-d/ui/ScrollBox.d.ts +67 -0
- package/dist/two-d/ui/ScrollBox.d.ts.map +1 -0
- package/dist/two-d/ui/ScrollBox.js +127 -0
- package/dist/two-d/ui/ScrollBox.js.map +1 -0
- package/dist/two-d/ui/Skins.d.ts +59 -0
- package/dist/two-d/ui/Skins.d.ts.map +1 -0
- package/dist/two-d/ui/Skins.js +77 -0
- package/dist/two-d/ui/Skins.js.map +1 -0
- package/dist/two-d/ui/Slider.d.ts +91 -0
- package/dist/two-d/ui/Slider.d.ts.map +1 -0
- package/dist/two-d/ui/Slider.js +170 -0
- package/dist/two-d/ui/Slider.js.map +1 -0
- package/dist/two-d/ui/Spinner.d.ts +67 -0
- package/dist/two-d/ui/Spinner.d.ts.map +1 -0
- package/dist/two-d/ui/Spinner.js +137 -0
- package/dist/two-d/ui/Spinner.js.map +1 -0
- package/dist/two-d/ui/TabbedList.d.ts +118 -0
- package/dist/two-d/ui/TabbedList.d.ts.map +1 -0
- package/dist/two-d/ui/TabbedList.js +221 -0
- package/dist/two-d/ui/TabbedList.js.map +1 -0
- package/dist/two-d/ui/TextModel.d.ts +65 -0
- package/dist/two-d/ui/TextModel.d.ts.map +1 -0
- package/dist/two-d/ui/TextModel.js +126 -0
- package/dist/two-d/ui/TextModel.js.map +1 -0
- package/dist/two-d/ui/TreeView.d.ts +68 -0
- package/dist/two-d/ui/TreeView.d.ts.map +1 -0
- package/dist/two-d/ui/TreeView.js +133 -0
- package/dist/two-d/ui/TreeView.js.map +1 -0
- package/dist/two-d/ui/Window.d.ts +13 -0
- package/dist/two-d/ui/Window.d.ts.map +1 -1
- package/dist/two-d/ui/Window.js +23 -0
- package/dist/two-d/ui/Window.js.map +1 -1
- package/dist/two-d/ui/WindowStack.d.ts.map +1 -1
- package/dist/two-d/ui/WindowStack.js +2 -0
- package/dist/two-d/ui/WindowStack.js.map +1 -1
- package/dist/two-d/ui/index.d.ts +29 -3
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +15 -2
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/two-d/ui/markup.d.ts +181 -0
- package/dist/two-d/ui/markup.d.ts.map +1 -0
- package/dist/two-d/ui/markup.js +370 -0
- package/dist/two-d/ui/markup.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/world/SideTurns.d.ts +115 -0
- package/dist/world/SideTurns.d.ts.map +1 -0
- package/dist/world/SideTurns.js +138 -0
- package/dist/world/SideTurns.js.map +1 -0
- package/dist/world/index.d.ts +2 -0
- package/dist/world/index.d.ts.map +1 -1
- package/dist/world/index.js +1 -0
- package/dist/world/index.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,365 @@ All notable changes to `mwg` are documented here. Format follows
|
|
|
5
5
|
[Semantic Versioning](https://semver.org/) as of this first release - a 0.y.z version means
|
|
6
6
|
the public API may still change between minor versions.
|
|
7
7
|
|
|
8
|
+
## [0.7.8] - 2026-09-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Unit identity usable by the AI. MWL units now carry their own `name`, `role`/function and
|
|
13
|
+
`can_recruit` leader flag: `[unit]` sets them, a side's own leader is `can_recruit`, `[role]`
|
|
14
|
+
stamps the role onto the units it matches, `[store_unit]`/save keep them, and `unitMatchesFilter`
|
|
15
|
+
reads all three - which also wires up the `can_recruit` the `[filter]` schema already allowed but
|
|
16
|
+
the runtime ignored. On the AI side, `ScoreSubject` and `HeuristicCandidate` carry
|
|
17
|
+
`type`/`role`/`can_recruit`/`name`, and the new `subjectsWhere`/`ScoreSubjectFilter` select a world
|
|
18
|
+
on any of them, so a mind can find "the enemy leader" without re-deriving it from ids.
|
|
19
|
+
- Leader identity on the unit (item 296). An autospawned `[side] leader=` unit carries `leader: true`
|
|
20
|
+
beside its `can_recruit`, `[store_unit]`/unstore and a save keep it, and `unitMatchesFilter` reads
|
|
21
|
+
it, so `[filter] leader=yes` finds the side's own leader without recomputing
|
|
22
|
+
`sides[id].leader === id`.
|
|
23
|
+
- One variable-path resolver for every reader (item 295). `$name` resolution, `[condition]`/
|
|
24
|
+
`[filter_condition]` variable reads, message interpolation and the bare `$name` copy all resolve
|
|
25
|
+
through the same path walker `set_variable` writes with, so a dotted name like `a.b` reads what
|
|
26
|
+
`[set_variable] name=a.b` wrote. Array indices are in scope (`a[0].b` reads the node `a.0.b` or
|
|
27
|
+
`a[0].b` wrote), an index that is not a whole number is refused by name rather than becoming a
|
|
28
|
+
literal key, and the `id` schema type accepts brackets so such a name compiles.
|
|
29
|
+
- `TerrainGraphicsLayer` (item 257): the renderer half of `[terrain_graphics]`, drawing
|
|
30
|
+
`resolveTerrainGraphics`'s placements as one `Sprite2D` per placement, in `layer` order (a stable
|
|
31
|
+
sort, so the rule pass's own row-major walk survives within a layer) at the pixel position a
|
|
32
|
+
caller-supplied `project` callback reports, with images resolved through the asset resolver.
|
|
33
|
+
`setPlacements` redraws in place.
|
|
34
|
+
- The canvas backend for inline markup, closing the three pieces item 258's acceptance still
|
|
35
|
+
named as open: `positionMarkupLines` places `layoutMarkupLines`'s lines into positioned
|
|
36
|
+
`PositionedMarkupSpan` runs under a `MarkupLayout`'s `direction`/`align`, so an `rtl` line flows
|
|
37
|
+
right to left and alignment defaults to the direction's own edge, and `MarkupText` draws them as
|
|
38
|
+
the counterpart to `RichLabel`'s HTML text - one `Text2D` per styled run, one `Sprite2D` per
|
|
39
|
+
`<img>` span resolved through the asset resolver, so an image is drawn rather than left to the
|
|
40
|
+
caller to position. An RTL sample is now covered by `tests/markup.test.ts`.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- One rule for the `id` value type, shared by the schema and `mwl.readers`. The schema accepts a
|
|
45
|
+
bracketed path like `a[0].b` as an `id` (a variable name legitimately carries index brackets),
|
|
46
|
+
but `readAttributes`' `id` and `id-list` kept a stricter copy of the pattern, so an adapter
|
|
47
|
+
reading a variable-name attribute raised `MWL_FIELD_TYPE` for a name the compiler had already
|
|
48
|
+
accepted. Both now call the exported `isMwlId`. One test in `tests/mwl.test.ts`.
|
|
49
|
+
- `actors.sell` is transactional again. It ignored the result of `Inventory.add`, so selling into
|
|
50
|
+
a shop stock with no room paid the seller and lost the item: two potions sold into a
|
|
51
|
+
capacity-1 stock produced 10 gold from nothing and left the potions nowhere. It now rolls the
|
|
52
|
+
bag back and refuses, exactly as `buy` already did for a full bag. One test in
|
|
53
|
+
`tests/shop.test.ts`.
|
|
54
|
+
- `board.goScore` counts territory again. Its `group` helper returned nothing for an empty
|
|
55
|
+
square, so the area-scoring loop never saw an enclosed empty region and only stones were
|
|
56
|
+
scored: four stones ringing a 3x3 board reported 4 instead of 9. `group` now groups connected
|
|
57
|
+
cells by value with `null` included, which leaves `liberties`/`playGo` unchanged because they
|
|
58
|
+
only ever pass a stone. One test, plus new coverage for `rollBackgammonDice`, a foundation
|
|
59
|
+
move from a tableau column, and `DiceCup.clearKept`, in `tests/classics.test.ts`.
|
|
60
|
+
- `board.addTacticalUnit` remembers each unit's own action budget, so `endTacticalTurn` refreshes
|
|
61
|
+
`actions` to it instead of a hardcoded two. A unit created with `actions: 3` was silently reset
|
|
62
|
+
to 2 every turn; the per-turn maximum is now `TacticalUnit.maxActions`, filled from the initial
|
|
63
|
+
`actions` when the caller does not set it. Six tests in `tests/tactics.test.ts`, which also
|
|
64
|
+
cover the overwatch reaction and attack paths that had none.
|
|
65
|
+
- `board.backgammonMoves` follows the bearing-off rules. It offered a bear-off from any point
|
|
66
|
+
whose roll reached past the off edge, so at the opening position a 6 came off from point 18
|
|
67
|
+
while checkers still sat on 0, 11 and 16. A bear-off now needs every checker in the home
|
|
68
|
+
board with none on the bar; an exact roll still takes any home checker, and an over-roll takes
|
|
69
|
+
only the checker nearest the off edge, since a checker must never skip past another. Three
|
|
70
|
+
tests in `tests/classics.test.ts`.
|
|
71
|
+
- An `[if]` branch no longer tries to execute its own `[condition]` child. The schema allows a
|
|
72
|
+
branch to carry one, but the executor ran every child, so an `[if]` whose condition held threw
|
|
73
|
+
`unknown MWL command: condition` instead of running its body; a false condition hid it because
|
|
74
|
+
the body never ran. `[if]`/`[else]` now run their command children only, the same rule
|
|
75
|
+
`[while]` already followed. Two tests in `tests/mwl-conditions.test.ts`.
|
|
76
|
+
- An `[else]` following an `[if]` is that branch's other half, so only one of the two runs. A
|
|
77
|
+
taken `[if]` used to run its own body and then fall through to the `[else]` as well, so both
|
|
78
|
+
branches executed; the `[else]` is now skipped when the `[if]` was taken, and run as the
|
|
79
|
+
fallback when it was not. Independent pairs still work, and a free-standing `[else]` with no
|
|
80
|
+
`[if]` before it still runs. Two tests in `tests/mwl-conditions.test.ts`.
|
|
81
|
+
- `[while]` had the same defect as `[if]`, so a loop body carrying a `[condition]` child threw.
|
|
82
|
+
It now runs its command children too. One test in `tests/mwl-variables.test.ts`.
|
|
83
|
+
- The variable-path readers item 295 named are now complete, closing three that were still flat:
|
|
84
|
+
a dialogue `[choice]`'s `variable=` gate, `[store_unit]`/`[unstore_unit]`/`[recall]`'s stored
|
|
85
|
+
list, and the hook host's `setVariable`, plus the public `execute()`'s `set_variable`. An
|
|
86
|
+
indexed path now builds a real array (`a[0]`, `a[1]`), so a stored list and an indexed write
|
|
87
|
+
agree on their shape. One test each in `tests/mwl-dialogue.test.ts`, `tests/mwl-actions.test.ts`
|
|
88
|
+
and `tests/mwl.test.ts`, and the `a[0].b` test now asserts the array.
|
|
89
|
+
|
|
90
|
+
### Changed
|
|
91
|
+
|
|
92
|
+
- `board.skirmishMoves` computes every reachable cell from one Dijkstra pass over the map
|
|
93
|
+
instead of one per candidate cell. The old per-cell search also re-sorted its own frontier
|
|
94
|
+
every step and `shift()`ed it, so it went quadratic in path length; the pass now uses a
|
|
95
|
+
binary min-heap. Behaviour is unchanged, verified by a differential run of the old and new
|
|
96
|
+
implementations over 58 randomised terrain maps. A `[complexity]` test keeps 20 calls on a
|
|
97
|
+
40x40 map under a ceiling far below the old cost, and a test pins that a cell held by
|
|
98
|
+
another unit is never offered as a move.
|
|
99
|
+
|
|
100
|
+
## [0.7.7] - 2026-09-11
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
|
|
104
|
+
- Heuristic AI (item 269): `Aspects`, `Difficulty`, `Goals`, `RecruitmentPattern`, and a
|
|
105
|
+
`HeuristicAI` candidate/stage pipeline with `defaultWeigh`/`keepAwayScore`/`goalScore`. Aspects
|
|
106
|
+
ship no values; the numbers stay content, and `keep_away` is a real penalty.
|
|
107
|
+
- Achievements and battle statistics (item 273): `core.Achievements` gained sub-achievements
|
|
108
|
+
(multi-criterion unlocks via `AchievementDef.criteria`, read back with `subProgress`), and
|
|
109
|
+
`battle.BattleStats` tracks recruits/recalls/advances/kills/deaths/damage dealt/damage taken by
|
|
110
|
+
unit type for a `PlayerStats`/`RunHistory` summary to fold in.
|
|
111
|
+
- Free map rotation (item 286): `Camera.rotateTo`/`animateRotationTo` turn the view to any angle,
|
|
112
|
+
not only a grid's whole steps, sharing 285's layer-level transform and taking the shorter way
|
|
113
|
+
around a full turn when animated.
|
|
114
|
+
- Battle UI models (item 265): `AttackPreview` (damage totals and an animated frame timeline from
|
|
115
|
+
the game's own numbers), `AttackDialog` (the selector plus the preview and its clock),
|
|
116
|
+
`UnitSelector` (attacker then target), and `Whiteboard` (planned orders with undo/redo). All
|
|
117
|
+
renderer-free; the dialog's pixels are `Bar`/`Label` a game composes.
|
|
118
|
+
- Story screens (item 264): `StoryScreen` (a full-screen backdrop, title and text advanced by a
|
|
119
|
+
click) over the renderer-free `StorySequence` (`advance`/`back`/`goTo`/`skip`/`restart`, with the
|
|
120
|
+
current beat's `music` reported as a signal). `StoryBeat` matches `MwlWorld.story`'s shape.
|
|
121
|
+
- Data-driven shell layout and skins (item 263): `Layout` (`resolveAnchor`/`anchorAlign` over nine
|
|
122
|
+
named anchors plus `fill`, and a `Grid` of `size`-or-`grow` tracks) and `Skins` (per-widget,
|
|
123
|
+
per-state looks with a widget-state -> widget-idle -> wildcard fallback chain, and `Skins.from`
|
|
124
|
+
for plain data). Both renderer-free.
|
|
125
|
+
- The missing UI widgets (item 261): `Slider` (`sliderFraction`/`sliderValueAt`), `Checkbox`,
|
|
126
|
+
`Spinner` (`spinValue`), `Dropdown`, `TextModel`, `DataTable`, `TreeView` and `ScrollBox`
|
|
127
|
+
(`scrollOffset`). The rule-bearing parts are pure functions or renderer-free models tested
|
|
128
|
+
headlessly, the drawing is a thin theme-driven shell, and text fields pair `TextModel` with a
|
|
129
|
+
`Label` rather than a separate `TextArea`.
|
|
130
|
+
- Fixed-angle view rotation on `Camera` (item 285): `grid: 'square' | 'hex'` sets four quarter turns
|
|
131
|
+
or six 60-degree steps, `setRotationStep`/`rotate` move through them, `toScreen`/`toWorld` invert
|
|
132
|
+
the turn, `view` reports the box around the turned viewport for culling, and `uprightRotation`
|
|
133
|
+
keeps a label drawn into the world upright.
|
|
134
|
+
- WML action vocabulary in `[event]` (item 250): `fire_event`, `store_unit`/`unstore_unit`/`recall`,
|
|
135
|
+
`modify_unit`/`heal_unit`, `set_terrain`, `capture_village`, `clear_shroud`, and the scenario-level
|
|
136
|
+
`[role]`/`[object]`/`[story]`, backed by `MwlWorld.villages`/`clearedShroud`/`roles`/`objects`/
|
|
137
|
+
`story` (all saved). WML's scenario `[item]` is deliberately not added: the tag already means an
|
|
138
|
+
inventory item definition.
|
|
139
|
+
- `blendPixels`/`rotatePixels` in `ImageModifiers.ts`: `~BLEND` and `~ROTATE` moved from a
|
|
140
|
+
runtime sprite-property/`ColorMatrixFilter` approximation to an exact, baked-once per-pixel
|
|
141
|
+
operation in `applyTextureModifiers` (`~ROTATE` in particular now rotates the source pixels
|
|
142
|
+
and expands the surface, which a sprite's own `rotation` cannot do - needed for terrain and
|
|
143
|
+
anything else that must keep tiling after the rotation). `blendMatrix` stays available for a
|
|
144
|
+
caller that explicitly wants the cheaper live approximation instead.
|
|
145
|
+
- `PaletteRemapMode` (`'exact'` | `'nearest'`) on `remapPixels`/`recolorTexture`, defaulting to
|
|
146
|
+
`'exact'`: a pixel is now repainted only on an exact match to a `from` colour unless
|
|
147
|
+
`'nearest'` is asked for explicitly. The old always-nearest behaviour silently recoloured an
|
|
148
|
+
entire image the first time `~RC`/`~PAL` met a short, specific palette instead of a full
|
|
149
|
+
covering; `paletteRangeMapping`'s own gradient usage opts into `'nearest'` explicitly, since
|
|
150
|
+
that is the one case it is correct for.
|
|
151
|
+
- `ImageTextureProbe.resolveColor` and the exported `parseColorPairs`/`parsePaletteLists`: `~RC`
|
|
152
|
+
and `~PAL` now accept a named colour (`~RC(magenta>red)`), not hex only, and `~PAL`'s two
|
|
153
|
+
comma-separated colour lists parse correctly instead of only the first colour of each list
|
|
154
|
+
(`parseImagePath`'s own comma split does not respect that list's internal boundary, which
|
|
155
|
+
`parsePaletteLists` now reconstructs).
|
|
156
|
+
- `~BLIT`/`~MASK` now hand `resolveTexture` the argument exactly as written, nested modifiers
|
|
157
|
+
included (`~BLIT(unit.png~RC(magenta>red),0,0)` calls it with the full string, not a bare
|
|
158
|
+
path with the modifier silently dropped).
|
|
159
|
+
- `withTextureCanvas` is now exported from `two-d/render`, so a caller building its own
|
|
160
|
+
texture-level modifier can reuse the same canvas bookkeeping `recolorTexture`/`~BLIT`/`~MASK`/
|
|
161
|
+
`~BLEND`/`~ROTATE` all share instead of duplicating it.
|
|
162
|
+
|
|
163
|
+
- `mwl.parseMapFile`/`MwlMapFile` (item 284): a Wesnoth-shaped `.map` loader. The `key=value`
|
|
164
|
+
header is split off and kept (keys not interpreted), and the comma-separated grid goes through
|
|
165
|
+
the same `parseTerrain` an inline `[map] terrain=` uses.
|
|
166
|
+
- `actors.craft` category-shaped ingredients (item 289): `Ingredient` now accepts `id` as a string
|
|
167
|
+
or a list, a `category` matched against the item definition's new `InventoryItem.category`
|
|
168
|
+
(kind-level, so it stays out of saves), or a `matches(item)` predicate. `craft` allocates against
|
|
169
|
+
a working copy so two flexible ingredients cannot count one stack twice.
|
|
170
|
+
- `two-d/render/SpriteAttachment.ts`: `SpriteAttachment` (item 291), ties a second sprite's
|
|
171
|
+
position to a first one's - `follow(x, y)` applies an offset, an optional `duration` makes
|
|
172
|
+
`update(dt)` report `done` once it elapses, so a permanent shadow and a temporary status icon
|
|
173
|
+
are the same class with different options. Renderer-neutral like `Projectile`/`LightningArc`.
|
|
174
|
+
|
|
175
|
+
- `two-d/render/LightningArc.ts`: `LightningArc` (item 292), the position data for a jittered
|
|
176
|
+
line between two points - a lightning bolt, a tether, a chain-lightning link - geometry only,
|
|
177
|
+
drawn by the caller through `Shape2D`'s `Graphics`. `retarget` moves either endpoint for a
|
|
178
|
+
tether following two moving units; an optional `flickerInterval` re-rolls the jitter on a
|
|
179
|
+
timer instead of holding one fixed shape.
|
|
180
|
+
- `assets.load`'s `optional`/`onMissing` options (item 287): paths a game can do without load
|
|
181
|
+
separately from the required batch, so one missing file never aborts the rest; `texture`/`get`
|
|
182
|
+
take a `fallback` value returned instead of a throw for a path that never loaded.
|
|
183
|
+
|
|
184
|
+
- `MultiTurnBeam` fronts, `blocker`, `onCell` and saved shape identity (item 278): a beam is now a
|
|
185
|
+
sequence of per-turn fronts rather than one captured cell per turn, so a game-supplied
|
|
186
|
+
`fronts(previous, turn)` expresses a cone, burst, fork or moving front. `BeamBlocker` replaces
|
|
187
|
+
the implicit blocker flags with one policy, `BeamStep.cells` reports every reached cell, and a
|
|
188
|
+
save carries the shape name so `fromJSON` refuses a mismatched shape; pre-fronts saves still load.
|
|
189
|
+
- `two-d/render/PaletteRemap.ts`: `remapPixels`/`paletteRangeMapping`/`recolorTexture` (item
|
|
190
|
+
256), a nearest-colour palette remap for team-colour-by-range - `paletteRangeMapping` places a
|
|
191
|
+
reference palette's own lightest-to-darkest order along a `min -> mid -> max` gradient,
|
|
192
|
+
`remapPixels` is the renderer-free pixel core, and `recolorTexture` (via the new shared
|
|
193
|
+
`withTextureCanvas` helper) is the canvas-backed wrapper.
|
|
194
|
+
- Eleven more `image~MOD` suffixes in `ImageModifiers.ts` (item 255): `~O`, `~R`/`~G`/`~B`,
|
|
195
|
+
`~BLEND` and `~CHAN` join `~FL`/`~SCALE`/`~GS`/`~CS` as sprite-property/`ColorMatrixFilter`
|
|
196
|
+
operations on `applyImageModifiers`; `~ROTATE` sets the sprite's own rotation. `~RC`, `~PAL`,
|
|
197
|
+
`~BLIT` and `~MASK` needed real pixel access or a sibling texture, so they are the new
|
|
198
|
+
`applyTextureModifiers`, built on 256's `withTextureCanvas`. `~GS` no longer replaces a filter
|
|
199
|
+
already on the sprite (was clobbering, now appends).
|
|
200
|
+
- `two-d/render/TerrainGraphics.ts`: `resolveTerrainGraphics`/`TerrainRule`/`matchTerrainRule`/
|
|
201
|
+
`squareRotate`/`hexRotate` (item 257), a rule-driven `[terrain_graphics]`-style transition pass
|
|
202
|
+
generalising `Autotile`'s fixed 47-shape blob table: arbitrary flag conditions at arbitrary
|
|
203
|
+
offsets, multi-image placement (so a piece bigger than one cell is one rule's own data, not
|
|
204
|
+
something `TileMap`'s one-sprite-per-cell grid has to hold), rotation and probability. Returns
|
|
205
|
+
plain placement data; drawing it through a renderer is still open.
|
|
206
|
+
- `markupToHtml` now renders colour and size as an inline style; `markupAccessibilityText` is a
|
|
207
|
+
proper accessibility projection for markup (an image becomes a caller-described string instead
|
|
208
|
+
of its raw path); `layoutMarkupLines` wraps already-parsed spans word by word, each word
|
|
209
|
+
measured under its own span's style, so a bold or larger run wraps where its own wider glyphs
|
|
210
|
+
actually land (item 258's remaining acceptance, in part - see ROADMAP for what is still open).
|
|
211
|
+
|
|
212
|
+
- `ParticleEmitter` spawn bounds (item 279): `ParticleSpawnArea` is an optional `spawn` on the
|
|
213
|
+
emitter's options, a `rect` or `ellipse` in local space so a burst spreads across an extent
|
|
214
|
+
instead of every particle starting at the emitter's single origin (a forge mouth, a flame
|
|
215
|
+
column, rain across a room). A point emitter draws nothing extra, so the seeded sequence an
|
|
216
|
+
existing replay recorded is unchanged.
|
|
217
|
+
- `roguelike.TargetingController` (item 280): the input-facing half of targeting, renderer-free.
|
|
218
|
+
A cursor moved by `move(dx, dy)` or a caller-resolved `moveTo(cell)`, range and line-of-sight
|
|
219
|
+
validation with an optional `validate` hook, a `preview()` of the shape's cells and a
|
|
220
|
+
`confirm()`/`cancel()` result carrying cells only, so damage, legality details and drawing stay
|
|
221
|
+
with the game. Hex levels step by their own six neighbours and measure in hex distance.
|
|
222
|
+
- `AudioListener`/`SoundSource`/`audioGain`/`audioPan`/`AudioFalloff` (item 271): positional
|
|
223
|
+
audio, renderer-free. A listener the game moves and turns, a `Sound` placed at a world point,
|
|
224
|
+
and the distance gain and stereo pan between them. `SoundSource.playFor(listener)` applies the
|
|
225
|
+
gain through `Sound.play`, which now takes an optional gain argument.
|
|
226
|
+
- `Input.onText`/`Input.onComposition`/`Input.textFromKey`/`Input.dispatchText`/
|
|
227
|
+
`Input.dispatchComposition` (item 262): the character a key press produces, and the three
|
|
228
|
+
phases of an input-method composition, so a free text field can be built. `onText` is a
|
|
229
|
+
stack-mode signal a focused field can consume.
|
|
230
|
+
- `MersenneTwister`/`MersenneTwisterState`/`RandomStreams` (item 266): MT19937 with the reference
|
|
231
|
+
`mt_rng`'s `seed`/`discard`/`discardCount` bookkeeping (verified against the standard test
|
|
232
|
+
vector) and named, independent streams derived from one base seed, so per-entity and per-usage
|
|
233
|
+
draws never shift each other. C++'s `uniform_int_distribution` is implementation-defined, so the
|
|
234
|
+
int mapping is MWG's own and documented as such.
|
|
235
|
+
- `i18n.parsePo`/`PoOptions` (item 270): a gettext `.po` loader into the same `Catalog` surface
|
|
236
|
+
as `parseFTL`, with `msgctxt`, `msgstr[N]` mapped onto the locale's CLDR categories,
|
|
237
|
+
untranslated entries left out for base fallback, and gettext `domain`-prefixed keys.
|
|
238
|
+
- `world.SideTurns`/`SideTurn`/`TimeOfDay`/`TimeArea`/`Alignment`/`alignmentBonus` (item 267): the
|
|
239
|
+
reference's outer turn model, sides in order with a schedule that steps per round, and a per-hex
|
|
240
|
+
`lawfulBonusAt` where a `TimeArea` overrides the global time of day.
|
|
241
|
+
- `ui.TabbedList`/`ListTab`/`TabbedListOptions` (item 281): a renderer-free model for a tabbed,
|
|
242
|
+
filtered, paged list with selection and a detail/close state, over caller-supplied rows and
|
|
243
|
+
predicates. The page is derived from the selection, so the two cannot disagree.
|
|
244
|
+
- `simulation.EventPresentation`/`EventPresentationOptions` (item 282): the documented recipe
|
|
245
|
+
tying a `SimulationRuntime` to a `PresentationQueue` - command result, animation lock,
|
|
246
|
+
scheduled secondary actor, cancellation, and save/load that resumes idle.
|
|
247
|
+
- `MwlWorld.sideStatus` and per-side `[victory]`/`[defeat]` under `[side]` (item 283): a side's
|
|
248
|
+
own condition is evaluated after the scenario-wide `[objectives]` ones, its result recorded by
|
|
249
|
+
side id, and `[win]`/`[lose]` record the side they name too. `MwlCommand`'s `win`/`lose` gained an
|
|
250
|
+
optional `side`.
|
|
251
|
+
- `simulation.CampaignSave`/`CampaignSaveState`/`CampaignSaveParts` (item 249): one `SaveSystem`
|
|
252
|
+
slot for a whole campaign, holding the campaign, world and simulation snapshots together, with
|
|
253
|
+
the world payload left opaque.
|
|
254
|
+
- `core.stateChecksum`/`core.SyncGuard` (item 272): a key-order-stable 32-bit checksum of JSON
|
|
255
|
+
state and a guard comparing the checksums peers compute per tick, so a lockstep run can notice
|
|
256
|
+
and locate a divergence.
|
|
257
|
+
- `ai.personalScoreView`/`ai.sideScoreView`/`ai.scoreWith`, over `ScoreSubject`/`ScoreView`/
|
|
258
|
+
`ScorePersonality` (items 274-276): the numbers a mind needs when a search is the wrong tool.
|
|
259
|
+
The game supplies what anything is worth, the framework assembles the view (own, allies and
|
|
260
|
+
enemies kept apart, with a `seen` count), and a personality is weights over the three, so a
|
|
261
|
+
selfish scout and a loyal one are content rather than two AI implementations. A unit's sight and a
|
|
262
|
+
whole side's read through the same two functions and differ only in the visibility set they are
|
|
263
|
+
handed, and `board.FactionFog.sees(side)` is that set as a predicate: it reads the shroud as it is
|
|
264
|
+
when called, not as it was when the predicate was made.
|
|
265
|
+
- `Animation`/`AnimatedSprite` frame timing (item 254): a frame is now a texture or
|
|
266
|
+
`{ texture, duration, offsetX, offsetY }`, so a frame carries its own time and its own place, as
|
|
267
|
+
Wesnoth's `image=a.png:120,b.png:80` does, and `AnimationOptions.startTime` is signed the way
|
|
268
|
+
Wesnoth writes it: positive holds the first frame, negative starts partway in (`start_time=-450`
|
|
269
|
+
over frames of 100ms opens on the fifth, which is how a swing is lined up with its damage frame).
|
|
270
|
+
`Animation.frameAt`/`frameIndexAt` are the rule, the sprite advances on its own elapsed time
|
|
271
|
+
rather than a leftover timer, and a frame's offset is reported through `AnimatedSprite.frameOffset`
|
|
272
|
+
for the caller to add where it already positions the sprite.
|
|
273
|
+
- `FactionFog.share(factions)` (item 268): factions put on one map, what is lit now and the shroud
|
|
274
|
+
they remember alike, which is what Wesnoth's `share_vision` means. Nothing shares until asked,
|
|
275
|
+
growing a group widens it rather than replacing it, and a share declared after a `sync` still
|
|
276
|
+
counts because the group is read when a cell is asked about. `sees(side)` follows it, so a side's
|
|
277
|
+
score view reads the team's eyes.
|
|
278
|
+
- `campaignChain` (item 247): a `[campaign]` pointed at `simulation.Campaign`. `first_scenario` opens
|
|
279
|
+
it, each `[scenario]`'s `next_scenario` is where it goes when it is won, and the chain ends where a
|
|
280
|
+
scenario has no next one. The order is content and the playing stays the game's, since the runner
|
|
281
|
+
is a callback; a scenario that decides for itself keeps its decision, which is where a runtime
|
|
282
|
+
`[endlevel]` will hook in. Malformed chains (no scenarios, one id twice, an unknown
|
|
283
|
+
`first_scenario`) throw by name. The `[campaign]` schema now accepts `first_scenario`, and
|
|
284
|
+
`contentCatalog` exposes each campaign's scenario links.
|
|
285
|
+
- `[endlevel]` and carry-over (item 248): a scenario ends with `result=victory|defeat`, and what it
|
|
286
|
+
hands on is `endLevelCarryover` - `bonus` plus a share of the side's gold (`carryover_percentage`,
|
|
287
|
+
80% when unset, which is the reference's own default rather than an invented one), the units of
|
|
288
|
+
that side still standing as the recall list, and `next_scenario` for where the campaign goes (the
|
|
289
|
+
hook `campaignChain` already honours). `carryoverIntoScenario` is the other half of the rule: the
|
|
290
|
+
carried share is added to what the next scenario declares when `carryover_add` asks for it, and is
|
|
291
|
+
otherwise a floor under it. `MWL_DEFAULT_CARRYOVER_PERCENTAGE` names the default.
|
|
292
|
+
- `[kill]` as a filter (item 251): naming a unit that is not there still throws, while a `[kill]`
|
|
293
|
+
whose attributes are a filter over the world's units is a no-op when it matches nobody, as WML's
|
|
294
|
+
own `[kill]` is. It reads the same attributes an event filter does, an empty filter matches every
|
|
295
|
+
unit (there as here), and the schema entry is open on attributes so a filter can say what it
|
|
296
|
+
means.
|
|
297
|
+
- A scenario turn limit, as a native condition (item 253): `[game] turn_limit=N` makes the runtime
|
|
298
|
+
set `time_over` as a world variable and fire the `time_over` event once the turn counter passes N.
|
|
299
|
+
Content tests it like any variable and answers it like any event, `[endlevel]` included, because a
|
|
300
|
+
limit is usually a defeat and sometimes the whole scenario.
|
|
301
|
+
- An inline-markup contract, first half of item 258: `MarkupSpan` plus `parseMarkup`/`stripMarkup`/
|
|
302
|
+
`markupToHtml`/`escapeHtml` in `src/two-d/ui/markup.ts`. Nested emphasis, named and hex colours, a
|
|
303
|
+
size, a line break, an image span carrying a path, `$name` interpolation supplied by the caller,
|
|
304
|
+
and the five entities as escapes. Unknown or malformed tags and unset variables stay literal
|
|
305
|
+
rather than vanishing, and output text is escaped so no raw HTML can leak. What the item's
|
|
306
|
+
acceptance still wants (backend equivalence, wrapping after styling, images through the asset
|
|
307
|
+
resolver, an accessibility projection) is recorded on the item rather than implied here.
|
|
308
|
+
- The `[side]` surface, and one key of it with behaviour (item 252): the Wesnoth keys `team_name`,
|
|
309
|
+
`user_team_name`, `share_vision`, `village_gold`, `heal`, `fog`, `shroud`, `hidden` and `flag` are
|
|
310
|
+
read onto `MwlWorld.sides` as written (`yes`/`no` as booleans), and `sideVisionGroups` turns
|
|
311
|
+
`team_name` with `share_vision` into the groups `FactionFog.share` takes.
|
|
312
|
+
- Hex projection options, first half of item 259: `hexToPixel`/`pixelToHex` take
|
|
313
|
+
`HexShape`/`HexOrientation`/`HexOffset`, so a grid can be flat-top or pointy-top with either
|
|
314
|
+
offset parity, and the default is the flat-top odd-q layout the module always had. The inverse is
|
|
315
|
+
the nearest cell centre, which cannot disagree with the projection at a hex's edge.
|
|
316
|
+
- `Halo` (item 260): the glow around a unit, an aura, a shrine's light. An `AnimatedSprite` that
|
|
317
|
+
`follow(x, y)`s a target with its own offset applied once, additive by default, with z-order left
|
|
318
|
+
to the caller. `[halo_frame]` needed nothing new after 254 gave frames their own timing.
|
|
319
|
+
|
|
320
|
+
### Fixed
|
|
321
|
+
|
|
322
|
+
- `FloatingTextStack` stacked the wrong way round: it moved the **newcomer** down by
|
|
323
|
+
`height + 1`, where Java's `FloatingText.push()` anchors the newcomer on the target and lifts
|
|
324
|
+
the lines already there to `below.top - height - 4`. A second pop-up on one target in one turn
|
|
325
|
+
therefore landed *below* the target instead of above the first - found by a consumer measuring
|
|
326
|
+
it, not by the tests, which asserted the offset's magnitude and never its direction.
|
|
327
|
+
`floatingTextStackOffset` is replaced by `floatingTextStackLift` (the position the older line
|
|
328
|
+
must take, rather than an offset the caller adds, so the sign cannot be got wrong quietly) and
|
|
329
|
+
by `floatingTextStackMoves`, the whole policy: which lines move, newest first, where each one
|
|
330
|
+
ends up, and what age each is forced to. The loop is arithmetic now, so it is checked as
|
|
331
|
+
arithmetic rather than through a rendered label. `FLOATING_TEXT_STACK_GAP` names Java's 4px gap.
|
|
332
|
+
- The lift survived exactly one frame. `FloatingText.update` wrote its own `y` from a base captured
|
|
333
|
+
on the first frame, so a line the stack had just moved snapped back on the next one: measured, a
|
|
334
|
+
line lifted to 166.6 was back at 194.4 beside the newcomer at 200, still overlapping it. The rise
|
|
335
|
+
now moves the pop-up's inner layer and never its position, which belongs to the caller and to the
|
|
336
|
+
stack; `baseY` is gone. A consumer repositioning a pop-up mid-flight no longer loses the position
|
|
337
|
+
on the next frame either.
|
|
338
|
+
- A pop-up scaled *after* `push` was measured before the scale, because a `FloatingText`'s `height`
|
|
339
|
+
includes its own scale. A port rasterising at 21px and drawing at 7 therefore spaced lifted lines
|
|
340
|
+
33.4 world pixels apart for lines 9.8 tall. `push` now takes a `scale`, applied before the pop-up
|
|
341
|
+
is measured, so the entry records the size the line is actually drawn at.
|
|
342
|
+
|
|
343
|
+
### Changed
|
|
344
|
+
|
|
345
|
+
- `FloatingText.shortenLife(seconds)` becomes `FloatingText.ageAtLeast(seconds)`, which does what
|
|
346
|
+
Java's rule says rather than something close: `above.timeLeft = Math.min(above.timeLeft,
|
|
347
|
+
LIFESPAN - numBelow / 5f)` caps what is *left*, and a cap on what is left is a floor under the
|
|
348
|
+
age. A line that has already lived past the floor keeps the age it has, where subtracting the
|
|
349
|
+
floor shortened it a second time. `floatingTextAgeAtLeast` is that arithmetic as a pure function,
|
|
350
|
+
so the difference is checked by a test; `floatingTextStackLifePenalty(linesBelow)` stays the
|
|
351
|
+
floor itself, a fifth of a second per line below.
|
|
352
|
+
- A stack keys on `key` alone, as Java's `stacks.get(key)` does. The old rule wanted the same key
|
|
353
|
+
*and* the same origin, which this framework had invented. A caller that reused one key for two
|
|
354
|
+
different targets now sees their lines stacked together, and has to give each target its own key.
|
|
355
|
+
- One side identity in `MwlWorld` (item 277): `unit.side`, `MwlMessage.side`, `MwlMap.starts` keys
|
|
356
|
+
and every `side`/`side_filter` attribute now hold the string `id` `[side]` declares, so a named
|
|
357
|
+
side (`id=rebels`) works throughout. `MwlSideRef` is just that id. The `[side] id` and the other
|
|
358
|
+
side-identifying schema attributes accept a string (numbers still validate), and the map
|
|
359
|
+
`<side> <code>` keep marker accepts a name.
|
|
360
|
+
|
|
361
|
+
### Fixed
|
|
362
|
+
|
|
363
|
+
- `ui.Window` (item 290): `closed` is now a getter to guard a caller's reference after `close()`,
|
|
364
|
+
`close()` is idempotent, input and layout on a closed window are no-ops rather than throws on
|
|
365
|
+
freed Pixi internals, and `WindowStack.push` refuses a closed window with a named error.
|
|
366
|
+
|
|
8
367
|
## [0.7.6] - 2026-09-11
|
|
9
368
|
|
|
10
369
|
### Added
|
package/README.md
CHANGED
|
@@ -12,12 +12,12 @@ of their own; improvements to `mwg`'s own files are shared back.
|
|
|
12
12
|
playable in the browser with no download, plus the generated API reference.
|
|
13
13
|
|
|
14
14
|
**[AI project prompt](https://datamoc.github.io/mwg/ai-prompt/)**: a copy-ready prompt for
|
|
15
|
-
planning or porting a demanding game with mwg, with links to the [mwg reference](REFERENCE.md)
|
|
15
|
+
planning or porting a demanding game with mwg, with links to the [mwg reference](https://github.com/datamoc/mwg/blob/main/REFERENCE.md)
|
|
16
16
|
and the [mwg Pixel Dungeon study](https://datamoc.github.io/mwg-pixel-dungeon/).
|
|
17
17
|
|
|
18
|
-
> **Status: pre-alpha (v0.7.
|
|
18
|
+
> **Status: pre-alpha (v0.7.7).** Every module in the shared floor below, plus optional
|
|
19
19
|
> 3D, mobile (Capacitor) and desktop (WebView2) packaging, is built and tested - see
|
|
20
|
-
> [ROADMAP.md](ROADMAP.md) for the full, numbered history.
|
|
20
|
+
> [ROADMAP.md](https://github.com/datamoc/mwg/blob/main/ROADMAP.md) for the full, numbered history.
|
|
21
21
|
>
|
|
22
22
|
> 0.4.0 was the reshaping release: the renderer moved out of `mwg/core`, `render`/`ui`/`stage`
|
|
23
23
|
> became `mwg/two-d`, and a set of names that meant several things each were made to mean one.
|
|
@@ -29,8 +29,8 @@ and the [mwg Pixel Dungeon study](https://datamoc.github.io/mwg-pixel-dungeon/).
|
|
|
29
29
|
> a name beginning with A, 2.0 one beginning with B, and so on. None of the names are chosen
|
|
30
30
|
> yet, and nothing depends on them until they are.
|
|
31
31
|
>
|
|
32
|
-
> **API stability:** everything documented in [REFERENCE.md](REFERENCE.md) and
|
|
33
|
-
> [API_REPORT.md](API_REPORT.md) is meant to be stable from 1.0 on. Anything that is not carries
|
|
32
|
+
> **API stability:** everything documented in [REFERENCE.md](https://github.com/datamoc/mwg/blob/main/REFERENCE.md) and
|
|
33
|
+
> [API_REPORT.md](https://github.com/datamoc/mwg/blob/main/API_REPORT.md) is meant to be stable from 1.0 on. Anything that is not carries
|
|
34
34
|
> an `@experimental` tag in its own doc comment, and is called out as experimental in the release
|
|
35
35
|
> notes that introduce it, so it can still change or disappear without a major version. A rename
|
|
36
36
|
> or a removal is deprecated first: the old name keeps working, its doc comment carries
|
|
@@ -143,7 +143,7 @@ them rather than pretending otherwise:
|
|
|
143
143
|
The practical effect: resources are **compiled at build time**, so at runtime every lookup
|
|
144
144
|
is synchronous. Game code never awaits an asset. The developer-side scripts behind this
|
|
145
145
|
and the other workflows (translation editing, benchmarks, packaging) are listed in
|
|
146
|
-
[tools.md](tools.md).
|
|
146
|
+
[tools.md](https://github.com/datamoc/mwg/blob/main/tools.md).
|
|
147
147
|
|
|
148
148
|
## Capability spec
|
|
149
149
|
|
|
@@ -387,7 +387,7 @@ with `advanceToInput`.
|
|
|
387
387
|
|
|
388
388
|
## Roadmap
|
|
389
389
|
|
|
390
|
-
See [ROADMAP.md](ROADMAP.md) for the full, numbered build order and implementation notes.
|
|
390
|
+
See [ROADMAP.md](https://github.com/datamoc/mwg/blob/main/ROADMAP.md) for the full, numbered build order and implementation notes.
|
|
391
391
|
The optional 3D group is now implemented without changing the existing 2D entry point.
|
|
392
392
|
|
|
393
393
|
## MWL
|
|
@@ -24,6 +24,12 @@ export interface InventoryItem {
|
|
|
24
24
|
quantity: number;
|
|
25
25
|
stackable?: boolean;
|
|
26
26
|
weight?: number;
|
|
27
|
+
/**
|
|
28
|
+
* A kind-level grouping - `'herb'`, `'runestone'`, `'potion'` - so a recipe can ask for "any
|
|
29
|
+
* herb" rather than one exact id. Like `stackable` and `weight` it describes the item's kind,
|
|
30
|
+
* so it comes from the game's item definitions on load and is not part of a save.
|
|
31
|
+
*/
|
|
32
|
+
category?: string;
|
|
27
33
|
/**
|
|
28
34
|
* Distinguishes otherwise-identical instances of the same item id - two `"sword"`s, one
|
|
29
35
|
* enchanted and one not, or two enchanted differently - so they never silently merge into
|
|
@@ -95,7 +101,7 @@ export declare class Inventory {
|
|
|
95
101
|
static fromJSON(defs: ReadonlyMap<string, ItemDefinition>, data: SavedInventory): Inventory;
|
|
96
102
|
}
|
|
97
103
|
/** the kind-level fields a game's own item table supplies, rather than the save file */
|
|
98
|
-
export type ItemDefinition = Pick<InventoryItem, 'stackable' | 'weight'>;
|
|
104
|
+
export type ItemDefinition = Pick<InventoryItem, 'stackable' | 'weight' | 'category'>;
|
|
99
105
|
/** one slot as saved: instance state only, no kind-level fields */
|
|
100
106
|
export interface SavedInventoryItem {
|
|
101
107
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Inventory.d.ts","sourceRoot":"","sources":["../../src/actors/Inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,aAAa;IAC7B,mGAAmG;IACnG,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAS;IACrB,OAAO,CAAC,KAAK,CAAuB;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,YAAY,OAAO,GAAE,gBAAqB,EAEzC;IAED,IAAI,KAAK,IAAI,SAAS,aAAa,EAAE,CAEpC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,OAAO,CAAC,QAAQ;IAIhB,8FAA8F;IAC9F,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAI/D;IAED;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAmBhC;IAED,0FAA0F;IAC1F,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAU/D;IAED;;;OAGG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAI,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAc7E;IAED;;;;;;;;;;;OAWG;IACH,MAAM,IAAI,cAAc,CAiBvB;IAED;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,SAAS,CAsB1F;CACD;AAED,wFAAwF;AACxF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"Inventory.d.ts","sourceRoot":"","sources":["../../src/actors/Inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,aAAa;IAC7B,mGAAmG;IACnG,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAS;IACrB,OAAO,CAAC,KAAK,CAAuB;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,YAAY,OAAO,GAAE,gBAAqB,EAEzC;IAED,IAAI,KAAK,IAAI,SAAS,aAAa,EAAE,CAEpC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,OAAO,CAAC,QAAQ;IAIhB,8FAA8F;IAC9F,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAI/D;IAED;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAmBhC;IAED,0FAA0F;IAC1F,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAU/D;IAED;;;OAGG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAI,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAc7E;IAED;;;;;;;;;;;OAWG;IACH,MAAM,IAAI,cAAc,CAiBvB;IAED;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,SAAS,CAsB1F;CACD;AAED,wFAAwF;AACxF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC;AAEtF,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Inventory.js","sourceRoot":"","sources":["../../src/actors/Inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"Inventory.js","sourceRoot":"","sources":["../../src/actors/Inventory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Shop.d.ts","sourceRoot":"","sources":["../../src/actors/Shop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,KAAK;IACrB,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC3B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CACnC;AAED,kGAAkG;AAClG,wBAAgB,GAAG,CAClB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GAClB,OAAO,CAkBT;AAED,iGAAiG;AACjG,wBAAgB,IAAI,CACnB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GAClB,OAAO,
|
|
1
|
+
{"version":3,"file":"Shop.d.ts","sourceRoot":"","sources":["../../src/actors/Shop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,KAAK;IACrB,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC3B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CACnC;AAED,kGAAkG;AAClG,wBAAgB,GAAG,CAClB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GAClB,OAAO,CAkBT;AAED,iGAAiG;AACjG,wBAAgB,IAAI,CACnB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GAClB,OAAO,CAcT"}
|
package/dist/actors/Shop.js
CHANGED
|
@@ -26,7 +26,10 @@ export function sell(wallet, stock, bag, id, quantity, options) {
|
|
|
26
26
|
if (!item || item.quantity < quantity)
|
|
27
27
|
return false;
|
|
28
28
|
bag.remove(id, quantity);
|
|
29
|
-
stock.add({ ...item, quantity })
|
|
29
|
+
if (!stock.add({ ...item, quantity })) {
|
|
30
|
+
bag.add({ ...item, quantity }); //the shop's stock had no room - put the item back
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
30
33
|
wallet.setBase(options.currency, wallet.base(options.currency) + price.sell * quantity);
|
|
31
34
|
return true;
|
|
32
35
|
}
|
package/dist/actors/Shop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Shop.js","sourceRoot":"","sources":["../../src/actors/Shop.ts"],"names":[],"mappings":"AAsCA,kGAAkG;AAClG,MAAM,UAAU,GAAG,CAClB,MAAiB,EACjB,KAAgB,EAChB,GAAc,EACd,EAAU,EACV,QAAgB,EAChB,OAAoB;IAEpB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE1D,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC;IAClC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;QAAE,OAAO,KAAK,CAAC;IAEvD,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACxC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,kDAAkD;QACvF,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IACvE,OAAO,IAAI,CAAC;AACb,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,IAAI,CACnB,MAAiB,EACjB,KAAgB,EAChB,GAAc,EACd,EAAU,EACV,QAAgB,EAChB,OAAoB;IAEpB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEpD,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACzB,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"Shop.js","sourceRoot":"","sources":["../../src/actors/Shop.ts"],"names":[],"mappings":"AAsCA,kGAAkG;AAClG,MAAM,UAAU,GAAG,CAClB,MAAiB,EACjB,KAAgB,EAChB,GAAc,EACd,EAAU,EACV,QAAgB,EAChB,OAAoB;IAEpB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE1D,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC;IAClC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;QAAE,OAAO,KAAK,CAAC;IAEvD,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACxC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,kDAAkD;QACvF,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IACvE,OAAO,IAAI,CAAC;AACb,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,IAAI,CACnB,MAAiB,EACjB,KAAgB,EAChB,GAAc,EACd,EAAU,EACV,QAAgB,EAChB,OAAoB;IAEpB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEpD,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,kDAAkD;QAClF,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC;IACxF,OAAO,IAAI,CAAC;AACb,CAAC"}
|
package/dist/actors/craft.d.ts
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import type { Inventory, InventoryItem } from './Inventory.ts';
|
|
2
|
+
/**
|
|
3
|
+
* What one recipe ingredient consumes. `id` is the simple case: one exact item, or any of
|
|
4
|
+
* several. `category` asks for any item of a kind ("any herb plus any runestone"), matching the
|
|
5
|
+
* `category` an item's definition carries. `matches` is the escape hatch when neither fits.
|
|
6
|
+
* Give exactly one of the three.
|
|
7
|
+
*/
|
|
8
|
+
export interface Ingredient {
|
|
9
|
+
/** one exact item id, or any of several */
|
|
10
|
+
readonly id?: string | readonly string[];
|
|
11
|
+
/** any item whose `category` is this */
|
|
12
|
+
readonly category?: string;
|
|
13
|
+
/** full control: an item this returns true for */
|
|
14
|
+
readonly matches?: (item: InventoryItem) => boolean;
|
|
15
|
+
/** how many items matching this the recipe needs */
|
|
16
|
+
readonly quantity: number;
|
|
17
|
+
}
|
|
2
18
|
export interface Recipe {
|
|
3
|
-
/** what gets consumed, by id
|
|
4
|
-
ingredients:
|
|
5
|
-
id: string;
|
|
6
|
-
quantity: number;
|
|
7
|
-
}>;
|
|
19
|
+
/** what gets consumed, by exact id, by category, or by predicate */
|
|
20
|
+
ingredients: Ingredient[];
|
|
8
21
|
/** what one crafting resolves to - a full item, since it needs its own weight/stackable */
|
|
9
22
|
result: InventoryItem;
|
|
10
23
|
}
|
|
@@ -15,10 +28,15 @@ export interface Recipe {
|
|
|
15
28
|
* adds/removes what a game already hands it; nothing there turns one stack of items into a
|
|
16
29
|
* different one, which is the entire gap this closes.
|
|
17
30
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
31
|
+
* An ingredient may name an exact `id` (or any of several), a `category` ("any herb", matched
|
|
32
|
+
* against the item definition's own `category`), or a `matches` predicate, and a quantity is
|
|
33
|
+
* taken from as many matching stacks as it spans.
|
|
34
|
+
*
|
|
35
|
+
* All or nothing: if any ingredient is missing or too few, nothing is touched. The allocation
|
|
36
|
+
* runs against a working copy of the stacks first, so two ingredients that could both take the
|
|
37
|
+
* same stack cannot each count it. If every ingredient is present but the result would not fit
|
|
38
|
+
* (`Inventory`'s own capacity, unrelated to crafting itself), the ingredients are put back
|
|
39
|
+
* exactly as they were rather than being spent for nothing.
|
|
22
40
|
*
|
|
23
41
|
* @returns whether the recipe resolved
|
|
24
42
|
*
|
|
@@ -27,15 +45,18 @@ export interface Recipe {
|
|
|
27
45
|
* import { craft, Inventory, type Recipe } from '@datamoc/mw_games/actors';
|
|
28
46
|
*
|
|
29
47
|
* const bag = new Inventory();
|
|
30
|
-
* bag.add({ id: '
|
|
31
|
-
* bag.add({ id: '
|
|
48
|
+
* bag.add({ id: 'sage', quantity: 2, stackable: true, category: 'herb' });
|
|
49
|
+
* bag.add({ id: 'ember', quantity: 1, stackable: true, category: 'runestone' });
|
|
32
50
|
*
|
|
33
51
|
* const recipe: Recipe = {
|
|
34
|
-
* ingredients: [
|
|
35
|
-
*
|
|
52
|
+
* ingredients: [
|
|
53
|
+
* { category: 'herb', quantity: 2 },
|
|
54
|
+
* { category: 'runestone', quantity: 1 },
|
|
55
|
+
* ],
|
|
56
|
+
* result: { id: 'elixir', quantity: 1 },
|
|
36
57
|
* };
|
|
37
58
|
*
|
|
38
|
-
* const made = craft(bag, recipe); // true -
|
|
59
|
+
* const made = craft(bag, recipe); // true - any herb plus any runestone becomes an elixir
|
|
39
60
|
* ```
|
|
40
61
|
*/
|
|
41
62
|
export declare function craft(inventory: Inventory, recipe: Recipe): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"craft.d.ts","sourceRoot":"","sources":["../../src/actors/craft.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/D,MAAM,WAAW,MAAM;
|
|
1
|
+
{"version":3,"file":"craft.d.ts","sourceRoot":"","sources":["../../src/actors/craft.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACzC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;IAEpD,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,MAAM;IACtB,oEAAoE;IACpE,WAAW,EAAE,UAAU,EAAE,CAAC;IAE1B,2FAA2F;IAC3F,MAAM,EAAE,aAAa,CAAC;CACtB;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CA+BnE"}
|