@v12-engine/create 0.1.1 → 0.4.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.
Files changed (263) hide show
  1. package/README.md +4 -1
  2. package/base/_gitignore +5 -0
  3. package/base/package.json +3 -3
  4. package/base/src/main.ts +36 -10
  5. package/base/src/navigation.worker.ts +7 -0
  6. package/base/vite.config.ts +24 -2
  7. package/cli.mjs +21 -6
  8. package/index.mjs +27 -7
  9. package/layers/desktop/electron/app.mjs +237 -0
  10. package/layers/desktop/electron/config.mjs +16 -0
  11. package/layers/desktop/electron/dev.mjs +63 -0
  12. package/layers/desktop/electron/files.mjs +86 -0
  13. package/layers/desktop/electron/icons/icon.icns +0 -0
  14. package/layers/desktop/electron/icons/icon.png +0 -0
  15. package/layers/desktop/electron/main.mjs +12 -0
  16. package/layers/desktop/electron/package.mjs +75 -0
  17. package/layers/desktop/electron/preload.cjs +41 -0
  18. package/layers/desktop/electron/presentation.m +87 -0
  19. package/layers/desktop/electron/serve.mjs +76 -0
  20. package/layers/desktop/electron/tools.mjs +63 -0
  21. package/layers/desktop/electron/updates.mjs +71 -0
  22. package/layers/desktop/package.json +13 -0
  23. package/layers/desktop/src/desktop.ts +175 -0
  24. package/layers/desktop/src/shell.ts +279 -0
  25. package/layers/desktop/tests/main.test.ts +189 -0
  26. package/layers/desktop/tests/shell.test.ts +152 -0
  27. package/layers/rooms/server.ts +13 -10
  28. package/layers/server/server.ts +4 -5
  29. package/layers/source/vite.config.ts +21 -1
  30. package/package.json +1 -1
  31. package/starters/campaign/README.md +9 -2
  32. package/starters/campaign/layers/rooms/server.ts +3 -3
  33. package/starters/campaign/layers/server/server.ts +3 -5
  34. package/starters/campaign/layers/tests/tests/rules.test.ts +40 -21
  35. package/starters/campaign/src/campaign/game.ts +26 -5
  36. package/starters/campaign/src/campaign/index.ts +104 -68
  37. package/starters/campaign/src/campaign/kills.ts +1 -1
  38. package/starters/campaign/src/campaign/missions/homecoming.ts +7 -7
  39. package/starters/campaign/src/campaign/missions/siege.ts +6 -6
  40. package/starters/campaign/src/campaign/missions/warlord.ts +13 -14
  41. package/starters/campaign/src/campaign/scenes.ts +8 -7
  42. package/starters/campaign/src/campaign/units.ts +59 -20
  43. package/starters/campaign/src/campaign/view/attacks.ts +19 -0
  44. package/starters/campaign/src/campaign/view/fire.ts +2 -2
  45. package/starters/campaign/src/campaign/view/index.ts +54 -43
  46. package/starters/campaign/src/campaign/waves.ts +18 -17
  47. package/starters/campaign/src/game.ts +8 -1
  48. package/starters/campaign/src/main.ts +38 -19
  49. package/starters/campaign/src/maps/fort.names.ts +2 -2
  50. package/starters/campaign/src/maps/fort.vgmap.json +102 -2
  51. package/starters/campaign/src/maps/homestead.names.ts +2 -2
  52. package/starters/campaign/src/maps/homestead.vgmap.json +85 -1
  53. package/starters/campaign/src/maps/pass.names.ts +2 -2
  54. package/starters/campaign/src/maps/pass.vgmap.json +69 -1
  55. package/starters/campaign/src/waves-panel.ts +2 -1
  56. package/starters/empty/README.md +18 -10
  57. package/starters/empty/layers/tests/tests/rules.test.ts +16 -17
  58. package/starters/empty/src/game.ts +11 -75
  59. package/starters/empty/src/generate.worker.ts +5 -5
  60. package/starters/empty/src/rules.ts +83 -25
  61. package/starters/empty/src/view.ts +82 -0
  62. package/starters/examples/README.md +83 -0
  63. package/starters/examples/layers/tests/tests/examples.test.ts +30 -0
  64. package/starters/examples/package.json +5 -0
  65. package/starters/examples/src/examples/abilities/areas.ts +165 -0
  66. package/starters/examples/src/examples/abilities/areasLooks.ts +30 -0
  67. package/starters/examples/src/examples/abilities/buffs.ts +287 -0
  68. package/starters/examples/src/examples/abilities/buffsLooks.ts +46 -0
  69. package/starters/examples/src/examples/abilities/changing.ts +228 -0
  70. package/starters/examples/src/examples/abilities/changingLooks.ts +61 -0
  71. package/starters/examples/src/examples/abilities/control.ts +158 -0
  72. package/starters/examples/src/examples/abilities/controlLooks.ts +78 -0
  73. package/starters/examples/src/examples/abilities/damage.ts +156 -0
  74. package/starters/examples/src/examples/abilities/damageLooks.ts +37 -0
  75. package/starters/examples/src/examples/abilities/family.ts +29 -0
  76. package/starters/examples/src/examples/abilities/index.ts +32 -0
  77. package/starters/examples/src/examples/abilities/kit.ts +179 -0
  78. package/starters/examples/src/examples/abilities/lookKit.ts +71 -0
  79. package/starters/examples/src/examples/abilities/looks.ts +47 -0
  80. package/starters/examples/src/examples/abilities/missiles.ts +203 -0
  81. package/starters/examples/src/examples/abilities/missilesLooks.ts +38 -0
  82. package/starters/examples/src/examples/abilities/moves.ts +206 -0
  83. package/starters/examples/src/examples/abilities/movesLooks.ts +52 -0
  84. package/starters/examples/src/examples/abilities/recasts.ts +181 -0
  85. package/starters/examples/src/examples/abilities/recastsLooks.ts +41 -0
  86. package/starters/examples/src/examples/abilities/resources.ts +166 -0
  87. package/starters/examples/src/examples/abilities/resourcesLooks.ts +42 -0
  88. package/starters/examples/src/examples/abilities/summons.ts +296 -0
  89. package/starters/examples/src/examples/abilities/summonsLooks.ts +115 -0
  90. package/starters/examples/src/examples/abilities/triggers.ts +204 -0
  91. package/starters/examples/src/examples/abilities/triggersLooks.ts +53 -0
  92. package/starters/examples/src/examples/abilities/vision.ts +137 -0
  93. package/starters/examples/src/examples/abilities/visionLooks.ts +50 -0
  94. package/starters/examples/src/examples/animation/index.ts +235 -0
  95. package/starters/examples/src/examples/animation/looks.ts +444 -0
  96. package/starters/examples/src/examples/catalog.ts +52 -0
  97. package/starters/examples/src/examples/cinematics/index.ts +217 -0
  98. package/starters/examples/src/examples/cinematics/looks.ts +476 -0
  99. package/starters/examples/src/examples/cinematics/tour.json +43 -0
  100. package/starters/examples/src/examples/cinematics/village.ts +88 -0
  101. package/starters/examples/src/examples/common/looks.ts +65 -0
  102. package/starters/examples/src/examples/common/units.ts +70 -0
  103. package/starters/examples/src/examples/construction/index.ts +329 -0
  104. package/starters/examples/src/examples/construction/looks.ts +275 -0
  105. package/starters/examples/src/examples/custom-animation/bones.ts +92 -0
  106. package/starters/examples/src/examples/custom-animation/index.ts +190 -0
  107. package/starters/examples/src/examples/custom-animation/looks.ts +523 -0
  108. package/starters/examples/src/examples/custom-animation/runes.ts +82 -0
  109. package/starters/examples/src/examples/custom-fx/glaive.look.ts +110 -0
  110. package/starters/examples/src/examples/custom-fx/glaive.ts +40 -0
  111. package/starters/examples/src/examples/custom-fx/gpu.look.ts +145 -0
  112. package/starters/examples/src/examples/custom-fx/gpu.ts +22 -0
  113. package/starters/examples/src/examples/custom-fx/index.ts +25 -0
  114. package/starters/examples/src/examples/custom-fx/lights.look.ts +144 -0
  115. package/starters/examples/src/examples/custom-fx/lights.ts +25 -0
  116. package/starters/examples/src/examples/custom-fx/looks.ts +36 -0
  117. package/starters/examples/src/examples/custom-fx/meteor.look.ts +133 -0
  118. package/starters/examples/src/examples/custom-fx/meteor.ts +26 -0
  119. package/starters/examples/src/examples/custom-fx/parts.look.ts +193 -0
  120. package/starters/examples/src/examples/custom-fx/parts.ts +21 -0
  121. package/starters/examples/src/examples/custom-fx/portal.look.ts +193 -0
  122. package/starters/examples/src/examples/custom-fx/portal.ts +48 -0
  123. package/starters/examples/src/examples/custom-fx/renderer.look.ts +139 -0
  124. package/starters/examples/src/examples/custom-fx/renderer.ts +18 -0
  125. package/starters/examples/src/examples/custom-fx/ribbons.look.ts +151 -0
  126. package/starters/examples/src/examples/custom-fx/ribbons.ts +22 -0
  127. package/starters/examples/src/examples/custom-fx/shader.ts +42 -0
  128. package/starters/examples/src/examples/custom-fx/shield.look.ts +226 -0
  129. package/starters/examples/src/examples/custom-fx/shield.ts +43 -0
  130. package/starters/examples/src/examples/define.ts +86 -0
  131. package/starters/examples/src/examples/destruction/index.ts +570 -0
  132. package/starters/examples/src/examples/destruction/looks.ts +447 -0
  133. package/starters/examples/src/examples/dialogs/index.ts +383 -0
  134. package/starters/examples/src/examples/dialogs/looks.ts +546 -0
  135. package/starters/examples/src/examples/dynamic-map/index.ts +603 -0
  136. package/starters/examples/src/examples/dynamic-map/looks.ts +301 -0
  137. package/starters/examples/src/examples/fx/blood.look.ts +62 -0
  138. package/starters/examples/src/examples/fx/blood.ts +59 -0
  139. package/starters/examples/src/examples/fx/feel.look.ts +86 -0
  140. package/starters/examples/src/examples/fx/feel.ts +57 -0
  141. package/starters/examples/src/examples/fx/fight.ts +28 -0
  142. package/starters/examples/src/examples/fx/floats.look.ts +108 -0
  143. package/starters/examples/src/examples/fx/floats.ts +24 -0
  144. package/starters/examples/src/examples/fx/gallery.look.ts +168 -0
  145. package/starters/examples/src/examples/fx/gallery.ts +23 -0
  146. package/starters/examples/src/examples/fx/index.ts +30 -0
  147. package/starters/examples/src/examples/fx/links.look.ts +83 -0
  148. package/starters/examples/src/examples/fx/links.ts +49 -0
  149. package/starters/examples/src/examples/fx/looks.ts +55 -0
  150. package/starters/examples/src/examples/fx/map.look.ts +93 -0
  151. package/starters/examples/src/examples/fx/map.ts +33 -0
  152. package/starters/examples/src/examples/fx/marks.look.ts +100 -0
  153. package/starters/examples/src/examples/fx/marks.ts +36 -0
  154. package/starters/examples/src/examples/fx/shots.look.ts +92 -0
  155. package/starters/examples/src/examples/fx/shots.ts +71 -0
  156. package/starters/examples/src/examples/fx/spells.look.ts +87 -0
  157. package/starters/examples/src/examples/fx/spells.ts +122 -0
  158. package/starters/examples/src/examples/fx/stage.ts +31 -0
  159. package/starters/examples/src/examples/gui/babylonScreen.ts +167 -0
  160. package/starters/examples/src/examples/gui/babylonWorld.ts +191 -0
  161. package/starters/examples/src/examples/gui/htmlPart.ts +95 -0
  162. package/starters/examples/src/examples/gui/index.ts +143 -0
  163. package/starters/examples/src/examples/gui/keys.ts +91 -0
  164. package/starters/examples/src/examples/gui/layout.ts +42 -0
  165. package/starters/examples/src/examples/gui/looks.ts +270 -0
  166. package/starters/examples/src/examples/gui/minimap.ts +127 -0
  167. package/starters/examples/src/examples/gui/ownInterface.ts +129 -0
  168. package/starters/examples/src/examples/gui/plates.ts +87 -0
  169. package/starters/examples/src/examples/gui/radial.ts +104 -0
  170. package/starters/examples/src/examples/gui/solidPart.ts +107 -0
  171. package/starters/examples/src/examples/looks.ts +45 -0
  172. package/starters/examples/src/examples/mechanics/battle.ts +51 -0
  173. package/starters/examples/src/examples/mechanics/damage.ts +80 -0
  174. package/starters/examples/src/examples/mechanics/flying.ts +93 -0
  175. package/starters/examples/src/examples/mechanics/formations.ts +58 -0
  176. package/starters/examples/src/examples/mechanics/highGround.ts +82 -0
  177. package/starters/examples/src/examples/mechanics/index.ts +44 -0
  178. package/starters/examples/src/examples/mechanics/looks.ts +289 -0
  179. package/starters/examples/src/examples/mechanics/maze.ts +119 -0
  180. package/starters/examples/src/examples/mechanics/orders.ts +68 -0
  181. package/starters/examples/src/examples/mechanics/selection.ts +30 -0
  182. package/starters/examples/src/examples/moba/index.ts +377 -0
  183. package/starters/examples/src/examples/moba/looks.ts +349 -0
  184. package/starters/examples/src/examples/moba/maps.ts +69 -0
  185. package/starters/examples/src/examples/moba/spells.ts +34 -0
  186. package/starters/examples/src/examples/moba/units.ts +196 -0
  187. package/starters/examples/src/examples/nature/camera.ts +15 -0
  188. package/starters/examples/src/examples/nature/grass.ts +64 -0
  189. package/starters/examples/src/examples/nature/index.ts +327 -0
  190. package/starters/examples/src/examples/nature/land.ts +173 -0
  191. package/starters/examples/src/examples/nature/looks.ts +577 -0
  192. package/starters/examples/src/examples/nature/maps.ts +370 -0
  193. package/starters/examples/src/examples/nature/skies.ts +324 -0
  194. package/starters/examples/src/examples/nature/weather.ts +80 -0
  195. package/starters/examples/src/examples/performance/index.ts +263 -0
  196. package/starters/examples/src/examples/performance/looks.ts +372 -0
  197. package/starters/examples/src/examples/performance/meter.ts +158 -0
  198. package/starters/examples/src/examples/post/grades.ts +86 -0
  199. package/starters/examples/src/examples/post/index.ts +202 -0
  200. package/starters/examples/src/examples/post/looks.ts +884 -0
  201. package/starters/examples/src/examples/post/passes.ts +213 -0
  202. package/starters/examples/src/examples/rts/ai.ts +49 -0
  203. package/starters/examples/src/examples/rts/airlift.ts +43 -0
  204. package/starters/examples/src/examples/rts/base.ts +129 -0
  205. package/starters/examples/src/examples/rts/build.ts +65 -0
  206. package/starters/examples/src/examples/rts/camps.ts +36 -0
  207. package/starters/examples/src/examples/rts/carry.ts +103 -0
  208. package/starters/examples/src/examples/rts/creeps.ts +61 -0
  209. package/starters/examples/src/examples/rts/data.ts +406 -0
  210. package/starters/examples/src/examples/rts/ferry.ts +41 -0
  211. package/starters/examples/src/examples/rts/garrison.ts +50 -0
  212. package/starters/examples/src/examples/rts/harvest.ts +29 -0
  213. package/starters/examples/src/examples/rts/hero.ts +67 -0
  214. package/starters/examples/src/examples/rts/index.ts +77 -0
  215. package/starters/examples/src/examples/rts/looks.ts +721 -0
  216. package/starters/examples/src/examples/rts/shop.ts +46 -0
  217. package/starters/examples/src/examples/rts/tech.ts +39 -0
  218. package/starters/examples/src/examples/rts/train.ts +48 -0
  219. package/starters/examples/src/examples/rts/waterside.ts +185 -0
  220. package/starters/examples/src/examples/showcase/index.ts +714 -0
  221. package/starters/examples/src/examples/showcase/looks.ts +238 -0
  222. package/starters/examples/src/game.ts +17 -0
  223. package/starters/examples/src/main.ts +82 -0
  224. package/starters/examples/src/rules.ts +31 -0
  225. package/starters/examples/src/shell/look.ts +79 -0
  226. package/starters/examples/src/shell/registry.ts +7 -0
  227. package/starters/examples/src/shell/scenes.ts +178 -0
  228. package/starters/examples/src/shell/shell.ts +290 -0
  229. package/starters/examples/src/shell/style.ts +202 -0
  230. package/starters/examples/src/view.ts +50 -0
  231. package/starters/melee/README.md +12 -3
  232. package/starters/melee/layers/tests/tests/heroes.test.ts +402 -0
  233. package/starters/melee/layers/tests/tests/rules.test.ts +10 -8
  234. package/starters/melee/src/game.ts +32 -2
  235. package/starters/melee/src/maps/bay.names.ts +2 -2
  236. package/starters/melee/src/maps/bay.vgmap.json +198 -1
  237. package/starters/melee/src/maps.ts +11 -9
  238. package/starters/melee/src/melee/abilities.ts +1 -194
  239. package/starters/melee/src/melee/blight.ts +7 -7
  240. package/starters/melee/src/melee/cellLayers.json +3 -3
  241. package/starters/melee/src/melee/data.json +1 -18
  242. package/starters/melee/src/melee/game.ts +6 -4
  243. package/starters/melee/src/melee/heroes.ts +1025 -0
  244. package/starters/melee/src/melee/index.ts +64 -61
  245. package/starters/melee/src/melee/items.ts +15 -362
  246. package/starters/melee/src/melee/languages/he.json +14 -2
  247. package/starters/melee/src/melee/pings.ts +5 -6
  248. package/starters/melee/src/melee/saves.ts +1 -1
  249. package/starters/melee/src/melee/undead.ts +15 -230
  250. package/starters/melee/src/melee/units.ts +37 -171
  251. package/starters/melee/src/melee/view/attacks.ts +19 -0
  252. package/starters/melee/src/melee/view/heroSpellLooks.ts +39 -8
  253. package/starters/melee/src/melee/view/index.ts +56 -52
  254. package/starters/melee/src/melee/view/looks.ts +86 -63
  255. package/starters/melee/src/melee/view/undeadLooks.ts +70 -31
  256. package/starters/melee/src/melee/view/walls.ts +1 -1
  257. package/starters.mjs +6 -0
  258. package/v12.mjs +14 -15
  259. package/starters/campaign/src/rules.ts +0 -20
  260. package/starters/empty/src/maps.ts +0 -44
  261. package/starters/empty/src/tiles.ts +0 -12
  262. package/starters/melee/src/melee/heroSpells.ts +0 -38
  263. package/starters/melee/src/rules.ts +0 -24
