@v12-engine/create 0.1.0 → 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 +2 -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
@@ -912,5 +912,89 @@
912
912
  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
913
913
  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
914
914
  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
915
- ]
915
+ ],
916
+ "cells": {
917
+ "grass": [
918
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
919
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
920
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
921
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
922
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
923
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
924
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
925
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
926
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
927
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
928
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
929
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
930
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
931
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
932
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
933
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
934
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
935
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
936
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
937
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
938
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
939
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
940
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
941
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
942
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
943
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
944
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
945
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
946
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
947
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
948
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
949
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
950
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
951
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
952
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
953
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
954
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAABAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
955
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
956
+ "AQEBAQEBAQEBAQEBAgICAgEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
957
+ "AQEBAQEBAQEBAQECAgICAgIBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
958
+ "AQEBAQEBAQEBAQICAgICAgICAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
959
+ "AQEBAQEBAQEBAQICAgICAgICAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
960
+ "AQEBAQEBAQEBAQICAgICAgICAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
961
+ "AQEBAQEBAQEBAQICAgICAgICAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
962
+ "AQEBAQEBAQEBAQECAgICAgIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
963
+ "AQEBAQEBAQEBAQEBAgICAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
964
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
965
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
966
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
967
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
968
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
969
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
970
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
971
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
972
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
973
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
974
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
975
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
976
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
977
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
978
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
979
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
980
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
981
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
982
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
983
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
984
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
985
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
986
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
987
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
988
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
989
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
990
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
991
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
992
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
993
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
994
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
995
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
996
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
997
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
998
+ ]
999
+ }
916
1000
  }
@@ -33,8 +33,8 @@ export type PassPaths = never
33
33
  /** The lights of the map that are named, for `client.lights.named(...)` */
34
34
  export type PassLights = never
35
35
 
36
- /** The effects of the map that are named, for `client.mapEffects.named(...)` */
37
- export type PassEffects = never
36
+ /** The effects of the map that are named, for `client.mapFx.named(...)` */
37
+ export type PassFx = never
38
38
 
39
39
  /** The ids of the regions, points and paths by name: what a field that names one keeps (it is handed the name) */
40
40
  export const PassIds = { regions: { "gate": 5, "yard": 8, "cells": 15 }, points: { "hold": 7, "back": 22 }, paths: { } } as const
@@ -518,5 +518,73 @@
518
518
  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
519
519
  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
520
520
  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
521
- ]
521
+ ],
522
+ "cells": {
523
+ "grass": [
524
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
525
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
526
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
527
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
528
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
529
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
530
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
531
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
532
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
533
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
534
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
535
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
536
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
537
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
538
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
539
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
540
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
541
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
542
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
543
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
544
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
545
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
546
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
547
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
548
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
549
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
550
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
551
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
552
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
553
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
554
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
555
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
556
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
557
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
558
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
559
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
560
+ "AQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
561
+ "AQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
562
+ "AQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
563
+ "AQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
564
+ "AQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
565
+ "AQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
566
+ "AQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
567
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
568
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
569
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
570
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
571
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
572
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
573
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
574
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
575
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
576
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
577
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
578
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
579
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
580
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
581
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
582
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
583
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
584
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
585
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
586
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
587
+ "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
588
+ ]
589
+ }
522
590
  }
@@ -113,7 +113,8 @@ function mount(element: HTMLElement, editor: EditorClient, panel: EditorPanel):
113
113
  row.className = kit.classes.option()
114
114
  row.dataset.wave = String(index)
115
115
  if (index === picked.get()) row.dataset.state = 'checked'
116
- row.textContent = `Wave ${index + 1}: ${describe(wave)}`
116
+ // (the letters the words typed were found in, marked: the kit's highlight)
117
+ row.replaceChildren(`Wave ${index + 1}: `, kit.highlight(describe(wave), filter()))
117
118
  row.addEventListener('click', () => pick(index))
118
119
  return row
119
120
  })
@@ -23,31 +23,36 @@ A game made with V12, at its start: a flat field, and a scout to walk it. Select
23
23
  <!-- @end -->
