@origingame/create-game 0.0.0-stage → 0.1.1

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 (590) hide show
  1. package/README.md +57 -2
  2. package/archetypes/README.md +99 -0
  3. package/archetypes/idle/.origin/setup +14 -0
  4. package/archetypes/idle/LICENSES.md +12 -0
  5. package/archetypes/idle/README.md +234 -0
  6. package/archetypes/idle/assets/audio/buy.wav +0 -0
  7. package/archetypes/idle/assets/audio/milestone.wav +0 -0
  8. package/archetypes/idle/assets/audio/nova.wav +0 -0
  9. package/archetypes/idle/assets/audio/orbit.wav +0 -0
  10. package/archetypes/idle/assets/audio/tap.wav +0 -0
  11. package/archetypes/idle/assets/audio/ui-close.ogt +9 -0
  12. package/archetypes/idle/assets/audio/ui-error.ogt +9 -0
  13. package/archetypes/idle/assets/audio/ui-open.ogt +9 -0
  14. package/archetypes/idle/assets/audio/ui-press.ogt +9 -0
  15. package/archetypes/idle/assets/audio/ui-success.ogt +9 -0
  16. package/archetypes/idle/assets/fonts/NotoSansSC-subset.ttf +0 -0
  17. package/archetypes/idle/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
  18. package/archetypes/idle/assets/fonts/OFL.txt +93 -0
  19. package/archetypes/idle/assets/fx/drift.ogt +21 -0
  20. package/archetypes/idle/assets/fx/milestone.ogt +21 -0
  21. package/archetypes/idle/assets/fx/nova.ogt +22 -0
  22. package/archetypes/idle/assets/fx/stars.ogt +20 -0
  23. package/archetypes/idle/assets/fx/tap.ogt +23 -0
  24. package/archetypes/idle/assets/looks/idle.ogt +17 -0
  25. package/archetypes/idle/assets/skins/sparkorb/ChakraPetch-BoldItalic.ttf +0 -0
  26. package/archetypes/idle/assets/skins/sparkorb/ChakraPetch-BoldItalic.ttf.ogt +9 -0
  27. package/archetypes/idle/assets/skins/sparkorb/LICENSES.md +19 -0
  28. package/archetypes/idle/assets/skins/sparkorb/OFL.txt +95 -0
  29. package/archetypes/idle/assets/skins/sparkorb/Orbitron-Medium.ttf +0 -0
  30. package/archetypes/idle/assets/skins/sparkorb/Orbitron-Medium.ttf.ogt +9 -0
  31. package/archetypes/idle/assets/skins/sparkorb/Rajdhani-Bold.ttf +0 -0
  32. package/archetypes/idle/assets/skins/sparkorb/Rajdhani-Bold.ttf.ogt +9 -0
  33. package/archetypes/idle/assets/skins/sparkorb/atlas.png +0 -0
  34. package/archetypes/idle/assets/skins/sparkorb/atlas.png.ogt +7 -0
  35. package/archetypes/idle/assets/skins/sparkorb/icons.png +0 -0
  36. package/archetypes/idle/assets/skins/sparkorb/icons.png.ogt +7 -0
  37. package/archetypes/idle/assets/skins/sparkorb/skin.ogt +113 -0
  38. package/archetypes/idle/assets/sprites/glow.png +0 -0
  39. package/archetypes/idle/assets/sprites/glow.png.ogt +8 -0
  40. package/archetypes/idle/assets/sprites/mote-crystal.png +0 -0
  41. package/archetypes/idle/assets/sprites/mote-crystal.png.ogt +7 -0
  42. package/archetypes/idle/assets/sprites/mote-ember.png +0 -0
  43. package/archetypes/idle/assets/sprites/mote-ember.png.ogt +7 -0
  44. package/archetypes/idle/assets/sprites/mote-star.png +0 -0
  45. package/archetypes/idle/assets/sprites/mote-star.png.ogt +7 -0
  46. package/archetypes/idle/assets/sprites/mote-storm.png +0 -0
  47. package/archetypes/idle/assets/sprites/mote-storm.png.ogt +7 -0
  48. package/archetypes/idle/assets/sprites/orb.png +0 -0
  49. package/archetypes/idle/assets/sprites/orb.png.ogt +7 -0
  50. package/archetypes/idle/assets/sprites/spark.png +0 -0
  51. package/archetypes/idle/assets/sprites/spark.png.ogt +7 -0
  52. package/archetypes/idle/assets/strings/en.ogt +62 -0
  53. package/archetypes/idle/assets/strings/zh-CN.ogt +62 -0
  54. package/archetypes/idle/gitattributes +22 -0
  55. package/archetypes/idle/gitignore +8 -0
  56. package/archetypes/idle/host.d.ts +46 -0
  57. package/archetypes/idle/package.json +18 -0
  58. package/archetypes/idle/project.ogt +14 -0
  59. package/archetypes/idle/references/metal/card.png +0 -0
  60. package/archetypes/idle/references/metal/orbit.png +0 -0
  61. package/archetypes/idle/references/metal/title.png +0 -0
  62. package/archetypes/idle/src/components.ts +139 -0
  63. package/archetypes/idle/src/main.ts +247 -0
  64. package/archetypes/idle/src/numbers.ts +126 -0
  65. package/archetypes/idle/src/systems.ts +340 -0
  66. package/archetypes/idle/src/ui.ts +412 -0
  67. package/archetypes/idle/tests/away.og.ts +42 -0
  68. package/archetypes/idle/tests/flow.og.ts +57 -0
  69. package/archetypes/idle/tests/frames.og.ts +33 -0
  70. package/archetypes/idle/tests/frames.ts +134 -0
  71. package/archetypes/idle/tests/lib.ts +74 -0
  72. package/archetypes/idle/tests/milestone.og.ts +32 -0
  73. package/archetypes/idle/tests/nova.og.ts +52 -0
  74. package/archetypes/idle/tests/offline.og.ts +60 -0
  75. package/archetypes/idle/tests/pad.og.ts +55 -0
  76. package/archetypes/idle/tests/pause.og.ts +68 -0
  77. package/archetypes/idle/tests/phone.og.ts +50 -0
  78. package/archetypes/idle/tests/replay.og.ts +28 -0
  79. package/archetypes/idle/tools/make-assets.py +448 -0
  80. package/archetypes/idle/tools/oglite.py +285 -0
  81. package/archetypes/idle/tsconfig.json +17 -0
  82. package/archetypes/match3/.origin/setup +14 -0
  83. package/archetypes/match3/LICENSES.md +7 -0
  84. package/archetypes/match3/README.md +205 -0
  85. package/archetypes/match3/assets/audio/cascade.wav +0 -0
  86. package/archetypes/match3/assets/audio/clear.wav +0 -0
  87. package/archetypes/match3/assets/audio/lost.wav +0 -0
  88. package/archetypes/match3/assets/audio/refused.wav +0 -0
  89. package/archetypes/match3/assets/audio/select.wav +0 -0
  90. package/archetypes/match3/assets/audio/swap.wav +0 -0
  91. package/archetypes/match3/assets/audio/won.wav +0 -0
  92. package/archetypes/match3/assets/fonts/OFL.txt +93 -0
  93. package/archetypes/match3/assets/fonts/ui.ttf +0 -0
  94. package/archetypes/match3/assets/fonts/ui.ttf.ogt +11 -0
  95. package/archetypes/match3/assets/scenes/main.ogt +24 -0
  96. package/archetypes/match3/assets/sprites/backdrop.png +0 -0
  97. package/archetypes/match3/assets/sprites/board.ogt +21 -0
  98. package/archetypes/match3/assets/sprites/cells.ogt +7 -0
  99. package/archetypes/match3/assets/sprites/cells.png +0 -0
  100. package/archetypes/match3/assets/sprites/cells.png.ogt +7 -0
  101. package/archetypes/match3/assets/sprites/gems.ogt +75 -0
  102. package/archetypes/match3/assets/sprites/gems.png +0 -0
  103. package/archetypes/match3/assets/sprites/panel.png +0 -0
  104. package/archetypes/match3/assets/sprites/ring.png +0 -0
  105. package/archetypes/match3/gitattributes +22 -0
  106. package/archetypes/match3/gitignore +8 -0
  107. package/archetypes/match3/host.d.ts +46 -0
  108. package/archetypes/match3/package.json +18 -0
  109. package/archetypes/match3/project.ogt +18 -0
  110. package/archetypes/match3/references/metal/cascade.png +0 -0
  111. package/archetypes/match3/references/metal/clearing.png +0 -0
  112. package/archetypes/match3/references/metal/dealt.png +0 -0
  113. package/archetypes/match3/src/art.ts +54 -0
  114. package/archetypes/match3/src/board.ts +112 -0
  115. package/archetypes/match3/src/components.ts +95 -0
  116. package/archetypes/match3/src/layout.ts +25 -0
  117. package/archetypes/match3/src/main.ts +199 -0
  118. package/archetypes/match3/src/systems.ts +631 -0
  119. package/archetypes/match3/tests/drag.og.ts +31 -0
  120. package/archetypes/match3/tests/endings.og.ts +40 -0
  121. package/archetypes/match3/tests/frames.og.ts +49 -0
  122. package/archetypes/match3/tests/frames.ts +134 -0
  123. package/archetypes/match3/tests/hidpi.og.ts +41 -0
  124. package/archetypes/match3/tests/lib.ts +64 -0
  125. package/archetypes/match3/tests/replay.og.ts +28 -0
  126. package/archetypes/match3/tests/sounds.og.ts +50 -0
  127. package/archetypes/match3/tests/swap.og.ts +67 -0
  128. package/archetypes/match3/tools/make-assets.py +404 -0
  129. package/archetypes/match3/tools/oglite.py +285 -0
  130. package/archetypes/match3/tsconfig.json +17 -0
  131. package/archetypes/rhythm/.origin/setup +14 -0
  132. package/archetypes/rhythm/LICENSES.md +13 -0
  133. package/archetypes/rhythm/README.md +235 -0
  134. package/archetypes/rhythm/assets/audio/bass0.wav +0 -0
  135. package/archetypes/rhythm/assets/audio/bass1.wav +0 -0
  136. package/archetypes/rhythm/assets/audio/bass2.wav +0 -0
  137. package/archetypes/rhythm/assets/audio/bass3.wav +0 -0
  138. package/archetypes/rhythm/assets/audio/chords0.wav +0 -0
  139. package/archetypes/rhythm/assets/audio/chords1.wav +0 -0
  140. package/archetypes/rhythm/assets/audio/chords2.wav +0 -0
  141. package/archetypes/rhythm/assets/audio/chords3.wav +0 -0
  142. package/archetypes/rhythm/assets/audio/clear.wav +0 -0
  143. package/archetypes/rhythm/assets/audio/click.wav +0 -0
  144. package/archetypes/rhythm/assets/audio/drums.wav +0 -0
  145. package/archetypes/rhythm/assets/audio/fail.wav +0 -0
  146. package/archetypes/rhythm/assets/audio/leadA.wav +0 -0
  147. package/archetypes/rhythm/assets/audio/leadB.wav +0 -0
  148. package/archetypes/rhythm/assets/audio/miss.wav +0 -0
  149. package/archetypes/rhythm/assets/audio/tap0.wav +0 -0
  150. package/archetypes/rhythm/assets/audio/tap1.wav +0 -0
  151. package/archetypes/rhythm/assets/audio/tap2.wav +0 -0
  152. package/archetypes/rhythm/assets/audio/ui-close.ogt +9 -0
  153. package/archetypes/rhythm/assets/audio/ui-error.ogt +9 -0
  154. package/archetypes/rhythm/assets/audio/ui-open.ogt +9 -0
  155. package/archetypes/rhythm/assets/audio/ui-press.ogt +9 -0
  156. package/archetypes/rhythm/assets/audio/ui-success.ogt +9 -0
  157. package/archetypes/rhythm/assets/charts/neon-pulse.ogt +919 -0
  158. package/archetypes/rhythm/assets/fonts/NotoSansSC-subset.ttf +0 -0
  159. package/archetypes/rhythm/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
  160. package/archetypes/rhythm/assets/fonts/OFL.txt +93 -0
  161. package/archetypes/rhythm/assets/fx/hit.ogt +22 -0
  162. package/archetypes/rhythm/assets/skins/lanebeat/ChakraPetch-Medium.ttf +0 -0
  163. package/archetypes/rhythm/assets/skins/lanebeat/ChakraPetch-Medium.ttf.ogt +9 -0
  164. package/archetypes/rhythm/assets/skins/lanebeat/JetBrainsMono-Regular.ttf +0 -0
  165. package/archetypes/rhythm/assets/skins/lanebeat/JetBrainsMono-Regular.ttf.ogt +9 -0
  166. package/archetypes/rhythm/assets/skins/lanebeat/LICENSES.md +17 -0
  167. package/archetypes/rhythm/assets/skins/lanebeat/OFL.txt +95 -0
  168. package/archetypes/rhythm/assets/skins/lanebeat/Orbitron-Bold.ttf +0 -0
  169. package/archetypes/rhythm/assets/skins/lanebeat/Orbitron-Bold.ttf.ogt +9 -0
  170. package/archetypes/rhythm/assets/skins/lanebeat/atlas.png +0 -0
  171. package/archetypes/rhythm/assets/skins/lanebeat/atlas.png.ogt +7 -0
  172. package/archetypes/rhythm/assets/skins/lanebeat/icons.png +0 -0
  173. package/archetypes/rhythm/assets/skins/lanebeat/icons.png.ogt +7 -0
  174. package/archetypes/rhythm/assets/skins/lanebeat/skin.ogt +110 -0
  175. package/archetypes/rhythm/assets/sprites/lane.png +0 -0
  176. package/archetypes/rhythm/assets/sprites/lane.png.ogt +7 -0
  177. package/archetypes/rhythm/assets/sprites/note.png +0 -0
  178. package/archetypes/rhythm/assets/sprites/note.png.ogt +7 -0
  179. package/archetypes/rhythm/assets/sprites/ring.png +0 -0
  180. package/archetypes/rhythm/assets/sprites/ring.png.ogt +7 -0
  181. package/archetypes/rhythm/assets/sprites/spark.png +0 -0
  182. package/archetypes/rhythm/assets/sprites/spark.png.ogt +7 -0
  183. package/archetypes/rhythm/assets/strings/en.ogt +61 -0
  184. package/archetypes/rhythm/assets/strings/zh-CN.ogt +61 -0
  185. package/archetypes/rhythm/gitattributes +22 -0
  186. package/archetypes/rhythm/gitignore +8 -0
  187. package/archetypes/rhythm/host.d.ts +46 -0
  188. package/archetypes/rhythm/package.json +18 -0
  189. package/archetypes/rhythm/project.ogt +14 -0
  190. package/archetypes/rhythm/references/metal/highway.png +0 -0
  191. package/archetypes/rhythm/references/metal/results.png +0 -0
  192. package/archetypes/rhythm/references/metal/title.png +0 -0
  193. package/archetypes/rhythm/src/components.ts +147 -0
  194. package/archetypes/rhythm/src/main.ts +202 -0
  195. package/archetypes/rhythm/src/systems.ts +490 -0
  196. package/archetypes/rhythm/src/ui.ts +421 -0
  197. package/archetypes/rhythm/tests/band.og.ts +45 -0
  198. package/archetypes/rhythm/tests/calibrate.og.ts +49 -0
  199. package/archetypes/rhythm/tests/clear.og.ts +51 -0
  200. package/archetypes/rhythm/tests/fail.og.ts +40 -0
  201. package/archetypes/rhythm/tests/flow.og.ts +54 -0
  202. package/archetypes/rhythm/tests/frames.og.ts +35 -0
  203. package/archetypes/rhythm/tests/frames.ts +134 -0
  204. package/archetypes/rhythm/tests/lib.ts +123 -0
  205. package/archetypes/rhythm/tests/pad.og.ts +41 -0
  206. package/archetypes/rhythm/tests/pause.og.ts +77 -0
  207. package/archetypes/rhythm/tests/phone.og.ts +44 -0
  208. package/archetypes/rhythm/tests/replay.og.ts +27 -0
  209. package/archetypes/rhythm/tests/timing.og.ts +37 -0
  210. package/archetypes/rhythm/tools/make-assets.py +383 -0
  211. package/archetypes/rhythm/tools/oglite.py +285 -0
  212. package/archetypes/rhythm/tsconfig.json +17 -0
  213. package/archetypes/roguelike/.origin/setup +14 -0
  214. package/archetypes/roguelike/LICENSES.md +14 -0
  215. package/archetypes/roguelike/README.md +256 -0
  216. package/archetypes/roguelike/assets/ai/foe.ogt +28 -0
  217. package/archetypes/roguelike/assets/ai/guardian.ogt +26 -0
  218. package/archetypes/roguelike/assets/audio/bump.wav +0 -0
  219. package/archetypes/roguelike/assets/audio/drink.wav +0 -0
  220. package/archetypes/roguelike/assets/audio/fall.wav +0 -0
  221. package/archetypes/roguelike/assets/audio/hit.wav +0 -0
  222. package/archetypes/roguelike/assets/audio/hurt.wav +0 -0
  223. package/archetypes/roguelike/assets/audio/item.wav +0 -0
  224. package/archetypes/roguelike/assets/audio/kill.wav +0 -0
  225. package/archetypes/roguelike/assets/audio/pickup.wav +0 -0
  226. package/archetypes/roguelike/assets/audio/roar.wav +0 -0
  227. package/archetypes/roguelike/assets/audio/stairs.wav +0 -0
  228. package/archetypes/roguelike/assets/audio/step.ogt +9 -0
  229. package/archetypes/roguelike/assets/audio/telegraph.wav +0 -0
  230. package/archetypes/roguelike/assets/audio/tomb.wav +0 -0
  231. package/archetypes/roguelike/assets/audio/ui-close.ogt +9 -0
  232. package/archetypes/roguelike/assets/audio/ui-error.ogt +9 -0
  233. package/archetypes/roguelike/assets/audio/ui-open.ogt +9 -0
  234. package/archetypes/roguelike/assets/audio/ui-press.ogt +9 -0
  235. package/archetypes/roguelike/assets/audio/ui-success.ogt +9 -0
  236. package/archetypes/roguelike/assets/audio/won.wav +0 -0
  237. package/archetypes/roguelike/assets/fonts/NotoSansSC-subset.ttf +0 -0
  238. package/archetypes/roguelike/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
  239. package/archetypes/roguelike/assets/fonts/OFL.txt +93 -0
  240. package/archetypes/roguelike/assets/maps/dive.ogt +106 -0
  241. package/archetypes/roguelike/assets/skins/lampdive/DotGothic16-Regular.ttf +0 -0
  242. package/archetypes/roguelike/assets/skins/lampdive/DotGothic16-Regular.ttf.ogt +9 -0
  243. package/archetypes/roguelike/assets/skins/lampdive/LICENSES.md +16 -0
  244. package/archetypes/roguelike/assets/skins/lampdive/OFL.txt +93 -0
  245. package/archetypes/roguelike/assets/skins/lampdive/atlas.png +0 -0
  246. package/archetypes/roguelike/assets/skins/lampdive/atlas.png.ogt +7 -0
  247. package/archetypes/roguelike/assets/skins/lampdive/icons.png +0 -0
  248. package/archetypes/roguelike/assets/skins/lampdive/icons.png.ogt +7 -0
  249. package/archetypes/roguelike/assets/skins/lampdive/skin.ogt +115 -0
  250. package/archetypes/roguelike/assets/sprites/dive.ogt +50 -0
  251. package/archetypes/roguelike/assets/sprites/dive.png +0 -0
  252. package/archetypes/roguelike/assets/sprites/dive.png.ogt +7 -0
  253. package/archetypes/roguelike/assets/sprites/glow.png +0 -0
  254. package/archetypes/roguelike/assets/sprites/glow.png.ogt +7 -0
  255. package/archetypes/roguelike/assets/strings/en.ogt +57 -0
  256. package/archetypes/roguelike/assets/strings/zh-CN.ogt +57 -0
  257. package/archetypes/roguelike/assets/tiles/tomb.ogt +31 -0
  258. package/archetypes/roguelike/assets/tiles/tomb.png +0 -0
  259. package/archetypes/roguelike/assets/tiles/tomb.png.ogt +7 -0
  260. package/archetypes/roguelike/gitattributes +22 -0
  261. package/archetypes/roguelike/gitignore +8 -0
  262. package/archetypes/roguelike/host.d.ts +46 -0
  263. package/archetypes/roguelike/package.json +18 -0
  264. package/archetypes/roguelike/project.ogt +14 -0
  265. package/archetypes/roguelike/references/metal/dive.png +0 -0
  266. package/archetypes/roguelike/references/metal/over.png +0 -0
  267. package/archetypes/roguelike/references/metal/title.png +0 -0
  268. package/archetypes/roguelike/src/art.ts +23 -0
  269. package/archetypes/roguelike/src/components.ts +169 -0
  270. package/archetypes/roguelike/src/dive.ts +144 -0
  271. package/archetypes/roguelike/src/foes.ts +174 -0
  272. package/archetypes/roguelike/src/main.ts +258 -0
  273. package/archetypes/roguelike/src/systems.ts +620 -0
  274. package/archetypes/roguelike/src/ui.ts +350 -0
  275. package/archetypes/roguelike/tests/flow.og.ts +54 -0
  276. package/archetypes/roguelike/tests/foes.og.ts +45 -0
  277. package/archetypes/roguelike/tests/frames.og.ts +32 -0
  278. package/archetypes/roguelike/tests/frames.ts +134 -0
  279. package/archetypes/roguelike/tests/lib.ts +83 -0
  280. package/archetypes/roguelike/tests/lose.og.ts +44 -0
  281. package/archetypes/roguelike/tests/pad.og.ts +54 -0
  282. package/archetypes/roguelike/tests/pause.og.ts +59 -0
  283. package/archetypes/roguelike/tests/phone.og.ts +54 -0
  284. package/archetypes/roguelike/tests/replay.og.ts +24 -0
  285. package/archetypes/roguelike/tests/win.og.ts +60 -0
  286. package/archetypes/roguelike/tools/make-assets.py +518 -0
  287. package/archetypes/roguelike/tools/oglite.py +285 -0
  288. package/archetypes/roguelike/tsconfig.json +17 -0
  289. package/archetypes/runner/.origin/setup +14 -0
  290. package/archetypes/runner/LICENSES.md +10 -0
  291. package/archetypes/runner/README.md +225 -0
  292. package/archetypes/runner/assets/audio/coin.wav +0 -0
  293. package/archetypes/runner/assets/audio/crash.wav +0 -0
  294. package/archetypes/runner/assets/audio/hold.ogt +9 -0
  295. package/archetypes/runner/assets/audio/jump.wav +0 -0
  296. package/archetypes/runner/assets/audio/start.wav +0 -0
  297. package/archetypes/runner/assets/fonts/OFL.txt +93 -0
  298. package/archetypes/runner/assets/fonts/ui.ttf +0 -0
  299. package/archetypes/runner/assets/fonts/ui.ttf.ogt +11 -0
  300. package/archetypes/runner/assets/maps/far.ogt +25 -0
  301. package/archetypes/runner/assets/maps/near.ogt +25 -0
  302. package/archetypes/runner/assets/maps/roofs.ogt +19 -0
  303. package/archetypes/runner/assets/scenes/main.ogt +35 -0
  304. package/archetypes/runner/assets/sprites/coin.ogt +11 -0
  305. package/archetypes/runner/assets/sprites/coin.png +0 -0
  306. package/archetypes/runner/assets/sprites/coin.png.ogt +7 -0
  307. package/archetypes/runner/assets/sprites/courier.ogt +32 -0
  308. package/archetypes/runner/assets/sprites/courier.png +0 -0
  309. package/archetypes/runner/assets/sprites/courier.png.ogt +7 -0
  310. package/archetypes/runner/assets/sprites/props.ogt +21 -0
  311. package/archetypes/runner/assets/sprites/props.png +0 -0
  312. package/archetypes/runner/assets/sprites/props.png.ogt +7 -0
  313. package/archetypes/runner/assets/sprites/sky.png +0 -0
  314. package/archetypes/runner/assets/sprites/sky.png.ogt +7 -0
  315. package/archetypes/runner/assets/tiles/city.ogt +18 -0
  316. package/archetypes/runner/assets/tiles/city.png +0 -0
  317. package/archetypes/runner/assets/tiles/city.png.ogt +7 -0
  318. package/archetypes/runner/gitattributes +22 -0
  319. package/archetypes/runner/gitignore +8 -0
  320. package/archetypes/runner/host.d.ts +46 -0
  321. package/archetypes/runner/package.json +18 -0
  322. package/archetypes/runner/project.ogt +18 -0
  323. package/archetypes/runner/references/metal/frames-coin.png +0 -0
  324. package/archetypes/runner/references/metal/frames-crash.png +0 -0
  325. package/archetypes/runner/references/metal/frames-title.png +0 -0
  326. package/archetypes/runner/src/art.ts +57 -0
  327. package/archetypes/runner/src/components.ts +94 -0
  328. package/archetypes/runner/src/main.ts +241 -0
  329. package/archetypes/runner/src/systems.ts +553 -0
  330. package/archetypes/runner/tests/coins.og.ts +30 -0
  331. package/archetypes/runner/tests/flow.og.ts +72 -0
  332. package/archetypes/runner/tests/frames.og.ts +37 -0
  333. package/archetypes/runner/tests/frames.ts +134 -0
  334. package/archetypes/runner/tests/jump.og.ts +44 -0
  335. package/archetypes/runner/tests/lib.ts +42 -0
  336. package/archetypes/runner/tests/records.og.ts +43 -0
  337. package/archetypes/runner/tests/replay.og.ts +36 -0
  338. package/archetypes/runner/tests/sounds.og.ts +43 -0
  339. package/archetypes/runner/tests/tune.og.ts +36 -0
  340. package/archetypes/runner/tools/make-assets.py +603 -0
  341. package/archetypes/runner/tools/oglite.py +285 -0
  342. package/archetypes/runner/tsconfig.json +17 -0
  343. package/archetypes/third-person/.origin/setup +14 -0
  344. package/archetypes/third-person/LICENSES.md +23 -0
  345. package/archetypes/third-person/README.md +249 -0
  346. package/archetypes/third-person/assets/ai/sentinel-east.ogt +69 -0
  347. package/archetypes/third-person/assets/ai/sentinel-north.ogt +69 -0
  348. package/archetypes/third-person/assets/ai/sentinel-west.ogt +69 -0
  349. package/archetypes/third-person/assets/anims/humanoid-clips.glb +0 -0
  350. package/archetypes/third-person/assets/audio/alarm.wav +0 -0
  351. package/archetypes/third-person/assets/audio/dawn.wav +0 -0
  352. package/archetypes/third-person/assets/audio/grab.wav +0 -0
  353. package/archetypes/third-person/assets/audio/ignite.wav +0 -0
  354. package/archetypes/third-person/assets/audio/jump.wav +0 -0
  355. package/archetypes/third-person/assets/audio/night.wav +0 -0
  356. package/archetypes/third-person/assets/audio/splash.wav +0 -0
  357. package/archetypes/third-person/assets/audio/step.ogt +9 -0
  358. package/archetypes/third-person/assets/audio/ui-close.ogt +9 -0
  359. package/archetypes/third-person/assets/audio/ui-error.ogt +9 -0
  360. package/archetypes/third-person/assets/audio/ui-open.ogt +9 -0
  361. package/archetypes/third-person/assets/audio/ui-press.ogt +9 -0
  362. package/archetypes/third-person/assets/audio/ui-success.ogt +9 -0
  363. package/archetypes/third-person/assets/audio/vale.wav +0 -0
  364. package/archetypes/third-person/assets/fonts/NotoSansSC-subset.ttf +0 -0
  365. package/archetypes/third-person/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
  366. package/archetypes/third-person/assets/fonts/OFL.txt +93 -0
  367. package/archetypes/third-person/assets/fx/burst.ogt +25 -0
  368. package/archetypes/third-person/assets/fx/fire.ogt +24 -0
  369. package/archetypes/third-person/assets/fx/smoke.ogt +24 -0
  370. package/archetypes/third-person/assets/fx/splash.ogt +24 -0
  371. package/archetypes/third-person/assets/luts/teal-orange.cube +4917 -0
  372. package/archetypes/third-person/assets/models/stout.glb +0 -0
  373. package/archetypes/third-person/assets/models/strider.glb +0 -0
  374. package/archetypes/third-person/assets/models/strider.glb.ogt +9 -0
  375. package/archetypes/third-person/assets/nav/vale.ogt +43 -0
  376. package/archetypes/third-person/assets/rigs/strider.ogt +6 -0
  377. package/archetypes/third-person/assets/skins/ember/Cinzel-Bold.ttf +0 -0
  378. package/archetypes/third-person/assets/skins/ember/Cinzel-Bold.ttf.ogt +9 -0
  379. package/archetypes/third-person/assets/skins/ember/LICENSES.md +13 -0
  380. package/archetypes/third-person/assets/skins/ember/Newsreader-Medium.ttf +0 -0
  381. package/archetypes/third-person/assets/skins/ember/Newsreader-Medium.ttf.ogt +9 -0
  382. package/archetypes/third-person/assets/skins/ember/OFL.txt +94 -0
  383. package/archetypes/third-person/assets/skins/ember/atlas.png +0 -0
  384. package/archetypes/third-person/assets/skins/ember/atlas.png.ogt +7 -0
  385. package/archetypes/third-person/assets/skins/ember/icons.png +0 -0
  386. package/archetypes/third-person/assets/skins/ember/icons.png.ogt +7 -0
  387. package/archetypes/third-person/assets/skins/ember/skin.ogt +109 -0
  388. package/archetypes/third-person/assets/strings/en.ogt +47 -0
  389. package/archetypes/third-person/assets/strings/zh-CN.ogt +47 -0
  390. package/archetypes/third-person/assets/terrain/vale-control.png +0 -0
  391. package/archetypes/third-person/assets/terrain/vale.ogt +42 -0
  392. package/archetypes/third-person/assets/terrain/vale.png +0 -0
  393. package/archetypes/third-person/assets/textures/decals.png +0 -0
  394. package/archetypes/third-person/assets/textures/flame.png +0 -0
  395. package/archetypes/third-person/assets/textures/smoke.png +0 -0
  396. package/archetypes/third-person/assets/textures/spark.png +0 -0
  397. package/archetypes/third-person/assets/textures/terrain-grass.png +0 -0
  398. package/archetypes/third-person/assets/textures/terrain-path.png +0 -0
  399. package/archetypes/third-person/assets/textures/terrain-rock.png +0 -0
  400. package/archetypes/third-person/assets/textures/terrain-sand.png +0 -0
  401. package/archetypes/third-person/gitattributes +22 -0
  402. package/archetypes/third-person/gitignore +8 -0
  403. package/archetypes/third-person/host.d.ts +46 -0
  404. package/archetypes/third-person/package.json +18 -0
  405. package/archetypes/third-person/project.ogt +14 -0
  406. package/archetypes/third-person/references/metal/beacon.png +0 -0
  407. package/archetypes/third-person/references/metal/dawn.png +0 -0
  408. package/archetypes/third-person/references/metal/title.png +0 -0
  409. package/archetypes/third-person/references/webgl2/beacon.png +0 -0
  410. package/archetypes/third-person/src/anim.ts +87 -0
  411. package/archetypes/third-person/src/beacons.ts +80 -0
  412. package/archetypes/third-person/src/components.ts +148 -0
  413. package/archetypes/third-person/src/hero.ts +293 -0
  414. package/archetypes/third-person/src/main.ts +164 -0
  415. package/archetypes/third-person/src/sentinels.ts +159 -0
  416. package/archetypes/third-person/src/sound.ts +66 -0
  417. package/archetypes/third-person/src/ui.ts +451 -0
  418. package/archetypes/third-person/src/world.ts +212 -0
  419. package/archetypes/third-person/tests/flow.og.ts +70 -0
  420. package/archetypes/third-person/tests/frames.og.ts +35 -0
  421. package/archetypes/third-person/tests/frames.ts +134 -0
  422. package/archetypes/third-person/tests/hitstop.og.ts +26 -0
  423. package/archetypes/third-person/tests/lib.ts +87 -0
  424. package/archetypes/third-person/tests/lose.og.ts +44 -0
  425. package/archetypes/third-person/tests/pause.og.ts +64 -0
  426. package/archetypes/third-person/tests/phone.og.ts +65 -0
  427. package/archetypes/third-person/tests/replay.og.ts +32 -0
  428. package/archetypes/third-person/tests/restart.og.ts +28 -0
  429. package/archetypes/third-person/tests/sentinels.og.ts +48 -0
  430. package/archetypes/third-person/tests/win.og.ts +62 -0
  431. package/archetypes/third-person/tools/make-assets.py +353 -0
  432. package/archetypes/third-person/tools/oglite.py +285 -0
  433. package/archetypes/third-person/tsconfig.json +17 -0
  434. package/archetypes/topdown/.origin/setup +14 -0
  435. package/archetypes/topdown/LICENSES.md +10 -0
  436. package/archetypes/topdown/README.md +235 -0
  437. package/archetypes/topdown/assets/ai/slime.ogt +49 -0
  438. package/archetypes/topdown/assets/audio/coin.wav +0 -0
  439. package/archetypes/topdown/assets/audio/door.wav +0 -0
  440. package/archetypes/topdown/assets/audio/hit.wav +0 -0
  441. package/archetypes/topdown/assets/audio/hurt.wav +0 -0
  442. package/archetypes/topdown/assets/audio/key.wav +0 -0
  443. package/archetypes/topdown/assets/audio/step.ogt +9 -0
  444. package/archetypes/topdown/assets/fonts/OFL.txt +93 -0
  445. package/archetypes/topdown/assets/fonts/ui.ttf +0 -0
  446. package/archetypes/topdown/assets/fonts/ui.ttf.ogt +9 -0
  447. package/archetypes/topdown/assets/maps/tomb.tmj +2183 -0
  448. package/archetypes/topdown/assets/sprites/hero.ogt +58 -0
  449. package/archetypes/topdown/assets/sprites/hero.png +0 -0
  450. package/archetypes/topdown/assets/sprites/hero.png.ogt +7 -0
  451. package/archetypes/topdown/assets/sprites/items.ogt +15 -0
  452. package/archetypes/topdown/assets/sprites/items.png +0 -0
  453. package/archetypes/topdown/assets/sprites/items.png.ogt +7 -0
  454. package/archetypes/topdown/assets/sprites/slime.ogt +17 -0
  455. package/archetypes/topdown/assets/sprites/slime.png +0 -0
  456. package/archetypes/topdown/assets/sprites/slime.png.ogt +7 -0
  457. package/archetypes/topdown/assets/tiles/dungeon.ogt +65 -0
  458. package/archetypes/topdown/assets/tiles/dungeon.png +0 -0
  459. package/archetypes/topdown/assets/tiles/dungeon.png.ogt +7 -0
  460. package/archetypes/topdown/gitattributes +22 -0
  461. package/archetypes/topdown/gitignore +8 -0
  462. package/archetypes/topdown/host.d.ts +46 -0
  463. package/archetypes/topdown/package.json +18 -0
  464. package/archetypes/topdown/project.ogt +14 -0
  465. package/archetypes/topdown/references/metal/crit.png +0 -0
  466. package/archetypes/topdown/references/metal/dash.png +0 -0
  467. package/archetypes/topdown/references/metal/east.png +0 -0
  468. package/archetypes/topdown/references/metal/start.png +0 -0
  469. package/archetypes/topdown/src/art.ts +48 -0
  470. package/archetypes/topdown/src/components.ts +128 -0
  471. package/archetypes/topdown/src/main.ts +275 -0
  472. package/archetypes/topdown/src/systems.ts +503 -0
  473. package/archetypes/topdown/tests/ai.og.ts +64 -0
  474. package/archetypes/topdown/tests/combat.og.ts +72 -0
  475. package/archetypes/topdown/tests/door.og.ts +62 -0
  476. package/archetypes/topdown/tests/flee.og.ts +49 -0
  477. package/archetypes/topdown/tests/frames.og.ts +45 -0
  478. package/archetypes/topdown/tests/frames.ts +134 -0
  479. package/archetypes/topdown/tests/lib.ts +71 -0
  480. package/archetypes/topdown/tests/replay.og.ts +40 -0
  481. package/archetypes/topdown/tests/walk.og.ts +46 -0
  482. package/archetypes/topdown/tools/make-assets.py +623 -0
  483. package/archetypes/topdown/tools/oglite.py +285 -0
  484. package/archetypes/topdown/tsconfig.json +17 -0
  485. package/archetypes/tower-defense/.origin/setup +14 -0
  486. package/archetypes/tower-defense/LICENSES.md +15 -0
  487. package/archetypes/tower-defense/README.md +240 -0
  488. package/archetypes/tower-defense/assets/ai/plant.ogt +16 -0
  489. package/archetypes/tower-defense/assets/audio/clear.wav +0 -0
  490. package/archetypes/tower-defense/assets/audio/frost.wav +0 -0
  491. package/archetypes/tower-defense/assets/audio/leak.wav +0 -0
  492. package/archetypes/tower-defense/assets/audio/lost.wav +0 -0
  493. package/archetypes/tower-defense/assets/audio/night.wav +0 -0
  494. package/archetypes/tower-defense/assets/audio/plant.wav +0 -0
  495. package/archetypes/tower-defense/assets/audio/pop.wav +0 -0
  496. package/archetypes/tower-defense/assets/audio/thorn.wav +0 -0
  497. package/archetypes/tower-defense/assets/audio/ui-close.ogt +9 -0
  498. package/archetypes/tower-defense/assets/audio/ui-error.ogt +9 -0
  499. package/archetypes/tower-defense/assets/audio/ui-open.ogt +9 -0
  500. package/archetypes/tower-defense/assets/audio/ui-press.ogt +9 -0
  501. package/archetypes/tower-defense/assets/audio/ui-success.ogt +9 -0
  502. package/archetypes/tower-defense/assets/audio/wave.wav +0 -0
  503. package/archetypes/tower-defense/assets/audio/won.wav +0 -0
  504. package/archetypes/tower-defense/assets/fonts/NotoSansSC-subset.ttf +0 -0
  505. package/archetypes/tower-defense/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
  506. package/archetypes/tower-defense/assets/fonts/OFL.txt +93 -0
  507. package/archetypes/tower-defense/assets/fx/fireflies.ogt +21 -0
  508. package/archetypes/tower-defense/assets/fx/pop.ogt +21 -0
  509. package/archetypes/tower-defense/assets/maps/garden.ogt +91 -0
  510. package/archetypes/tower-defense/assets/skins/pathguard/Fredoka-SemiBold.ttf +0 -0
  511. package/archetypes/tower-defense/assets/skins/pathguard/Fredoka-SemiBold.ttf.ogt +9 -0
  512. package/archetypes/tower-defense/assets/skins/pathguard/LICENSES.md +13 -0
  513. package/archetypes/tower-defense/assets/skins/pathguard/LilitaOne-Regular.ttf +0 -0
  514. package/archetypes/tower-defense/assets/skins/pathguard/LilitaOne-Regular.ttf.ogt +9 -0
  515. package/archetypes/tower-defense/assets/skins/pathguard/OFL.txt +94 -0
  516. package/archetypes/tower-defense/assets/skins/pathguard/atlas.png +0 -0
  517. package/archetypes/tower-defense/assets/skins/pathguard/atlas.png.ogt +7 -0
  518. package/archetypes/tower-defense/assets/skins/pathguard/icons.png +0 -0
  519. package/archetypes/tower-defense/assets/skins/pathguard/icons.png.ogt +7 -0
  520. package/archetypes/tower-defense/assets/skins/pathguard/skin.ogt +111 -0
  521. package/archetypes/tower-defense/assets/sprites/garden.ogt +66 -0
  522. package/archetypes/tower-defense/assets/sprites/garden.png +0 -0
  523. package/archetypes/tower-defense/assets/sprites/garden.png.ogt +7 -0
  524. package/archetypes/tower-defense/assets/sprites/glow.png +0 -0
  525. package/archetypes/tower-defense/assets/sprites/glow.png.ogt +7 -0
  526. package/archetypes/tower-defense/assets/sprites/ring.png +0 -0
  527. package/archetypes/tower-defense/assets/sprites/ring.png.ogt +7 -0
  528. package/archetypes/tower-defense/assets/sprites/spark.png +0 -0
  529. package/archetypes/tower-defense/assets/sprites/spark.png.ogt +7 -0
  530. package/archetypes/tower-defense/assets/strings/en.ogt +47 -0
  531. package/archetypes/tower-defense/assets/strings/zh-CN.ogt +47 -0
  532. package/archetypes/tower-defense/assets/tiles/garden.ogt +10 -0
  533. package/archetypes/tower-defense/assets/tiles/garden.png +0 -0
  534. package/archetypes/tower-defense/assets/tiles/garden.png.ogt +7 -0
  535. package/archetypes/tower-defense/gitattributes +22 -0
  536. package/archetypes/tower-defense/gitignore +8 -0
  537. package/archetypes/tower-defense/host.d.ts +46 -0
  538. package/archetypes/tower-defense/package.json +18 -0
  539. package/archetypes/tower-defense/project.ogt +14 -0
  540. package/archetypes/tower-defense/references/metal/end.png +0 -0
  541. package/archetypes/tower-defense/references/metal/title.png +0 -0
  542. package/archetypes/tower-defense/references/metal/wave.png +0 -0
  543. package/archetypes/tower-defense/src/art.ts +24 -0
  544. package/archetypes/tower-defense/src/components.ts +156 -0
  545. package/archetypes/tower-defense/src/main.ts +253 -0
  546. package/archetypes/tower-defense/src/systems.ts +658 -0
  547. package/archetypes/tower-defense/src/ui.ts +382 -0
  548. package/archetypes/tower-defense/tests/flow.og.ts +56 -0
  549. package/archetypes/tower-defense/tests/frames.og.ts +31 -0
  550. package/archetypes/tower-defense/tests/frames.ts +134 -0
  551. package/archetypes/tower-defense/tests/lib.ts +81 -0
  552. package/archetypes/tower-defense/tests/lose.og.ts +40 -0
  553. package/archetypes/tower-defense/tests/maze.og.ts +53 -0
  554. package/archetypes/tower-defense/tests/pad.og.ts +41 -0
  555. package/archetypes/tower-defense/tests/pause.og.ts +59 -0
  556. package/archetypes/tower-defense/tests/phone.og.ts +49 -0
  557. package/archetypes/tower-defense/tests/replay.og.ts +28 -0
  558. package/archetypes/tower-defense/tests/win.og.ts +58 -0
  559. package/archetypes/tower-defense/tools/make-assets.py +640 -0
  560. package/archetypes/tower-defense/tools/oglite.py +285 -0
  561. package/archetypes/tower-defense/tsconfig.json +17 -0
  562. package/bin/create.ts +503 -0
  563. package/looks/catalogue.json +1871 -0
  564. package/package.json +31 -4
  565. package/template/.origin/setup +14 -0
  566. package/template/LICENSES.md +23 -0
  567. package/template/README.md +37 -0
  568. package/template/assets/ai/guard.ogt +48 -0
  569. package/template/assets/audio/blip.wav +0 -0
  570. package/template/assets/audio/click.ogt +9 -0
  571. package/template/assets/fonts/NotoSansSC-Regular-subset.ttf +0 -0
  572. package/template/assets/fonts/NotoSansSC-Regular-subset.ttf.ogt +12 -0
  573. package/template/assets/fonts/OFL.txt +93 -0
  574. package/template/assets/looks/origin-game.ogt +12 -0
  575. package/template/assets/models/dropship.glb +0 -0
  576. package/template/assets/models/walker.glb +0 -0
  577. package/template/assets/nav/yard.ogt +27 -0
  578. package/template/assets/scenes/main.ogt +34 -0
  579. package/template/assets/strings/en.ogt +14 -0
  580. package/template/assets/textures/stone.png +0 -0
  581. package/template/assets/textures/stone_n.png +0 -0
  582. package/template/assets/textures/stone_n.png.ogt +7 -0
  583. package/template/gitattributes +22 -0
  584. package/template/gitignore +8 -0
  585. package/template/package.json +18 -0
  586. package/template/project.ogt +25 -0
  587. package/template/src/main.ts +246 -0
  588. package/template/tests/guard.og.ts +67 -0
  589. package/template/tests/smoke.og.ts +43 -0
  590. package/template/tsconfig.json +17 -0