@@ -1,37 +1,41 @@
1
1
  import {
2
2
  defineCellLayer,
3
+ foliagePack,
4
+ presetFoliageStyles,
3
5
  defineRace,
4
- withCapture,
5
- withConcealment,
6
- withStances,
7
- withData,
6
+ capturePack,
7
+ stancesPack,
8
+ layData,
8
9
  type Entity,
9
- type GameModule,
10
- type StartData,
10
+ type Rules,
11
+ type StartingBaseData,
11
12
  hotRules,
12
13
  presetScore,
13
14
  heroState,
14
- withHeroes,
15
- withMobaStats,
16
- withVeterancy,
17
- withWalls,
18
- withRemains,
19
- withFriendlyFire,
20
- laneMinion
15
+ heroesPack,
16
+ mobaStatsPack,
17
+ veterancyPack,
18
+ wallsPack,
19
+ remainsPack,
20
+ friendlyFirePack,
21
+ laneMinion,
22
+ defaultCallingSet,
23
+ defaultHeroSpellSet,
24
+ useDefaults,
25
+ visionPack
21
26
  } from '@v12-engine/engine'
22
27
  import { meleeBrain } from '@v12-engine/engine/ai'
23
28
  import { abilities, buffs } from './abilities'
24
29
  import { formations } from './formations'