24
24
  | Check the types | `npm run typecheck` |
25
25
  | Build the page to host | `npm run build`, into `dist/` |
26
+ <!-- @if desktop -->
27
+ | Play it as an app | `npm run app`: the page in a window of its own (Electron, fetched the first time) |
28
+ | Make the app to hand out | `npm run package`, into `out/` |
29
+ <!-- @end -->
26
30
 
27
31
  ## Where to go from here
28
32
 
29
- 1. **A second unit type.** Add it to `UNIT` and `units` in `src/rules.ts`, and its look to `src/game.ts`. Give it `attackDamage`, `attackSpeed` and `attackRange` in its `stats`, and an attack in its `attacks`, and it fights.
30
- 2. **A second player.** `players: 2` in `src/maps.ts`, with a start for each, and `start` gives them a scout too.
33
+ 1. **A second unit type.** Add it to `UNIT` and give it with `game.unit({ … })` in `src/rules.ts`, and its look in `src/view.ts`. Give it `attackDamage`, `attackSpeed` and `attackRange` in its `stats`, and an attack in its `attacks`, and it fights.
34
+ 2. **A second player.** `players: 2` in `flatField` in `src/rules.ts`, with a start for each, and `game.onStart` gives them a scout too.
31
35
  <!-- @if editor -->
32
- 3. **A map of your own.** Open `/?editor`, paint, raise ground, place units, and Save. Then import `src/maps/field.vgmap.json` in `src/maps.ts`, as its comment says.
36
+ 3. **A map of your own.** Open `/?editor`, paint, raise ground, place units, and Save. Then give `src/maps/field.vgmap.json` to `game.maps` in `src/rules.ts`, as its comment says.
33
37
  <!-- @end -->
34
38
  <!-- @if !editor -->
35
- 3. **A map of your own.** `createMap` in `src/maps.ts` makes the field; its `ground`, `tiles` and `objects` are yours to fill in code.
39
+ 3. **A map of your own.** `createMap` in `src/rules.ts` makes the field; its `ground`, `tiles` and `objects` are yours to fill in code.
36
40
  <!-- @end -->
37
41
  4. **Winning.** `victory` in `src/rules.ts`: `coreVictory` makes the last side with a unit of a kind the winner.
38
42
  <!-- @if assets -->
39
- 5. **A model.** One of the shared art's (`import { characters } from '@v12-engine/assets'`, then `model: { src: characters.models.knight, scale: 0.6 }` in its look in `src/game.ts`), or a `.glb` of yours in `public/models/` (`src: 'scout.glb'`). The map editor's Content lists the shared art's trees, rocks and buildings to put down as scenery.
43
+ 5. **A model.** One of the shared art's (`import { characters } from '@v12-engine/assets'`, then `model: { src: characters.models.knight, scale: 0.6 }` in its look in `src/view.ts`), or a `.glb` of yours in `public/models/` (`src: 'scout.glb'`). The map editor's Content lists the shared art's trees, rocks and buildings to put down as scenery.
40
44
  <!-- @end -->
41
45
  <!-- @if !assets -->
42
- 5. **A model.** A `.glb` in `public/models/`, and `model: { src: 'scout.glb', scale: 1 }` in its look in `src/game.ts`.
46
+ 5. **A model.** A `.glb` in `public/models/`, and `model: { src: 'scout.glb', scale: 1 }` in its look in `src/view.ts`.
43
47
  <!-- @end -->
48
+ 6. **Grass.** A layer of cells in `src/rules.ts` with the engine's ready-made styles (`presetFoliageStyles`) and `foliagePack` among its packs, its look `foliage(presetFoliage.meadow)` in `src/view.ts`'s `ground.cellLayers`: it hides, burns and grows back as each style says, painted with the editor's Terrain panel.
44
49
 
45
50
  ## What is where
46
51
 