@@ -0,0 +1,640 @@
1
+ #!/usr/bin/env python3
2
+ """Regenerates Path Guard's self-made assets (CC0), byte for byte:
3
+
4
+ python3 tools/make-assets.py # from the archetype directory
5
+
6
+ - assets/tiles/garden.png + garden.ogt: the night garden's 32 px tileset
7
+ (two grasses, the hedge, a stone, the gate, the doorstep, a tower pad,
8
+ a flower), drawn with antialiased shapes,
9
+ - assets/maps/garden.ogt: the 9 x 13 field (ground, the hedges and stones
10
+ that block, the pads layer the towers fill at run time),
11
+ - assets/sprites/garden.png + garden.ogt: the flipbook sheet (three
12
+ visitors, three plants, the lantern, the shots, the cursor) and
13
+ assets/sprites/ring.png (a tower's range) and spark.png (particles),
14
+ - assets/audio/*.wav: the plant, the shots, the pop, the leak, the waves,
15
+ the win and the loss, and the night's music loop,
16
+ - assets/fonts/NotoSansSC-subset.ttf + .ogt: Noto Sans SC subset to the
17
+ characters of assets/strings/zh-CN.ogt (needs fontTools and the project
18
+ template's font; skipped with a note when either is missing).
19
+
20
+ Standard library only except the font subset; deterministic.
21
+ """
22
+ import math, os, re, sys
23
+
24
+ here = os.path.dirname(os.path.abspath(__file__))
25
+ sys.path.insert(0, here)
26
+ from oglite import Canvas, png_bytes, write_wav, tone, noise, mix, concat, subset_font # noqa: E402
27
+
28
+ root = os.path.dirname(here)
29
+ assets = os.path.join(root, "assets")
30
+ T = 32 # pixels per tile and per sprite frame
31
+
32
+ INK = "#0d1a14"
33
+
34
+
35
+ def write(path, data):
36
+ path = os.path.join(assets, path)
37
+ os.makedirs(os.path.dirname(path), exist_ok=True)
38
+ with open(path, "wb" if isinstance(data, bytes) else "w") as f:
39
+ f.write(data)
40
+
41
+
42
+ def canvas_png(c):
43
+ return png_bytes(c.w, c.h, c.rgba())
44
+
45
+
46
+ def hashn(*v):
47
+ h = 2166136261
48
+ for x in v:
49
+ h = ((h ^ (x & 0xFFFFFFFF)) * 16777619) & 0xFFFFFFFF
50
+ return h
51
+
52
+
53
+ # ── the tileset ────────────────────────────────────────────────────────────
54
+
55
+ GRASS = ("#1d3b2a", "#1d3b2a")
56
+ BLADE = "#2c5a3b"
57
+
58
+
59
+ def grass(c, ox, oy, variant):
60
+ c.rect(ox, oy, T, T, GRASS[variant])
61
+ for k in range(7):
62
+ h = hashn(variant, k, 7)
63
+ x = ox + 3 + h % 26
64
+ y = oy + 4 + (h >> 8) % 24
65
+ c.line(x, y + 4, x + ((h >> 16) % 3) - 1, y, 1.3, BLADE)
66
+ if variant == 1:
67
+ for k in range(2):
68
+ h = hashn(9, k)
69
+ c.circle(ox + 6 + h % 20, oy + 6 + (h >> 8) % 20, 1.6, "#e8c55a")
70
+
71
+
72
+ def hedge(c, ox, oy):
73
+ c.rect(ox, oy, T, T, "#10291c")
74
+ for (x, y, r) in ((8, 10, 9), (22, 9, 9), (15, 20, 10), (6, 24, 7), (26, 24, 7)):
75
+ c.circle(ox + x, oy + y, r + 1.2, INK)
76
+ for (x, y, r) in ((8, 10, 9), (22, 9, 9), (15, 20, 10), (6, 24, 7), (26, 24, 7)):
77
+ c.circle(ox + x, oy + y, r, "#1f5234")
78
+ c.circle(ox + x - 2, oy + y - 3, r * 0.45, "#2f7046")
79
+
80
+
81
+ def stone(c, ox, oy):
82
+ grass(c, ox, oy, 0)
83
+ c.ellipse(ox + 16, oy + 25, 12, 4, "#0f2218", 0.8)
84
+ c.poly([(ox + 5, oy + 24), (ox + 8, oy + 10), (ox + 17, oy + 5), (ox + 27, oy + 11), (ox + 28, oy + 24)], INK)
85
+ c.poly([(ox + 7, oy + 23), (ox + 9.5, oy + 11), (ox + 17, oy + 7), (ox + 25.5, oy + 12), (ox + 26, oy + 23)], "#6f7887")
86
+ c.poly([(ox + 10, oy + 13), (ox + 17, oy + 8.5), (ox + 23, oy + 12), (ox + 15, oy + 15)], "#97a0ae")
87
+
88
+
89
+ def gate(c, ox, oy):
90
+ c.rect(ox, oy, T, T, "#4c3a2a")
91
+ for k in range(5):
92
+ h = hashn(3, k)
93
+ c.circle(ox + 4 + h % 24, oy + 4 + (h >> 8) % 24, 1.5, "#5e4834")
94
+ for x in (2, 25):
95
+ c.rect(ox + x - 1, oy, 7, T, INK, radius=2)
96
+ c.rect(ox + x, oy, 5, T, "#8a5a35", radius=2)
97
+ c.rect(ox + x + 1, oy + 2, 1.5, T - 4, "#a87447")
98
+
99
+
100
+ def doorstep(c, ox, oy):
101
+ c.rect(ox, oy, T, T, "#3a3328")
102
+ c.rect(ox + 2, oy + 3, 28, 26, INK, radius=4)
103
+ c.rect(ox + 3, oy + 4, 26, 24, "#8d8270", radius=3)
104
+ c.rect(ox + 5, oy + 6, 22, 3, "#b3a78f", radius=1.5)
105
+ c.circle(ox + 16, oy + 16, 9, "#ffcf73", 0.25)
106
+
107
+
108
+ def pad(c, ox, oy):
109
+ c.ellipse(ox + 16, oy + 18, 13, 10, INK)
110
+ c.ellipse(ox + 16, oy + 18, 12, 9, "#4a3626")
111
+ c.ellipse(ox + 16, oy + 17, 9, 6, "#5d4430")
112
+
113
+
114
+ def flower(c, ox, oy):
115
+ for k in range(3):
116
+ h = hashn(5, k)
117
+ x, y = ox + 6 + h % 20, oy + 6 + (h >> 8) % 20
118
+ for a in range(5):
119
+ ang = a * 2 * math.pi / 5
120
+ c.circle(x + 2.2 * math.cos(ang), y + 2.2 * math.sin(ang), 1.5, "#c9b6f2")
121
+ c.circle(x, y, 1.2, "#ffd166")
122
+
123
+
124
+ def tileset():
125
+ c = Canvas(10 * T, T)
126
+ grass(c, 0, 0, 0)
127
+ grass(c, T, 0, 1)
128
+ hedge(c, 2 * T, 0)
129
+ stone(c, 3 * T, 0)
130
+ gate(c, 4 * T, 0)
131
+ doorstep(c, 5 * T, 0)
132
+ pad(c, 6 * T, 0)
133
+ flower(c, 7 * T, 0)
134
+ pad(c, 8 * T, 0)
135
+ pad(c, 9 * T, 0)
136
+ return c
137
+
138
+
139
+ TILESET = """type tileset
140
+ version 1
141
+ ---
142
+ # Written by tools/make-assets.py: 0-1 grass, 2 hedge, 3 stone, 4 the gate,
143
+ # 5 the doorstep, 6 a thorn's pad, 7 night flowers, 8 a frost lily's pad,
144
+ # 9 a hedge's pad (the pads layer says which plant stands on a cell).
145
+ texture "tiles/garden.png"
146
+ grid 32 32 10 1
147
+ filter linear
148
+ solid 2 3
149
+ """
150
+
151
+ MAP = [
152
+ "HHHHGHHHH",
153
+ "H.,.....H",
154
+ "H.......H",
155
+ "H.R...R.H",
156
+ "H.....,.H",
157
+ "H.,.....H",
158
+ "H...R...H",
159
+ "H.......H",
160
+ "HR.....RH",
161
+ "H....,..H",
162
+ "H..R.R..H",
163
+ "H.,.....H",
164
+ "HHHHDHHHH",
165
+ ]
166
+
167
+
168
+ def map_text():
169
+ ground = []
170
+ walls = []
171
+ decor = []
172
+ for y, row in enumerate(MAP):
173
+ g, w, d = "", "", ""
174
+ for x, ch in enumerate(row):
175
+ g += {"G": "g", "D": "d", ",": "b"}.get(ch, "a")
176
+ w += {"H": "H", "R": "R"}.get(ch, ".")
177
+ d += "f" if ch == "." and hashn(x, y, 31) % 9 == 0 else "."
178
+ ground.append(g)
179
+ walls.append(w)
180
+ decor.append(d)
181
+ out = ["type tilemap", "version 1", "---",
182
+ "# Path Guard's field (tools/make-assets.py): 9 x 13 cells of 32 px, one",
183
+ "# world unit each. Visitors come through the gate (top) and walk to the",
184
+ "# doorstep (bottom); hedges and stones block them; the pads layer is",
185
+ "# empty until a plant is set on a cell.",
186
+ f"size {len(MAP[0])} {len(MAP)}", "tile 32 32", "unit 1", 'tileset "tiles/garden.ogt"',
187
+ "layer ground {", " z -12", ' legend "a" 0', ' legend "b" 1', ' legend "g" 4', ' legend "d" 5']
188
+ out += [f' row "{r}"' for r in ground]
189
+ out += ["}", "layer decor {", " z -11", ' legend "f" 7']
190
+ out += [f' row "{r}"' for r in decor]
191
+ out += ["}", "layer walls {", " z -10", " collision true", ' legend "H" 2', ' legend "R" 3']
192
+ out += [f' row "{r}"' for r in walls]
193
+ out += ["}", "layer pads {", " z -9"]
194
+ out += [f' row "{"." * len(MAP[0])}"' for _ in MAP]
195
+ out += ["}",
196
+ "object gate {", ' kind "spawn"', " at 4.5 0.5", "}",
197
+ "object doorstep {", ' kind "goal"', " at 4.5 12.5", "}"]
198
+ return "\n".join(out) + "\n"
199
+
200
+
201
+ # ── the sprite sheet ───────────────────────────────────────────────────────
202
+
203
+ def beetle(c, ox, oy, k):
204
+ leg = 2 if k else -2
205
+ for i, y in enumerate((12, 17, 22)):
206
+ d = leg if i % 2 == 0 else -leg
207
+ c.line(ox + 8, oy + y, ox + 3, oy + y + d, 2, INK)
208
+ c.line(ox + 24, oy + y, ox + 29, oy + y - d, 2, INK)
209
+ c.ellipse(ox + 16, oy + 17, 10, 12, INK)
210
+ c.ellipse(ox + 16, oy + 17, 8.6, 10.6, "#5b3fa6")
211
+ c.line(ox + 16, oy + 9, ox + 16, oy + 27, 1.4, INK)
212
+ c.ellipse(ox + 12.5, oy + 14, 2.4, 4, "#8d6fe0")
213
+ c.ellipse(ox + 16, oy + 6, 6, 4, INK)
214
+ c.ellipse(ox + 16, oy + 6, 4.8, 3, "#2b1f4f")
215
+ c.circle(ox + 13.5, oy + 5.5, 1.3, "#ffd166")
216
+ c.circle(ox + 18.5, oy + 5.5, 1.3, "#ffd166")
217
+
218
+
219
+ def moth(c, ox, oy, k):
220
+ lift = 4 if k else 0
221
+ for s in (-1, 1):
222
+ cx = ox + 16 + s * 8
223
+ c.ellipse(cx, oy + 13 - lift * 0.5, 8, 9 - lift, INK)
224
+ c.ellipse(cx, oy + 13 - lift * 0.5, 6.8, 7.8 - lift, "#d9c9f7")
225
+ c.circle(cx + s * 1.5, oy + 12 - lift * 0.5, 2, "#9a83d6")
226
+ c.ellipse(cx - s * 1, oy + 22, 5, 4.5, INK)
227
+ c.ellipse(cx - s * 1, oy + 22, 4, 3.5, "#bfaeea")
228
+ c.ellipse(ox + 16, oy + 17, 3.2, 9, INK)
229
+ c.ellipse(ox + 16, oy + 17, 2.2, 8, "#4f3d86")
230
+ c.line(ox + 15, oy + 8, ox + 12, oy + 3, 1.2, INK)
231
+ c.line(ox + 17, oy + 8, ox + 20, oy + 3, 1.2, INK)
232
+
233
+
234
+ def snail(c, ox, oy, k):
235
+ st = 2 if k else 0
236
+ c.ellipse(ox + 16, oy + 20 + st * 0.5, 7, 11 + st, INK)
237
+ c.ellipse(ox + 16, oy + 20 + st * 0.5, 5.8, 9.8 + st, "#a9c46e")
238
+ c.circle(ox + 16, oy + 15, 10.5, INK)
239
+ c.circle(ox + 16, oy + 15, 9.3, "#d98b4a")
240
+ c.ring(ox + 16, oy + 15, 6.5, 1.6, "#9c5a2a")
241
+ c.ring(ox + 16, oy + 15, 3.5, 1.6, "#9c5a2a")
242
+ c.line(ox + 14, oy + 29 + st, ox + 12, oy + 31, 1.2, INK)
243
+ c.line(ox + 18, oy + 29 + st, ox + 20, oy + 31, 1.2, INK)
244
+
245
+
246
+ def stem(c, ox, oy, sway):
247
+ c.line(ox + 16, oy + 30, ox + 16 + sway, oy + 16, 4, INK)
248
+ c.line(ox + 16, oy + 30, ox + 16 + sway, oy + 16, 2.4, "#3f8a4f")
249
+ c.ellipse(ox + 10, oy + 26, 5, 2.6, INK)
250
+ c.ellipse(ox + 10, oy + 26, 4, 1.8, "#4fa35f")
251
+ c.ellipse(ox + 22, oy + 24, 5, 2.6, INK)
252
+ c.ellipse(ox + 22, oy + 24, 4, 1.8, "#4fa35f")
253
+
254
+
255
+ def thorn(c, ox, oy, k):
256
+ sway = (-1, 1, 0)[k]
257
+ stem(c, ox, oy, sway)
258
+ hx, hy = ox + 16 + sway, oy + 12
259
+ r = 9 if k < 2 else 7.5
260
+ for a in range(8):
261
+ ang = a * math.pi / 4
262
+ c.poly([(hx + (r - 1) * math.cos(ang - 0.25), hy + (r - 1) * math.sin(ang - 0.25)),
263
+ (hx + (r + 4) * math.cos(ang), hy + (r + 4) * math.sin(ang)),
264
+ (hx + (r - 1) * math.cos(ang + 0.25), hy + (r - 1) * math.sin(ang + 0.25))], INK)
265
+ c.circle(hx, hy, r + 1, INK)
266
+ c.circle(hx, hy, r, "#e05a6a")
267
+ c.circle(hx - 2.5, hy - 3, r * 0.35, "#f28b96")
268
+ if k == 2:
269
+ c.circle(hx, hy - 4.5, 3, INK)
270
+ else:
271
+ c.circle(hx - 2.5, hy, 1.2, INK)
272
+ c.circle(hx + 2.5, hy, 1.2, INK)
273
+
274
+
275
+ def frost(c, ox, oy, k):
276
+ sway = (-1, 1, 0)[k]
277
+ stem(c, ox, oy, sway)
278
+ hx, hy = ox + 16 + sway, oy + 12
279
+ open_ = 1.25 if k == 2 else 1.0
280
+ for a in range(6):
281
+ ang = a * math.pi / 3 + math.pi / 6
282
+ px, py = hx + 6 * open_ * math.cos(ang), hy + 6 * open_ * math.sin(ang)
283
+ c.ellipse(px, py, 5.6, 5.6, INK)
284
+ for a in range(6):
285
+ ang = a * math.pi / 3 + math.pi / 6
286
+ px, py = hx + 6 * open_ * math.cos(ang), hy + 6 * open_ * math.sin(ang)
287
+ c.ellipse(px, py, 4.5, 4.5, "#9ad8ff")
288
+ c.circle(hx, hy, 4, "#eaf8ff")
289
+ c.circle(hx, hy, 1.8, "#5cb6e8")
290
+
291
+
292
+ def bush(c, ox, oy, k):
293
+ lift = 1 if k else 0
294
+ for (x, y, r) in ((10, 19, 8), (22, 19, 8), (16, 12 - lift, 9)):
295
+ c.circle(ox + x, oy + y, r + 1.2, INK)
296
+ for (x, y, r) in ((10, 19, 8), (22, 19, 8), (16, 12 - lift, 9)):
297
+ c.circle(ox + x, oy + y, r, "#2f7a45")
298
+ c.circle(ox + x - 2, oy + y - 2.5, r * 0.45, "#47a35f")
299
+ c.circle(ox + 20, oy + 9 - lift, 1.6, "#ffd166")
300
+
301
+
302
+ def lantern(c, ox, oy, k):
303
+ c.rect(ox + 14, oy + 14, 4, 18, INK, radius=1)
304
+ c.rect(ox + 15, oy + 14, 2, 18, "#6b4a2e")
305
+ glow = (0.35, 0.5)[k]
306
+ c.circle(ox + 16, oy + 11, 11, "#ffcf73", glow * 0.5)
307
+ c.rect(ox + 9, oy + 3, 14, 15, INK, radius=3)
308
+ c.rect(ox + 10.5, oy + 4.5, 11, 12, "#ffcf73", radius=2)
309
+ c.rect(ox + 12.5, oy + 6.5, 7, 8, "#fff1c9", radius=1.5)
310
+ c.rect(ox + 8, oy + 2, 16, 3, "#3a2a1c", radius=1.5)
311
+
312
+
313
+ def seed(c, ox, oy):
314
+ c.circle(ox + 16, oy + 16, 5.2, INK)
315
+ c.circle(ox + 16, oy + 16, 4, "#ff8a96")
316
+ c.circle(ox + 14.6, oy + 14.6, 1.4, "#ffd0d6")
317
+
318
+
319
+ def flake(c, ox, oy):
320
+ for a in range(3):
321
+ ang = a * math.pi / 3
322
+ dx, dy = 6 * math.cos(ang), 6 * math.sin(ang)
323
+ c.line(ox + 16 - dx, oy + 16 - dy, ox + 16 + dx, oy + 16 + dy, 3, INK)
324
+ for a in range(3):
325
+ ang = a * math.pi / 3
326
+ dx, dy = 6 * math.cos(ang), 6 * math.sin(ang)
327
+ c.line(ox + 16 - dx, oy + 16 - dy, ox + 16 + dx, oy + 16 + dy, 1.6, "#dff4ff")
328
+
329
+
330
+ def cursor(c, ox, oy, colour):
331
+ for (x, y, sx, sy) in ((2, 2, 1, 1), (30, 2, -1, 1), (2, 30, 1, -1), (30, 30, -1, -1)):
332
+ c.line(ox + x, oy + y, ox + x + sx * 8, oy + y, 3.4, INK)
333
+ c.line(ox + x, oy + y, ox + x, oy + y + sy * 8, 3.4, INK)
334
+ c.line(ox + x, oy + y, ox + x + sx * 8, oy + y, 2, colour)
335
+ c.line(ox + x, oy + y, ox + x, oy + y + sy * 8, 2, colour)
336
+
337
+
338
+ def turned(src):
339
+ """The canvas turned a quarter clockwise: its top edge becomes its right edge."""
340
+ out = Canvas(src.w, src.h)
341
+ for y in range(src.h):
342
+ for x in range(src.w):
343
+ out.px[y * src.w + x] = list(src.px[(src.w - 1 - x) * src.w + y])
344
+ return out
345
+
346
+
347
+ # Frames in sheet order (8 columns): the flipbook's clips name them.
348
+ FRAMES = [
349
+ ("beetle", 0), ("beetle", 1), ("moth", 0), ("moth", 1), ("snail", 0), ("snail", 1), ("lantern", 0), ("lantern", 1),
350
+ ("thorn", 0), ("thorn", 1), ("thorn", 2), ("frost", 0), ("frost", 1), ("frost", 2), ("bush", 0), ("bush", 1),
351
+ ("seed", 0), ("flake", 0), ("cursor", 0), ("cursor", 1),
352
+ ]
353
+
354
+
355
+ def sheet():
356
+ c = Canvas(8 * T, 3 * T)
357
+ draw = {"lantern": lantern, "thorn": thorn, "frost": frost, "bush": bush}
358
+ # The visitors are drawn head up and turned to face +x: og.nav's
359
+ # faceMovement turns a 2D sprite's +x the way it walks.
360
+ walkers = {"beetle": (beetle, 1), "moth": (moth, 1), "snail": (snail, 3)}
361
+ for i, (name, k) in enumerate(FRAMES):
362
+ ox, oy = (i % 8) * T, (i // 8) * T
363
+ if name in walkers:
364
+ f, turns = walkers[name]
365
+ tmp = Canvas(T, T)
366
+ f(tmp, 0, 0, k)
367
+ for _ in range(turns):
368
+ tmp = turned(tmp)
369
+ for y in range(T):
370
+ for x in range(T):
371
+ c.px[(oy + y) * c.w + ox + x] = tmp.px[y * T + x]
372
+ elif name in draw:
373
+ draw[name](c, ox, oy, k)
374
+ elif name == "seed":
375
+ seed(c, ox, oy)
376
+ elif name == "flake":
377
+ flake(c, ox, oy)
378
+ elif name == "cursor":
379
+ cursor(c, ox, oy, "#fff4dc" if k == 0 else "#ff6b6b")
380
+ return c
381
+
382
+
383
+ SHEET = """type flipbook
384
+ version 1
385
+ ---
386
+ # Written by tools/make-assets.py: 32 px frames, eight a row. The visitors
387
+ # crawl, the plants sway and open on the frame they shoot ("shoot" ends the
388
+ # once-clips), the lantern flickers.
389
+ texture "garden.png"
390
+ pivot 0.5 0.5
391
+ grid 32 32 8 3
392
+ clip beetle {
393
+ frames 0 1
394
+ fps 6
395
+ }
396
+ clip moth {
397
+ frames 2 3
398
+ fps 10
399
+ }
400
+ clip snail {
401
+ frames 4 5
402
+ fps 3
403
+ }
404
+ clip lantern {
405
+ frames 6 7
406
+ durations 0.6 0.25
407
+ }
408
+ clip thorn {
409
+ frames 8 9
410
+ fps 2
411
+ mode pingPong
412
+ }
413
+ clip thorn_shoot {
414
+ frames 10 8
415
+ durations 0.12 0.1
416
+ mode once
417
+ }
418
+ clip frost {
419
+ frames 11 12
420
+ fps 2
421
+ mode pingPong
422
+ }
423
+ clip frost_shoot {
424
+ frames 13 11
425
+ durations 0.14 0.1
426
+ mode once
427
+ }
428
+ clip hedge {
429
+ frames 14 15
430
+ fps 1.5
431
+ mode pingPong
432
+ }
433
+ clip seed {
434
+ frames 16
435
+ fps 1
436
+ }
437
+ clip flake {
438
+ frames 17
439
+ fps 1
440
+ }
441
+ clip cursor {
442
+ frames 18
443
+ fps 1
444
+ }
445
+ clip refused {
446
+ frames 19
447
+ fps 1
448
+ }
449
+ """
450
+
451
+
452
+ def ring():
453
+ c = Canvas(128, 128)
454
+ c.circle(64, 64, 62, "#fff4dc", 0.08)
455
+ c.ring(64, 64, 62, 2.5, "#fff4dc", 0.7)
456
+ return c
457
+
458
+
459
+ def spark():
460
+ c = Canvas(16, 16)
461
+ for r, a in ((7.5, 0.15), (5, 0.35), (3, 0.8), (1.6, 1.0)):
462
+ c.circle(8, 8, r, "#ffffff", a)
463
+ return c
464
+
465
+
466
+ def glow():
467
+ """A soft round glow, fully clear at its edge (a falloff, not rings)."""
468
+ n = 64
469
+ rows = []
470
+ for y in range(n):
471
+ row = bytearray()
472
+ for x in range(n):
473
+ d = math.hypot(x + 0.5 - n / 2, y + 0.5 - n / 2) / (n / 2)
474
+ a = max(0.0, 1 - d) ** 2.2
475
+ row += bytes([255, 255, 255, round(a * 255)])
476
+ rows.append(bytes(row))
477
+ return png_bytes(n, n, rows)
478
+
479
+
480
+ LINEAR = """type import
481
+ version 1
482
+ ---
483
+ # Drawn art: lossless, sampled linear.
484
+ texture {
485
+ kind color
486
+ }
487
+ """
488
+
489
+ POP = """type particles
490
+ version 1
491
+ ---
492
+ # A visitor turned away: a puff of petals thrown out, drawn as sprites.
493
+ maxParticles 48
494
+ shape point
495
+ spread 180
496
+ burst 0 14
497
+ duration 0.1
498
+ lifetime 0.35 0.6
499
+ speed 1.6 3.2
500
+ size 0.12 0.22
501
+ sizeOverLife 0 1 1 0
502
+ colorOverLife {
503
+ key 0 1 0.86 0.45 1
504
+ key 1 0.79 0.71 0.95 0
505
+ }
506
+ gravity 0 -2 0
507
+ drag 2
508
+ texture "sprites/spark.png"
509
+ render sprite 20
510
+ """
511
+
512
+
513
+ FIREFLIES = """type particles
514
+ version 1
515
+ ---
516
+ # Fireflies over the garden: slow, drifting, blinking out; drawn as glowing sprites above the lawn.
517
+ maxParticles 40
518
+ shape box 7 9 0
519
+ rate 5
520
+ lifetime 3 5
521
+ speed 0.05 0.25
522
+ size 0.12 0.2
523
+ sizeOverLife 0 0.2 0.3 1 0.8 1 1 0
524
+ colorOverLife {
525
+ key 0 0.85 1 0.45 0
526
+ key 0.2 0.85 1 0.45 0.9
527
+ key 0.8 0.95 0.9 0.4 0.7
528
+ key 1 0.95 0.9 0.4 0
529
+ }
530
+ noise 0.5 0.4 0.3
531
+ texture "sprites/spark.png"
532
+ blend additive
533
+ render sprite 6
534
+ """
535
+
536
+
537
+ # ── sounds ─────────────────────────────────────────────────────────────────
538
+
539
+ RATE = 22050
540
+
541
+
542
+ def chord_pad(seconds, freqs, gain):
543
+ n = int(seconds * RATE)
544
+ out = [0.0] * n
545
+ for f in freqs:
546
+ for i in range(n):
547
+ t = i / RATE
548
+ env = min(1.0, t / 0.4) * min(1.0, (seconds - t) / 0.4)
549
+ out[i] += gain * env * (math.sin(2 * math.pi * f * t) + 0.3 * math.sin(4 * math.pi * f * t))
550
+ return out
551
+
552
+
553
+ def pluck(seconds, f, gain=0.25):
554
+ n = int(seconds * RATE)
555
+ return [gain * math.exp(-i / RATE / 0.25) * (math.sin(2 * math.pi * f * i / RATE) + 0.4 * math.sin(6 * math.pi * f * i / RATE)) for i in range(n)]
556
+
557
+
558
+ def music():
559
+ """Four bars at 84 BPM in A minor pentatonic: a soft pad and a plucked arpeggio, looped seamlessly."""
560
+ beat = 60 / 84
561
+ bars = [(220.0, 261.63, 329.63), (196.0, 246.94, 293.66), (174.61, 220.0, 261.63), (196.0, 246.94, 329.63)]
562
+ arp = [440.0, 523.25, 659.25, 587.33, 523.25, 440.0, 392.0, 440.0]
563
+ total = int(16 * beat * RATE)
564
+ out = [0.0] * total
565
+ for b, ch in enumerate(bars):
566
+ pad = chord_pad(4 * beat, ch, 0.05)
567
+ start = int(b * 4 * beat * RATE)
568
+ for i, s in enumerate(pad):
569
+ if start + i < total:
570
+ out[start + i] += s
571
+ for k in range(8):
572
+ f = arp[(k + b * 2) % 8] * (0.5 if b == 2 and k % 2 else 1)
573
+ p = pluck(beat, f, 0.12)
574
+ s0 = int((b * 4 + k * 0.5) * beat * RATE)
575
+ for i, s in enumerate(p):
576
+ out[(s0 + i) % total] += s
577
+ return out
578
+
579
+
580
+ def sounds():
581
+ a = os.path.join(assets, "audio")
582
+ os.makedirs(a, exist_ok=True)
583
+ w = lambda name, s: write_wav(os.path.join(a, name), s) # noqa: E731
584
+ w("plant.wav", mix(noise(0.12, decay=0.03, gain=0.35, seed=5), tone(0.18, 180, 90, shape="tri", decay=0.07, gain=0.5)))
585
+ w("thorn.wav", tone(0.09, 880, 520, shape="tri", decay=0.03, gain=0.35))
586
+ w("frost.wav", mix(tone(0.22, 1568, 1568, decay=0.08, gain=0.22), tone(0.22, 2349, 2349, decay=0.05, gain=0.12)))
587
+ w("pop.wav", concat(tone(0.05, 300, 700, shape="sine", decay=0.03, gain=0.45), tone(0.12, 1319, 1319, shape="square", decay=0.05, gain=0.12)))
588
+ w("leak.wav", mix(tone(0.7, 196, 180, decay=0.3, gain=0.5), tone(0.7, 98, 96, shape="tri", decay=0.35, gain=0.4)))
589
+ w("wave.wav", concat(tone(0.18, 392, shape="tri", gain=0.4, decay=0.12), tone(0.3, 523.25, shape="tri", gain=0.4, decay=0.2)))
590
+ w("clear.wav", concat(*[tone(0.09, f, shape="tri", gain=0.35, decay=0.08) for f in (523.25, 659.25, 783.99)], tone(0.3, 1046.5, shape="tri", gain=0.35, decay=0.2)))
591
+ w("won.wav", concat(*[tone(0.14, f, shape="tri", gain=0.4, decay=0.12) for f in (523.25, 659.25, 783.99, 659.25)], tone(0.6, 1046.5, shape="tri", gain=0.4, decay=0.35)))
592
+ w("lost.wav", concat(*[tone(0.22, f, shape="tri", gain=0.4, decay=0.18) for f in (392.0, 349.23, 311.13)], tone(0.7, 261.63, shape="tri", gain=0.4, decay=0.4)))
593
+ w("night.wav", music())
594
+ presets = {"ui-press": "click", "ui-open": "select", "ui-close": "back", "ui-error": "error", "ui-success": "levelup"}
595
+ for name, preset in presets.items():
596
+ write(f"audio/{name}.ogt", f'type sfx\nversion 1\n---\n# og sfx\'s "{preset}" preset, synthesised by og cook (the UI\'s {name[3:]} sound).\npreset "{preset}"\nseed 0\npitch 1\nlength 1\nvolume 0.8\n')
597
+
598
+
599
+ # ── the font ───────────────────────────────────────────────────────────────
600
+
601
+ def zh_characters():
602
+ text = open(os.path.join(assets, "strings", "zh-CN.ogt"), encoding="utf-8").read()
603
+ chars = sorted({ch for ch in text if ord(ch) > 0x2E7F})
604
+ return "".join(chars)
605
+
606
+
607
+ def font():
608
+ chars = zh_characters()
609
+ src = os.path.join(root, "..", "..", "game", "assets", "fonts", "NotoSansSC-Regular-subset.ttf")
610
+ try:
611
+ subset_font(src, os.path.join(assets, "fonts", "NotoSansSC-subset.ttf"), chars)
612
+ except Exception as e: # noqa: BLE001
613
+ print(f"font subset skipped ({e}); the committed assets/fonts/NotoSansSC-subset.ttf stays")
614
+ write("fonts/NotoSansSC-subset.ttf.ogt", "type import\nversion 1\n---\n"
615
+ "# Latin-1, CJK punctuation and every character of assets/strings/zh-CN.ogt (tools/make-assets.py).\n"
616
+ f'font {{\n charset latin cjk-punct\n chars "{chars}"\n em_px 32\n px_range 4\n}}\n')
617
+
618
+
619
+ def main():
620
+ write("tiles/garden.png", canvas_png(tileset()))
621
+ write("tiles/garden.png.ogt", LINEAR)
622
+ write("tiles/garden.ogt", TILESET)
623
+ write("maps/garden.ogt", map_text())
624
+ write("sprites/garden.png", canvas_png(sheet()))
625
+ write("sprites/garden.png.ogt", LINEAR)
626
+ write("sprites/garden.ogt", SHEET)
627
+ write("sprites/ring.png", canvas_png(ring()))
628
+ write("sprites/ring.png.ogt", LINEAR)
629
+ write("sprites/spark.png", canvas_png(spark()))
630
+ write("sprites/spark.png.ogt", LINEAR)
631
+ write("sprites/glow.png", glow())
632
+ write("sprites/glow.png.ogt", LINEAR)
633
+ write("fx/pop.ogt", POP)
634
+ write("fx/fireflies.ogt", FIREFLIES)
635
+ sounds()
636
+ font()
637
+
638
+
639
+ if __name__ == "__main__":
640
+ main()