25
30
  import { blightLayer, blightSpread, blightSystem, undeadHooks } from './blight'
26
- import { heroSpellBuffs, heroSpells } from './heroSpells'
27
- import { itemAbilities, itemEffects, items } from './items'
31
+ import { harvested, heroAbilities, heroBuffs, heroEffects, heroHooks } from './heroes'
32
+ import { defaultItemSet } from './items'
28
33
  import { meleeEditor, tiles } from './maps'
29
34
  import { meleeGenerator } from './generator'
30
35
  import { units, upgrades } from './units'
31
36
  import { meleeSaves } from './saves'
32
37
  import { undeadAbilities, undeadBuffs } from './undead'
33
38
  import dataFile from './data.json'
34
- import { maps } from '../maps'
35
39
  import { PING_KINDS, pingsFile } from './pings'
36
40
 
37
41
  /** The ruins a fallen building leaves (`ruins`): of its size, 2 to 4 cells; none for a wall's piece, what stands on something, what cannot be felled, or ruins (taken away, they leave nothing) */
@@ -43,11 +47,14 @@ function ruinsOf(dead: Entity): string | null {
43
47
  }
44
48
 
45
49
  /** A town hall and five peasants on the side of the closest gold mine, as in a classic melee game: the humans' start, and the game's */