47
- - `src/rules.ts`: the rules, what there is and what happens once a game starts. The engine alone (`@v12-engine/engine`), so the page, the server and the tests play the same game
48
- - `src/game.ts`: how it looks, and the game whole (`defineGame`)
49
- - `src/maps.ts`: the maps. One, made in code. A map says which game it is for (`game`, the rules' `id`)
50
- - `src/main.ts`: the page, its scenes made by `appScenes`
52
+ - `src/rules.ts`: the game (`createGame`), what there is, its maps and what happens once a game starts. The engine alone (`@v12-engine/engine`), so the page, the server, the editor and the tests play the same game, and a worker of the page's reads it with nothing of the client. Its one map is made in code; a map says which game it is for (`game`, the game's `id`)
53
+ - `src/game.ts`: the game whole, its look given (`game.view(() => import('./view'))`): the one object the page, the server, the editor and the tests take
54
+ - `src/view.ts`: how it looks (`GameView`), fetched as the page first plays it
55
+ - `src/main.ts`: the page, its scenes made by `appScenes` of the game
51
56
  <!-- @if editor -->
52
57
  - `src/editor.ts`: the map editor's own settings, for `appScenes`
53
58
  <!-- @end -->
@@ -65,6 +70,9 @@ A game made with V12, at its start: a flat field, and a scout to walk it. Select
65
70
  <!-- @if tests -->
66
71
  - `tests/`: the rules tested with no page, `testWorld`
67
72
  <!-- @end -->
73
+ <!-- @if desktop -->
74
+ - `electron/`: the shell around the page, Electron's main process: `config.mjs` (the app's name, its identifier and the updater's address, yours to settle before it is handed out), `app.mjs` (the window, its full screen, what the page may ask), `preload.cjs` (the bridge the page asks through), `files.mjs` (saves, settings and the error log as files), `updates.mjs`, `presentation.m` (the addon that hides the Dock and the menu bar on macOS), `dev.mjs` (`npm run app`) and `package.mjs` (`npm run package`). `src/shell.ts` is all the page asks of it and `src/desktop.ts` what it does with that: over the whole screen with a Windowed setting, saves and settings as files, the game saved as the window closes, an error log, Exit on the start menu, Quit on the pause menu. The updater's address (`UPDATES`) is a placeholder until the docs' A desktop game, offline says what goes there
75
+ <!-- @end -->
68
76
  - `public/` (make it when needed): the game's models (`.glb`, in `public/models/`), sounds and pictures
69
77
  <!-- @if assets -->
70
78
  - `@v12-engine/assets`: shared models to start with (adventurers with their clips, buildings, trees and rocks, props, weapons), served where `public/`'s files are by `assetsPackage()` in `vite.config.ts`; a file of yours at the same path is the one served, and a build copies what the game uses. Whose each file is: its group's `CREDITS.md` in `node_modules/@v12-engine/assets/groups/`
@@ -1,29 +1,28 @@
1
- /** The rules, tested with no page: a world steps here as it does in a page (`@v12-engine/engine/testing`) */
2
- import { checkRules, createWorldFromMap } from '@v12-engine/engine'
3
- import { order, run, testWorld } from '@v12-engine/engine/testing'
1
+ /** The game, tested with no page: a world steps here as it does in a page (`@v12-engine/engine/testing`) */
2
+ import { createWorldFromMap } from '@v12-engine/engine'
3
+ import { run, testWorld } from '@v12-engine/engine/testing'
4
4
  import { describe, expect, it } from 'vitest'
5
- import { mapNamed } from '../src/maps'
6
- import { rules, start, UNIT } from '../src/rules'
5
+ import { game, UNIT } from '../src/game'
7
6
 