46
- const HUMAN_START: StartData = { hall: 'townhall', workers: { type: 'peasant', count: 5 } }
50
+ const HUMAN_START: StartingBaseData = { hall: 'townhall', workers: { type: 'peasant', count: 5 } }
47
51
 
48
- /** Classic base building: gather gold, raise an army, destroy the other side */
49
- export const melee: GameModule = withData(
50
- {
52
+ /**
53
+ * Classic base building: gather gold, raise an army, destroy the other side. Its items are the engine's (`./items`):
54
+ * all of them, with what they use and the hero arena stats they give
55
+ */
56
+ export const melee: Rules = layData(
57
+ useDefaults({
51
58
  id: 'my-game',
52
59
  name: 'My game',
53
60
  version: '1.0.0',
@@ -63,24 +70,24 @@ export const melee: GameModule = withData(
63
70
  id: 'human',
64
71
  name: 'Human',
65
72
  description: 'The Kingdom: peasants, footmen, riflemen and gryphons',
66
- // a town hall and five peasants on the side of the closest gold mine (`StartData`, the engine's `startingBase`)
67
- start: HUMAN_START
73
+ // a town hall and five peasants on the side of the closest gold mine (`StartingBaseData`, the engine's `startingBase`)
74
+ startingBase: HUMAN_START
68
75
  }),
69
76
  defineRace({
70
77
  id: 'undead',
71
78
  name: 'Undead',
72
79
  description: 'The Restless: acolytes gather at a cursed mine, ghouls bring lumber, everything goes up on blight',
73
80
  // a gravehold and a cursed mine on the closest gold mine, three acolytes and a ghoul
74
- start: { hall: 'gravehold', workers: { type: 'acolyte', count: 3 }, units: [{ type: 'ghoul', count: 1 }], onMine: 'cursedMine' },
81
+ startingBase: { hall: 'gravehold', workers: { type: 'acolyte', count: 3 }, units: [{ type: 'ghoul', count: 1 }], onMine: 'cursedMine' },
75
82
  // gold at a cursed mine, buildings on blight (`blight.ts`)
76
83
  hooks: undeadHooks
77
84
  })
78
85
  ],
79
- abilities: [...abilities, ...heroSpells, ...itemAbilities, ...undeadAbilities],
86
+ // the heroes' own (`heroes.ts`); the spells every hero brings two of are the engine's set (`defaultHeroSpellSet`)
87
+ abilities: [...abilities, ...heroAbilities, ...undeadAbilities],
80
88
  // the classic battle line beside the engine's formations, on the button by the minimap (`formations.ts`)
81
89
  formations,
82
- effects: itemEffects,
83
- items,
90
+ effects: heroEffects,
84
91
  resources: [
85
92
  // gold pays for most things, and is what upkeep cuts into
86
93
  { id: 'gold', name: 'Gold', start: 500, upkeep: true },
@@ -88,13 +95,19 @@ export const melee: GameModule = withData(
88
95
  ],
89
96
  currency: 'gold',
90
97
  tiles,
91
- // tall grass, painted on the map: what is in it is hidden from those outside (features-plan G)
98
+ // grass painted on the map, of the foliage pack (`foliagePack` below): tall grass, whose who stands in it is hidden
99
+ // from those outside it, and dry grass that burns fast. Each value is a style: what it is to the rules here, how it
100
+ // looks in the view (`ground.cellLayers.bush`), by the names of the engine's ready-made ones (`presetFoliageStyles`)
92
101
  cellLayers: [
93
102
  defineCellLayer({
94
103
  id: 'bush',
95
104
  name: 'Bushes',
96
105
  description: 'Tall grass: who stands in it is hidden from those outside it',
97
- color: [0.2, 0.75, 0.25]
106
+ color: [0.2, 0.75, 0.25],
107
+ values: [
108
+ { value: 1, name: 'Tall grass', foliage: presetFoliageStyles.tallGrass },
109
+ { value: 2, name: 'Dry grass', color: [0.8, 0.7, 0.4], foliage: presetFoliageStyles.dryGrass }
110
+ ]
98
111
  }),
99
112
  // spoiled ground round the Restless' halls and cursed mines, that its buildings go up on (features-plan C5)
100
113
  blightLayer
@@ -103,43 +116,44 @@ export const melee: GameModule = withData(
103
116
  editor: meleeEditor,
104
117
  // maps made by a generator: the ground, the starts, the mines and their camps, the woods (`generator.ts`)
105
118
  generator: meleeGenerator,
106
- // the maps it ships, the Bay: a save of a game on it keeps only what changed of its ground
107
- maps: Object.values(maps),
108
119
  // the file the editor's Pings fold writes, whose kinds the rules let go (`./pings`)
109
120
  files: [pingsFile],
110
121
  upkeep: [
111
122
  { above: 50, name: 'Low upkeep', income: 0.7 },
112
123
  { above: 80, name: 'High upkeep', income: 0.4 }
113
124
  ],
114
- buffs: [...buffs, ...heroSpellBuffs, ...undeadBuffs],
125
+ buffs: [...buffs, ...heroBuffs, ...undeadBuffs],
115
126
  // as in classic RTS games: eight minutes from one morning to the next, starting at eight
116
127
  day: { length: 480, start: 8, dawn: 6, dusk: 18 },
117
128
  // heroes, creeps' camps that guard their ground and sleep there at night, shops and taverns, as in classic RTS games
118
- // who stands in the bushes is seen only from the same bush, or from close by; points to capture; units' stances
129
+ // who stands in the bushes is seen only from the same bush, or from close by, and they burn, as their styles say
130
+ // (`foliagePack`: set alight with `ignite`, by an ability's `foliage` effect, or the editor's Play here); points to
131
+ // capture; units' stances
119
132
  // the heroes' stats: ability power, crits, penetration, life steal, tenacity, haste (a hero arena game's)
120
133
  // pieces of wall laid in a line and joined (`stoneWall`); units that are not heroes ranking up by their kills, a
121
134
  // lane's minions not: a wave is as strong as the one before it
122
135
  packs: [
123
- withHeroes(),
124
- withConcealment({ layer: 'bush' }),
125
- withCapture(),
126
- withStances(),
127
- withMobaStats(),
128
- withWalls(),
129
- withVeterancy({ earns: (_world, entity) => entity.alive && !entity.isStructure && !entity.has(heroState) && !entity.has(laneMinion) }),
136
+ heroesPack(),
137
+ foliagePack({ layer: 'bush', fire: { damage: 5 } }),
138
+ capturePack(),
139
+ stancesPack(),
140
+ mobaStatsPack(),
141
+ wallsPack(),
142
+ veterancyPack({ earns: (_world, entity) => entity.alive && !entity.isStructure && !entity.has(heroState) && !entity.has(laneMinion) }),
143
+ // a unit seen wherever it runs (a branded hero, a marked one), and one seen only from up close (a hero in the shadows)
144
+ visionPack(),
130
145
  // a fallen building leaves ruins of its size where it stood, to clear for their lumber (`ruins`); not a wall's
131
146
  // piece, nor what stands on something (a cursed mine on its gold mine), nor what nothing can fell
132
- withRemains({ rubble: (_world, dead) => ruinsOf(dead) }),
147
+ remainsPack({ rubble: (_world, dead) => ruinsOf(dead) }),
133
148
  // as in classic RTS games: a unit told to attack (A, then a click) one of its own or an ally's does; a right click never
134
- withFriendlyFire()
149
+ friendlyFirePack()
135
150
  ],
136
151
  // what a player of no race starts with: the humans' start
137
- start: HUMAN_START,
152
+ startingBase: HUMAN_START,
138
153
  // its computer players play by the engine's profiles: on a server, each seat the computer plays gets a difficulty
139
154
  // and a personality to choose in the lobby (`seatSettingsOf`; `againstTheRest` reads them)
140
155
  ai: {},
141
- // the classic damage table: each attack type against each armour type (`units.ts`, `undead.ts` name them)
142
- rules: {
156
+ settings: {
143
157
  // the pings the view draws (`./pings`), and those the editor's Pings fold added (`pings.json`)
144
158
  talk: { pings: { kinds: PING_KINDS } },
145
159
  // the time left of a hero's buffs to everyone who sees it, for the plate's sweeps (indicators-plan U3): a hero's
@@ -153,28 +167,17 @@ export const melee: GameModule = withData(
153
167
  // sight. A map says otherwise (Map › Starts explored)
154
168
  fog: { startExplored: true },
155
169
  // allies trade as in a classic allies menu: what one sends arrives whole (`give`, the Allies panel)
156
- economy: { tradeTax: 0 },
157
- combat: {
158
- damageTable: {
159
- attacks: ['normal', 'pierce', 'siege', 'magic', 'chaos', 'hero'],
160
- armours: ['light', 'medium', 'heavy', 'fortified', 'hero', 'unarmored'],
161
- table: [
162
- [1, 1.5, 1, 0.7, 1, 1],
163
- [2, 0.75, 1, 0.35, 0.5, 1.5],
164
- [1, 0.5, 1, 1.5, 0.5, 1.5],
165
- [1.25, 0.75, 2, 0.35, 0.5, 1],
166
- [1, 1, 1, 1, 1, 1],
167
- [1, 1, 1, 0.5, 1, 1]
168
- ]
169
- }
170
- }
170
+ economy: { tradeTax: 0 }
171
171
  },
172
- components: [blightSpread],
172
+ // what Bone Reaver reaped, kept through his deaths (`heroes.ts`)
173
+ components: [blightSpread, harvested],
174
+ // what the heroes' innates do in code: Bulwark, Shatter, Shadow Step, Static Charge, Harvest (`heroes.ts`)
175
+ hooks: heroHooks,
173
176
  // a save made before a patch is loaded after it (`saves.ts`)
174
177
  saves: meleeSaves,
175
178
  // every number and word of every definition can be changed from the editor's Data panel, and is kept in `data.json`
176
179
  editable: 'all'
177
- },
180
+ }, [defaultItemSet, defaultHeroSpellSet(), defaultCallingSet()]),
178
181
  dataFile
179
182
  )
180
183
 
@@ -1,362 +1,15 @@
1
- import { type AbilityDef, defineEffect, type EffectKind, type ItemDef } from '@v12-engine/engine'
2
-
3
- // the game's own effects, each with the fields it reads (`EffectTypes`)
4
- declare module '@v12-engine/engine' {
5
- interface EffectTypes {
6
- /** Heals the carrier `perSecond` of its health a second, once it has gone `unhurtFor` seconds without being hurt */
7
- mend: { perSecond: number; unhurtFor: number }
8
- }
9
- }
10
-
11
- /** What using an item does. Abilities like any other, only that nobody has them without the item */
12
- export const itemAbilities: AbilityDef[] = [
13
- {
14
- id: 'revealArea',
15
- name: 'Reveal',
16
- description: 'Lifts the fog over an area anywhere for 5 seconds. Enemies can see it happen',
17
- target: 'point',
18
- range: 1000,
19
- cooldown: 10,
20
- effects: [{ type: 'reveal', radius: 9, duration: 5 }]
21
- },
22
- {
23
- id: 'plantWard',
24
- name: 'Plant',
25
- description: 'Puts down a ward that sees around it for 60 seconds. Enemies see it for the first 2 seconds, then only with an oracle',
26
- target: 'point',
27
- range: 6,
28
- cooldown: 1,
29
- effects: [{ type: 'spawn', unit: 'ward' }]
30
- },
31
- {
32
- id: 'sweep',
33
- name: 'Sweep',
34
- description: 'Sends out a pulse that finds enemy wards around the hero. They can be seen, and struck down, for 8 seconds',
35
- target: 'none',
36
- cooldown: 25,
37
- effects: [{ type: 'detect', radius: 14, duration: 8 }]
38
- },
39
- {
40
- id: 'drinkHealing',
41
- name: 'Drink',
42
- description: 'Restores 250 health',
43
- target: 'none',
44
- cooldown: 20,
45
- effects: [{ type: 'heal', amount: 250, on: 'caster' }]
46
- },
47
- {
48
- id: 'drinkMana',
49
- name: 'Drink',
50
- description: 'Restores 150 mana',
51
- target: 'none',
52
- cooldown: 20,
53
- effects: [{ type: 'mana', amount: 150, on: 'caster' }]
54
- },
55
- {
56
- id: 'readHealing',
57
- name: 'Read',
58
- description: 'Heals friendly units around the reader for 150',
59
- target: 'none',
60
- cooldown: 30,
61
- effects: [{ type: 'heal', amount: 150, radius: 6 }]
62
- },
63
- {
64
- id: 'intervention',
65
- name: 'Intervention',
66
- description: 'Calls down a beam on a spot far away: after 2.5 seconds friends there regain 150 to 350 health, more with every level',
67
- target: 'point',
68
- range: 68,
69
- cooldown: 90,
70
- aim: { shape: 'circle', radius: 6.9 },
71
- effects: [{ type: 'after', delay: 2.5, effects: [{ type: 'heal', amount: 150, scaling: { level: 11.8 }, radius: 6.9 }] }]
72
- },
73
- {
74
- id: 'mendingHeart',
75
- name: 'Mending Heart',
76
- description: 'Regains 3% of its health every second after 8 seconds without being hurt',
77
- target: 'passive',
78
- effects: [{ type: 'mend', perSecond: 0.03, unhurtFor: 8 }]
79
- }
80
- ]
81
-
82
- /** What the items do that the effects of the engine do not cover */
83
- export const itemEffects: EffectKind[] = [
84
- /** Kept up all the time: a part of its health back every second, once `delay` seconds have passed without being hurt */
85
- defineEffect('mend', ({ world, caster, interval = 0 }, effect) => {
86
- if (world.time - caster.hurtAt >= effect.unhurtFor) world.heal(caster, caster.maxHp * effect.perSecond * interval)
87
- })
88
- ]
89
-
90
- /** Shops never run out of what is built to last. What is used up comes a few at a time */
91
- const few = (max: number, restock: number) => ({ max, restock })
92
-
93
- export const items: ItemDef[] = [
94
- // ---- used up
95
- {
96
- id: 'healingPotion',
97
- name: 'Health Potion',
98
- description: 'Restores 250 health when drunk',
99
- tier: 'consumable',
100
- cost: { gold: 150 },
101
- charges: 1,
102
- ability: 'drinkHealing',
103
- stock: few(3, 60)
104
- },
105
- {
106
- id: 'manaPotion',
107
- name: 'Mana Potion',
108
- description: 'Restores 150 mana when drunk',
109
- tier: 'consumable',
110
- cost: { gold: 200 },
111
- charges: 1,
112
- ability: 'drinkMana',
113
- stock: few(2, 60)
114
- },
115
- {
116
- id: 'scrollOfHealing',
117
- name: 'Scroll of Healing',
118
- description: 'Heals friendly units around the reader for 150',
119
- tier: 'consumable',
120
- cost: { gold: 250 },
121
- charges: 1,
122
- ability: 'readHealing',
123
- stock: few(1, 120)
124
- },
125
- {
126
- id: 'revealingDust',
127
- name: 'Revealing Dust',
128
- description: 'Lifts the fog over an area anywhere on the map for 5 seconds. Enemies can see it happen',
129
- tier: 'consumable',
130
- cost: { gold: 50 },
131
- charges: 2,
132
- ability: 'revealArea',
133
- stock: few(3, 45)
134
- },
135
- {
136
- id: 'sentryWard',
137
- name: 'Sentry Ward',
138
- description: 'Puts down a ward that sees around it for 60 seconds. Enemies see it for 2 seconds, then only with an oracle. Goes down in 3 hits',
139
- tier: 'consumable',
140
- cost: { gold: 75 },
141
- charges: 2,
142
- ability: 'plantWard',
143
- stock: few(2, 60)
144
- },
145
- {
146
- id: 'oracle',
147
- name: "Oracle's Eye",
148
- description: 'Sends out a pulse that finds enemy wards around the hero, for 8 seconds. Every 25 seconds',
149
- tier: 'consumable',
150
- cost: { gold: 150 },
151
- ability: 'sweep',
152
- stock: few(1, 90)
153
- },
154
-
155
- // ---- to start with
156
- {
157
- id: 'squiresBlade',
158
- name: "Squire's Blade",
159
- description: '+10 attack damage, +80 health, and 2.5% of all damage dealt comes back as health',
160
- tier: 'starter',
161
- cost: { gold: 225 },
162
- bonus: { stats: { attackDamage: 10, health: 80, omnivamp: 0.025 } }
163
- },
164
- {
165
- id: 'squiresShield',
166
- name: "Squire's Shield",
167
- description: '+110 health, and 0.8 more health regained per second',
168
- tier: 'starter',
169
- cost: { gold: 225 },
170
- bonus: { stats: { health: 110, healthRegen: 0.8 } }
171
- },
172
- {
173
- id: 'squiresRing',
174
- name: "Squire's Ring",
175
- description: '+18 ability power, +90 health, and 1 more mana regained per second',
176
- tier: 'starter',
177
- cost: { gold: 200 },
178
- bonus: { stats: { abilityPower: 18, health: 90, manaRegen: 1 } }
179
- },
180
-
181
- // ---- basic
182
- {
183
- id: 'longSword',
184
- name: 'Long Sword',
185
- description: '+10 attack damage',
186
- tier: 'basic',
187
- cost: { gold: 175 },
188
- bonus: { stats: { attackDamage: 10 } }
189
- },
190
- { id: 'dagger', name: 'Dagger', description: 'Attacks 10% faster', tier: 'basic', cost: { gold: 125 }, bonus: { percent: { attackSpeed: 0.1 } } },
191
- { id: 'clothArmor', name: 'Cloth Armor', description: '+15 armor', tier: 'basic', cost: { gold: 150 }, bonus: { stats: { armor: 15 } } },
192
- {
193
- id: 'wardingMantle',
194
- name: 'Warding Mantle',
195
- description: '+20 magic resist',
196
- tier: 'basic',
197
- cost: { gold: 200 },
198
- bonus: { stats: { magicResist: 20 } }
199
- },
200
- { id: 'bloodGem', name: 'Blood Gem', description: '+150 health', tier: 'basic', cost: { gold: 200 }, bonus: { stats: { health: 150 } } },
201
- {
202
- id: 'apprenticeTome',
203
- name: "Apprentice's Tome",
204
- description: '+20 ability power',
205
- tier: 'basic',
206
- cost: { gold: 200 },
207
- bonus: { stats: { abilityPower: 20 } }
208
- },
209
- {
210
- id: 'manaCharm',
211
- name: 'Mana Charm',
212
- description: 'Mana comes back 50% faster',
213
- tier: 'basic',
214
- cost: { gold: 100 },
215
- bonus: { percent: { manaRegen: 0.5 } }
216
- },
217
- { id: 'boots', name: 'Boots', description: '+25 move speed', tier: 'basic', cost: { gold: 150 }, bonus: { stats: { moveSpeed: 0.3125 } } },
218
- {
219
- id: 'duelistsCloak',
220
- name: "Duelist's Cloak",
221
- description: '15% chance to strike critically',
222
- tier: 'basic',
223
- cost: { gold: 300 },
224
- bonus: { stats: { critChance: 0.15 } }
225
- },
226
- { id: 'pickaxe', name: 'Pickaxe', description: '+25 attack damage', tier: 'basic', cost: { gold: 440 }, bonus: { stats: { attackDamage: 25 } } },
227
- {
228
- id: 'greatsword',
229
- name: 'Greatsword',
230
- description: '+40 attack damage',
231
- tier: 'basic',
232
- cost: { gold: 650 },
233
- bonus: { stats: { attackDamage: 40 } }
234
- },
235
-
236
- // ---- built from the basic ones
237
- {
238
- id: 'leechingRod',
239
- name: 'Leeching Rod',
240
- description: '+15 attack damage, and 7% of the damage of attacks comes back as health',
241
- tier: 'epic',
242
- cost: { gold: 450 },
243
- from: ['longSword'],
244
- bonus: { stats: { attackDamage: 15, lifeSteal: 0.07 } }
245
- },
246
- {
247
- id: 'jaggedKnife',
248
- name: 'Jagged Knife',
249
- description: '+20 attack damage, ignores 10 armor',
250
- tier: 'epic',
251
- cost: { gold: 500 },
252
- from: ['longSword', 'longSword'],
253
- bonus: { stats: { attackDamage: 20, lethality: 10 } }
254
- },
255
- {
256
- id: 'hexCodex',
257
- name: 'Hex Codex',
258
- description: '+25 ability power, 10 ability haste',
259
- tier: 'epic',
260
- cost: { gold: 425 },
261
- from: ['apprenticeTome'],
262
- bonus: { stats: { abilityPower: 25, abilityHaste: 10 } }
263
- },
264
- {
265
- id: 'piercingJewel',
266
- name: 'Piercing Jewel',
267
- description: '+25 ability power, ignores 13% of magic resist',
268
- tier: 'epic',
269
- cost: { gold: 550 },
270
- from: ['apprenticeTome'],
271
- bonus: { stats: { abilityPower: 25, magicPenetrationPercent: 0.13 } }
272
- },
273
- {
274
- id: 'mendersIdol',
275
- name: "Mender's Idol",
276
- description: 'Heals and shields are 8% stronger, mana comes back 50% faster',
277
- tier: 'epic',
278
- cost: { gold: 300 },
279
- from: ['manaCharm'],
280
- bonus: { stats: { healShieldPower: 0.08 }, percent: { manaRegen: 0.5 } }
281
- },
282
- {
283
- id: 'ogreBelt',
284
- name: 'Ogre Belt',
285
- description: '+350 health',
286
- tier: 'epic',
287
- cost: { gold: 450 },
288
- from: ['bloodGem'],
289
- bonus: { stats: { health: 350 } }
290
- },
291
- {
292
- id: 'stoneBracer',
293
- name: 'Stone Bracer',
294
- description: '+200 health, and health comes back twice as fast',
295
- tier: 'epic',
296
- cost: { gold: 400 },
297
- from: ['bloodGem'],
298
- bonus: { stats: { health: 200 }, percent: { healthRegen: 1 } }
299
- },
300
- {
301
- id: 'chainVest',
302
- name: 'Chain Vest',
303
- description: '+40 armor',
304
- tier: 'epic',
305
- cost: { gold: 400 },
306
- from: ['clothArmor'],
307
- bonus: { stats: { armor: 40 } }
308
- },
309
- {
310
- id: 'swiftGreaves',
311
- name: 'Swift Greaves',
312
- description: '+45 move speed, attacks 30% faster',
313
- tier: 'epic',
314
- cost: { gold: 550 },
315
- from: ['boots', 'dagger', 'dagger'],
316
- bonus: { stats: { moveSpeed: 0.5625 }, percent: { attackSpeed: 0.3 } }
317
- },
318
- {
319
- id: 'steadfastTreads',
320
- name: 'Steadfast Treads',
321
- description: '+45 move speed, +20 magic resist, stuns and slows last 30% shorter',
322
- tier: 'epic',
323
- cost: { gold: 625 },
324
- from: ['boots', 'wardingMantle'],
325
- bonus: { stats: { moveSpeed: 0.5625, magicResist: 20, tenacity: 0.3 } }
326
- },
327
-
328
- // ---- what it all leads to
329
- {
330
- id: 'keenEdge',
331
- name: 'Keen Edge',
332
- description: '+75 attack damage, 25% chance to strike critically, and critical strikes deal 30% more',
333
- tier: 'legendary',
334
- cost: { gold: 1750 },
335
- from: ['greatsword', 'pickaxe', 'duelistsCloak'],
336
- bonus: { stats: { attackDamage: 75, critChance: 0.25, critDamage: 0.3 } }
337
- },
338
- {
339
- id: 'mendingPlate',
340
- name: 'Mending Plate',
341
- description: '+1000 health, health comes back twice as fast. After 8 seconds without being hurt, 3% of its health comes back every second',
342
- tier: 'legendary',
343
- cost: { gold: 1550 },
344
- from: ['ogreBelt', 'ogreBelt', 'stoneBracer'],
345
- bonus: { stats: { health: 1000 }, percent: { healthRegen: 1 } },
346
- passive: 'mendingHeart'
347
- },
348
- {
349
- id: 'reprieve',
350
- name: 'Reprieve',
351
- description:
352
- '+30 ability power, 15 ability haste, heals and shields are 10% stronger, mana comes back twice as fast. Used: a beam on a spot far away heals friends there for 150 to 350 after 2.5 seconds. Every 90 seconds',
353
- tier: 'legendary',
354
- cost: { gold: 1150 },
355
- from: ['hexCodex', 'mendersIdol'],
356
- bonus: { stats: { abilityPower: 30, abilityHaste: 15, healShieldPower: 0.1 }, percent: { manaRegen: 1 } },
357
- ability: 'intervention'
358
- }
359
- ]
360
-
361
- /** Everything there is to buy, the way a shop lays it out */
362
- export const catalogue = items.map((item) => item.id)
1
+ import { defaultItems, defaultItemSet, itemTier } from '@v12-engine/engine'
2
+
3
+ /*
4
+ * The game's items are the engine's default set (`defaultItemSet`): a whole tree, from the draughts to the twelve
5
+ * legendaries and the relics, with what they use. The game takes it in `index.ts` (`useDefaults`), all of it; to take
6
+ * all but some, only some, some changed, items of its own besides, or none, say so there:
7
+ *
8
+ * useDefaults(rules, [defaultItemSet], { items: { except: ['sightWard'], with: [myItem], change: { boots: { cost: { gold: 250 } } } } })
9
+ *
10
+ * or in `data.json` (the editor's Data panel writes it): `"defaults": { "items": { "except": ["sightWard"] } }`
11
+ */
12
+ export { defaultItemSet }
13
+
14
+ /** Everything there is to buy, the way a shop lays it out: the set's items but the relics, which are found, never sold */
15
+ export const catalogue = defaultItems.filter((item) => itemTier(item) !== 'relic').map((item) => item.id)
@@ -56,6 +56,12 @@
56
56
  "ui.menu.saves": "שמירה וטעינה",
57
57
  "ui.menu.score": "ניקוד",
58
58
  "ui.menu.restart": "התחלה מחדש",
59
+ "ui.menu.photo": "מצב צילום",
60
+ "ui.photo.how": "W, A, S, D לתנועה, Q ו-E למטה ולמעלה, Shift מהר יותר; גרירה לסיבוב, הכפתור האמצעי להזזה, הגלגלת לקרבה ולמרחק; Esc ליציאה",
61
+ "ui.photo.hour": "שעה ביום",
62
+ "ui.photo.take": "צילום",
63
+ "ui.photo.leave": "יציאה",
64
+ "ui.photo.taken": "{name}, {width} × {height}",
59
65
  "ui.menu.surrender": "כניעה",
60
66
  "ui.menu.waits": "המשחק ממתין",
61
67
  "ui.settings.reset": "החזרת הכול לברירת המחדל",
@@ -78,8 +84,14 @@
78
84
  "unit.gryphon": "רוכב גריפון",
79
85
  "unit.priest": "כוהן",
80
86
  "unit.sorceress": "מכשפה",
81
- "unit.paladin": "פלדין",
82
- "unit.archmage": "ארכי־קוסם",
87
+ "unit.oathbreaker": "שובר השבועה",
88
+ "unit.dawnPriest": "כוהן השחר",
89
+ "unit.stormcaller": "קורא הסערה",
90
+ "unit.galeHunter": "צייד הרוח",
91
+ "unit.gravelord": "אדון הקברים",
92
+ "unit.rimeWitch": "מכשפת הכפור",
93
+ "unit.duskblade": "להב הדמדומים",
94
+ "unit.boneReaver": "קוצר העצמות",
83
95
  "unit.townhall": "בית העירייה",
84
96
  "unit.keep": "מבצר",
85
97
  "unit.castle": "טירה",
@@ -9,23 +9,22 @@ export const WHEEL_PINGS = ['look', 'danger', 'assist', 'onMyWay', 'missing', 'r
9
9
 
10
10
  /**
11
11
  * The pings melee has besides the wheel's: sent from code and heard by a computer ally (push attacks, hold defends:
12
- * `GameRules.talk.pings.meanings`), off the wheel (`wheel: { hidden: true }` in the view)
12
+ * `RuleSettings.talk.pings.meanings`), off the wheel (`wheel: { hidden: true }` in the view)
13
13
  */
14
14
  export const OFF_WHEEL_PINGS = ['hold', 'push', 'question'] as const
15
15
 
16
16
  /**
17
17
  * The kinds of ping melee has, kept in one place: what the view draws and puts on the wheel (`playerPings:
18
- * withPingsFile(presetPings(PINGS), pings.json)`)
18
+ * layPings(presetPings(PINGS), pings.json)`)
19
19
  */
20
20
  export const PINGS = [...WHEEL_PINGS, ...OFF_WHEEL_PINGS] as const
21
21
 
22
22
  /**
23
- * The kinds the editor's Pings fold added in `pings.json`, its keys: a file of the game's own (`GameModule.files`), read
23
+ * The kinds the editor's Pings fold added in `pings.json`, its keys: a file of the game's own (`Rules.files`), read
24
24
  * without the client (the module runs where the simulation runs), and read again as the fold writes it
25
25
  */
26
- export const pingsFile = defineGameFile('pings.json', pingsData, (data) =>
27
- Object.keys((data as { kinds?: Record<string, unknown> } | null)?.kinds ?? {})
28
- )
26
+ export const pingsFile = defineGameFile({ id: 'pings.json', data: pingsData, read: (data) =>
27
+ Object.keys((data as { kinds?: Record<string, unknown> } | null)?.kinds ?? {}) })
29
28
 
30
29
  /**
31
30
  * What the rules let go (`rules.talk.pings.kinds`): the kinds above and those of `pings.json` as the game plays it, so a
@@ -1,7 +1,7 @@
1
1
  import type { SaveRules } from '@v12-engine/engine'
2
2
 
3
3
  /*
4
- * How melee's saves outlive its patches (`GameModule.saves`): the version of what it keeps in a save, and the step
4
+ * How melee's saves outlive its patches (`Rules.saves`): the version of what it keeps in a save, and the step
5
5
  * from each version to the next, for a save made before a patch that changed what a save holds. Declared, a save made
6
6
  * before a change of the rules loads all the same (without it, only a save of the very same rules does).
7
7
  */