8
- describe('the rules', () => {
9
- it('fit together: every id they name is theirs, every effect has a handler (checkRules)', () => {
10
- expect(checkRules(rules).filter((problem) => problem.level === 'error')).toEqual([])
7
+ describe('the game', () => {
8
+ it('fits together: every id it names is its own, every effect has a handler, every map places what it has (check)', async () => {
9
+ expect((await game.check()).filter((problem) => problem.level === 'error')).toEqual([])
11
10
  })
12
11
 
13
- it('give each player with a start a scout, at it', async () => {
14
- const map = mapNamed()
15
- const world = await createWorldFromMap({ map, game: rules, seed: 1 })
16
- start(world, { map })
17
- const scouts = [...world.actors.values()].filter((entity) => entity.def.id === UNIT.scout)
12
+ it('gives each player with a start a scout, at it', async () => {
13
+ const map = await game.loadMap()
14
+ const world = await createWorldFromMap({ map, rules: game.toRules(), seed: 1 })
15
+ await game.toStart()?.(world, { map })
16
+ const scouts = [...world.units.values()].filter((entity) => entity.def.id === UNIT.scout)
18
17
  expect(scouts).toHaveLength(map.players.length)
19
18
  expect(scouts[0].pos.x).toBeCloseTo(map.players[0].start!.x)
20
19
  world.dispose()
21
20
  })
22
21
 
23
- it('send a scout where it is ordered', async () => {
24
- const world = await testWorld(rules)
25
- const scout = world.spawn(UNIT.scout, 1, { x: 10, z: 10 })
26
- order(world, [scout], { type: 'move', point: { x: 30, z: 10 } })
22
+ it('sends a scout where it is ordered', async () => {
23
+ const world = await testWorld(game)
24
+ const scout = world.spawn(UNIT.scout, { at: { x: 10, z: 10 }, owner: 1 })
25
+ scout.order('move', { x: 30, z: 10 })
27
26
  run(world, 20, () => scout.pos.x > 29)
28
27
  expect(scout.pos.x).toBeGreaterThan(29)
29
28
  world.dispose()
@@ -1,79 +1,15 @@
1
- /** The game, whole: its rules and how it looks. What the page plays and the editor makes maps for */
2
- import { defineGame, type GameView, hotView, presetBuffMarker, presetRallyFlag, presetSpellStyles, presetWeather, TILE_LOOKS } from '@v12-engine/client'
3
- import { rules, type Unit } from './rules'
4
-
5
1
  /**
6
- * The look: a unit type is drawn from `parts` (boxes, cylinders, cones, spheres, pyramids) until it has a model, a
7
- * `.glb` in `public/models/` named by `model` (`{ src: 'scout.glb', scale: 1 }`). `color: 'team'` is its side's colour
8
- // @if assets
9
- *
10
- * The shared art has models to start with: `import { characters } from '@v12-engine/assets'` and
11
- * `model: { src: characters.models.knight, scale: 0.6 }` (played with its own clips)
12
- // @end
2
+ * The game whole: its rules (`src/rules.ts`) and its look (`src/view.ts`), fetched as the page first plays it. What the
3
+ * page, the server and the tests take; a server or a test never fetches the look
13
4
  */
14
- export const view: GameView<Unit> = {
15
- scene: {
16
- // trees and scenery in front of the player's own units faded out (`seeThrough`): who for, how, how much
17
- seeThrough: {},
18
- /**
19
- * Looks by name to start a map from: the map editor's Look panel puts one on a map (Preset), a scene plays a map with
20
- * one (`gameScene({ environment: 'dusk' })`), the rules change to one (`world.setEnvironment(view.scene.environments.storm,
21
- * { over: 20 })`). Each is a `MapEnvironment`: sky, light, mist, wind, clouds, weather, water
22
- */
23
- environments: {
24
- dusk: {
25
- sky: [0.55, 0.42, 0.5],
26
- clouds: { cover: 0.4, color: [1, 0.8, 0.7] },
27
- light: { sunUp: 12, sunAround: 250, sunColor: [1, 0.62, 0.42], sun: 1, ambient: 0.45, ambientColor: [0.8, 0.7, 0.9] },
28
- fog: { start: 60, end: 200 },
29
- mist: { ground: { base: 0, top: 2, density: 0.25 } }
30
- },
31
- storm: {
32
- sky: [0.3, 0.33, 0.38],
33
- clouds: { cover: 0.9, color: [0.55, 0.57, 0.6] },
34
- cloudLayer: { height: 18, cover: 0.7, opacity: 0.55, shadows: 0.5 },
35
- light: { sun: 0.7, ambient: 0.5 },
36
- wind: { around: 70, strength: 0.8, gusts: 0.6 },
37
- weather: { kind: 'rain', amount: 0.9, splashes: 0.6 },
38
- fog: { start: 40, end: 140 }
39
- }
40
- },
41
- // the ready-made rain (its map has some), styles of abilities, rally flag and buff glow: the client draws none by itself
42
- weather: presetWeather()
43
- },
44
- fx: {
45
- abilities: {
46
- styles: presetSpellStyles()
47
- }
48
- },
49
- units: {
50
- looks: {
51
- scout: {
52
- height: 1.4,
53
- parts: [
54
- { shape: 'cylinder', size: [0.6, 1, 0.6], offset: [0, 0.5, 0], color: 'team' },
55
- { shape: 'sphere', size: [0.45, 0.45, 0.45], offset: [0, 1.2, 0], color: [0.9, 0.8, 0.65] }
56
- ]
57
- }
58
- },
59
- rallyFlag: presetRallyFlag(),
60
- buffMarker: presetBuffMarker()
61
- },
62
- ground: {
63
- /**
64
- * How each tile of the ground (src/tiles.ts) looks: a colour (the minimap's, and the ground's until its picture comes)
65
- * and a picture repeated over the ground. A picture is a file in `public/textures/` by its path there, or made in
66
- * code with no file: `pattern: 'grass'` (grass, gravel, rock, cobbles, planks, ice, lava… fifteen), with a `recipe` (a second
67
- * colour, specks, how strong, and the pattern's own parameters: `params: { seams: 1.2 }`), or a pattern of the
68
- * game's own (`patterns: { cobbles: definePattern({ name, params, shade }) }` on the view, then `pattern: 'cobbles'`;
69
- * the map editor offers it with a slider for each parameter)
70
- */
71
- // the client's looks of the engine's tiles, made in code (no files), and the road as gravel of a colour of its own
72
- tiles: { ...TILE_LOOKS, road: { color: [0.55, 0.52, 0.47], pattern: 'gravel' } }
73
- }
74
- }
5
+ import { game } from './rules'
75
6
 
76
- export const game = defineGame({ rules, view, check: 'throw' })
7
+ // @if !desktop
8
+ game.view(() => import('./view'))
9
+ // @end
10
+ // @if desktop
11
+ // its look with what the desktop app adds to it: a Windowed setting, Quit on the pause menu
12
+ game.view(() => Promise.all([import('./view'), import('./desktop')]).then(([{ view }, { desktopView }]) => desktopView(view)))
13
+ // @end
77
14
 
78
- // saved while it runs (npm run dev): the game and the editor open take its new look, with no new page
79
- if (import.meta.hot) import.meta.hot.accept((module) => hotView(import.meta.hot, rules.id, view, module?.view))
15
+ export { game, UNIT, type Unit } from './rules'
@@ -1,9 +1,9 @@
1
1
  /**
2
- * The page's worker that makes the random map's preview with the game's generator (`rules.generator`), so the menu
3
- * goes on while it is made. Given to the app in `main.ts` (`generatorWorker`)
2
+ * The page's worker that makes the random map's preview with the game's generator (`generator` in `src/rules.ts`), so
3
+ * the menu goes on while it is made. Given to the app in `main.ts` (`generatorWorker`)
4
4
  */
5
- // the rules alone: nothing of the client is loaded into the worker
5
+ // the game's rules alone (`src/rules.ts`, the game with no look given yet): nothing of the client is in the worker
6
6
  import { serveMapGenerator } from '@v12-engine/engine'
7
- import { rules } from './rules'
7
+ import { game } from './rules'
8
8
 
9
- serveMapGenerator(rules)
9
+ serveMapGenerator(game)
@@ -1,31 +1,57 @@
1
1
  /**
2
- * The rules: what there is, and what happens once a game starts. They use the engine alone, so the page, the server
3
- * and the tests all play the same game. Start here: a unit type is an entry of `units`
2
+ * The rules: what there is, its maps, and what happens once a game starts, on the game (`createGame`), the one object
3
+ * the page, the server and the tests take (`src/game.ts` gives it its look). The engine alone
4
+ * (`@v12-engine/engine`), so they all play the same game, and a worker of the page's reads it with nothing of the
5
+ * client (`src/generate.worker.ts`). Start here: a unit type is a `game.unit`
4
6
  */
5
- import { defineIds, type GameMap, type GameModule, hotRules, type IdOf, presetGenerator, type World } from '@v12-engine/engine'
6
- import { maps } from './maps'
7
- import { tiles } from './tiles'
7
+ import { createGame, createMap, defineIds, type GameMap, hotGame, type IdOf, presetGenerator, presetTiles } from '@v12-engine/engine'
8
+ // @if editor
9
+ // import { mapsFrom } from '@v12-engine/engine'
10
+ // import field from './maps/field.vgmap.json'
11
+ // @end
8
12
 
9
13
  /** The ids of the game's unit types, named once: `UNIT.scout` everywhere else */
10
14
  export const UNIT = defineIds('scout')
11
15
  export type Unit = IdOf<typeof UNIT>
12
16
 
13
- export const rules: GameModule = {
17
+ /**
18
+ * What the ground can be painted with: the engine's tiles of an RTS (grass, dark grass, dirt, road, sand, rock, snow),
19
+ * which the map editor's Paint offers and the rules read (`world.registry.tile('road')`). How each looks is the view's
20
+ * (`ground.tiles` in `src/view.ts`). A game's own goes beside them (`defineTile({ id: 'lava', name: 'Lava' })`), its look
21
+ * there; a map keeps its paint by these names, so their order can change
22
+ */
23
+ const tiles = [...presetTiles]
24
+
25
+ /*
26
+ * Heroes, items and their shop, when the game wants them: the engine has a set of each to take whole or in part
27
+ * (`useDefaults` round what `createGame` is given), each a choice of its own, all of it turned off by leaving it out:
28
+ *
29
+ * import { defaultCallingSet, defaultHeroSpellSet, defaultItemSet, heroesPack, useDefaults } from '@v12-engine/engine'
30
+ * export const game = createGame(
31
+ * useDefaults({ id: 'my-game', name: 'My game', units: [], packs: [heroesPack()], resources: [{ id: 'gold', name: 'Gold' }], currency: 'gold' }, [defaultItemSet, defaultHeroSpellSet(), defaultCallingSet()], {
32
+ * items: { except: ['bloodreaver'] }, // the item tree but some, or { only: [...] }, { with: [...my own] }, { change: {...} }
33
+ * heroSpells: { only: ['flash', 'barrier'] }
34
+ * })
35
+ * )
36
+ *
37
+ * - the items (`defaultItemSet`, priced in gold): about fifty in a build tree, with their tags (the shop's search and filters,
38
+ * `Rules.tags`) and the callings they suit; a unit sells them with `sells`, and `settings: { shop: { undo: 10 } }`
39
+ * says how long a purchase can be taken back
40
+ * - the hero spells (`defaultHeroSpellSet()`): Flash, Barrier and the rest, two a hero (`hero.spells`, keys D and F)
41
+ * - the callings (`defaultCallingSet()`): what a hero is good at (`hero.callings: { vanguard: 3 }`), which the shop
42
+ * suggests by; a hero's innate passive is `hero.innate`
43
+ * - the heroes pack (`heroesPack({ assistTime, shutdownGold, buybackCost, ... })`): heroes' levels, assists, kill streaks
44
+ * and buyback, each a rule of its own to change or turn off
45
+ *
46
+ * How their attacks look (several clips in turn, `UnitLook.attacks`) and how hits feel (`GameView.feel`) are the view's:
47
+ * `src/view.ts`
48
+ */
49
+ export const game = createGame({
14
50
  // the maps of this game say they are its own by this id: change it, and change theirs (`"game"`) with it
15
51
  id: 'my-game',
16
52
  name: 'My game',
17
- units: [
18
- {
19
- id: UNIT.scout,
20
- name: 'Scout',
21
- kind: 'unit',
22
- radius: 0.4,
23
- // no attack yet: give it `attackDamage`, `attackSpeed`, `attackRange` here and an attack in its `attacks`, and it fights
24
- stats: { health: 100, moveSpeed: 5 },
25
- sight: 10
26
- }
27
- ],
28
- // what the ground is painted with (src/tiles.ts)
53
+ // a view that names what the rules do not have (a look for no unit type) stops the page, saying what was meant
54
+ checkView: 'throw',
29
55
  tiles,
30
56
  // @if assets
31
57
  /**
@@ -47,21 +73,53 @@ export const rules: GameModule = {
47
73
  */
48
74
  generator: presetGenerator(),
49
75
  // @end
50
- // the maps the game ships: a save of a game on one of them keeps only what changed of its ground
51
- maps: Object.values(maps),
52
76
  // nobody wins or loses yet. `coreVictory` (the last side with something wins) or a system of your own decides it
53
77
  victory: null
78
+ })
79
+
80
+ game.unit({
81
+ id: UNIT.scout,
82
+ name: 'Scout',
83
+ kind: 'unit',
84
+ radius: 0.4,
85
+ // no attack yet: give it `attackDamage`, `attackSpeed`, `attackRange` here and an attack in its `attacks`, and it fights
86
+ stats: { health: 100, moveSpeed: 5 },
87
+ sight: 10
88
+ })
89
+
90
+ /**
91
+ * The maps of the game. There is one, made here in code: a flat field of 32 cells a side, a player with a start in its
92
+ * middle, and a road across it.
93
+ // @if editor
94
+ * The map editor (`npm run dev`, then `/?editor`) opens it, and Save writes it into `src/maps/field.vgmap.json`. From
95
+ * then on the file is the map: give it here in its place, as the lines below say, and `flatField` can go
96
+ // @end
97
+ */
98
+ function flatField(): GameMap {
99
+ const map = createMap({ name: 'Field', width: 32, depth: 32, players: 1, game: 'my-game', tileset: tiles.map((tile) => tile.id) })
100
+ map.players[0].start = { x: 16, z: 16 }
101
+ // a cell's paint is the place of its tile in the map's tileset, from 1 (0 is none: the ground's own colour)
102
+ const road = map.tileset.indexOf('road') + 1
103
+ for (let z = 20; z < 22; z++) for (let x = 0; x < map.width; x++) map.tiles[z * map.width + x] = road
104
+ return map
54
105
  }
55
106
 
107
+ // the maps by name, the first the one a game is on when nothing says which (and the one a map editor opens first). The
108
+ // maps the game ships: a save of a game on one of them keeps only what changed of its ground
109
+ // @if editor
110
+ // once the editor has saved the field: game.maps(mapsFrom({ './maps/field.vgmap.json': field }))
111
+ // @end
112
+ game.maps({ field: flatField() })
113
+
56
114
  /**
57
115
  * What the game does once a world is made from a map, before anyone plays: a scout for each player with a start, at
58
- * it. The page, the server and the editor's Play here each call it with the map
116
+ * it. The page, the server and the editor's Play here each run it with the map
59
117
  */
60
- export function start(world: World, { map }: { map?: GameMap }): void {
118
+ game.onStart((world, { map }) => {
61
119
  for (const player of map?.players ?? []) {
62
- if (player.start) world.spawn(UNIT.scout, player.id, player.start)
120
+ if (player.start) world.spawn(UNIT.scout, { at: player.start, owner: player.id })
63
121
  }
64
- }
122
+ })
65
123
 
66
124
  // saved while it runs (npm run dev): the game and the editor open take the new version, with no new page
67
- if (import.meta.hot) import.meta.hot.accept((module) => hotRules(import.meta.hot, rules, module?.rules))
125
+ if (import.meta.hot) import.meta.hot.accept((module) => hotGame(import.meta.hot, game, module?.game))