@waica/cli 0.3.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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -0
  3. package/dist/cli.js +184 -0
  4. package/dist/editor/assets/abap-08VXUWAP.js +1 -0
  5. package/dist/editor/assets/apex-BWPQTe0t.js +1 -0
  6. package/dist/editor/assets/azcli-Bc_sGQ0U.js +1 -0
  7. package/dist/editor/assets/bat-i0X4ZdIN.js +1 -0
  8. package/dist/editor/assets/bicep-B5-_aFwp.js +2 -0
  9. package/dist/editor/assets/cameligo-DMUM7wLl.js +1 -0
  10. package/dist/editor/assets/clojure-Cm7r79vr.js +1 -0
  11. package/dist/editor/assets/codicon-DCmgc-ay.ttf +0 -0
  12. package/dist/editor/assets/coffee-Ba7i2nA0.js +1 -0
  13. package/dist/editor/assets/cpp-C7h46wYY.js +1 -0
  14. package/dist/editor/assets/csharp-BKxtCVv1.js +1 -0
  15. package/dist/editor/assets/csp-bTuwJoIa.js +1 -0
  16. package/dist/editor/assets/css-DIMkf-bt.js +3 -0
  17. package/dist/editor/assets/css.worker-Fwwr_HdT.js +88 -0
  18. package/dist/editor/assets/cssMode-CQE-WdwL.js +4 -0
  19. package/dist/editor/assets/cypher-CVaqCwHa.js +1 -0
  20. package/dist/editor/assets/dart-onAF5SnQ.js +1 -0
  21. package/dist/editor/assets/dockerfile-DZFCIeNp.js +1 -0
  22. package/dist/editor/assets/ecl-D05T4iGw.js +1 -0
  23. package/dist/editor/assets/editor.worker-DsBDrWS5.js +12 -0
  24. package/dist/editor/assets/elixir-6RTg0lbw.js +1 -0
  25. package/dist/editor/assets/flow9-C5_-GSwl.js +1 -0
  26. package/dist/editor/assets/freemarker2-CYgdVabn.js +3 -0
  27. package/dist/editor/assets/fsharp-C8Ef5oNN.js +1 -0
  28. package/dist/editor/assets/go-C-y9NEjX.js +1 -0
  29. package/dist/editor/assets/graphql-fmXr3nnJ.js +1 -0
  30. package/dist/editor/assets/handlebars-DdeORCJD.js +1 -0
  31. package/dist/editor/assets/hcl-CpzslTdj.js +1 -0
  32. package/dist/editor/assets/html-DTIAGV84.js +1 -0
  33. package/dist/editor/assets/html.worker-B3Ztmmz2.js +495 -0
  34. package/dist/editor/assets/htmlMode-CRV3iBih.js +4 -0
  35. package/dist/editor/assets/index-Btzc6zxr.css +1 -0
  36. package/dist/editor/assets/index-Dhkqk31v.js +11016 -0
  37. package/dist/editor/assets/ini-sBoK_t0W.js +1 -0
  38. package/dist/editor/assets/java-BEtHBSE6.js +1 -0
  39. package/dist/editor/assets/javascript-dxBW86cl.js +1 -0
  40. package/dist/editor/assets/json.worker-PWQxM7ZO.js +51 -0
  41. package/dist/editor/assets/jsonMode-DFA5-FFK.js +10 -0
  42. package/dist/editor/assets/julia-Bri6UV-V.js +1 -0
  43. package/dist/editor/assets/kotlin-B0qVs-E9.js +1 -0
  44. package/dist/editor/assets/less-B9JPFI3C.js +2 -0
  45. package/dist/editor/assets/lexon-CfSJPG6W.js +1 -0
  46. package/dist/editor/assets/liquid-CScWaXYV.js +1 -0
  47. package/dist/editor/assets/lua-CsQS60Ue.js +1 -0
  48. package/dist/editor/assets/m3-D-oSqn_W.js +1 -0
  49. package/dist/editor/assets/markdown-Cimd5fb3.js +1 -0
  50. package/dist/editor/assets/mdx-Bvp84SqA.js +1 -0
  51. package/dist/editor/assets/mips-CIPQ_RoX.js +1 -0
  52. package/dist/editor/assets/msdax-DauUninz.js +1 -0
  53. package/dist/editor/assets/mysql-SOo6toE5.js +1 -0
  54. package/dist/editor/assets/objective-c-FvmIjYaQ.js +1 -0
  55. package/dist/editor/assets/pascal-DrH0SRf2.js +1 -0
  56. package/dist/editor/assets/pascaligo-D-ptJ9y-.js +1 -0
  57. package/dist/editor/assets/perl-oz_6vUea.js +1 -0
  58. package/dist/editor/assets/pgsql-DTj74zXo.js +1 -0
  59. package/dist/editor/assets/php-nr791fC2.js +1 -0
  60. package/dist/editor/assets/pla-CopQ2nXW.js +1 -0
  61. package/dist/editor/assets/postiats-43DmfD33.js +1 -0
  62. package/dist/editor/assets/powerquery-D3hlyOfw.js +1 -0
  63. package/dist/editor/assets/powershell-DmHpPYUd.js +1 -0
  64. package/dist/editor/assets/protobuf-C531GsRP.js +2 -0
  65. package/dist/editor/assets/pug-Z5eAx3Zn.js +1 -0
  66. package/dist/editor/assets/python-CG-OtvFa.js +1 -0
  67. package/dist/editor/assets/qsharp-DkqhCAOL.js +1 -0
  68. package/dist/editor/assets/r-BwWrilGY.js +1 -0
  69. package/dist/editor/assets/razor-r-iUEZPj.js +1 -0
  70. package/dist/editor/assets/redis-ClamHrr6.js +1 -0
  71. package/dist/editor/assets/redshift-DT7zqm-g.js +1 -0
  72. package/dist/editor/assets/restructuredtext-BYgofb2h.js +1 -0
  73. package/dist/editor/assets/ruby-DezsRK8O.js +1 -0
  74. package/dist/editor/assets/rust-DdL9SqIa.js +1 -0
  75. package/dist/editor/assets/sb-CcwsVR0C.js +1 -0
  76. package/dist/editor/assets/scala-DHpiXF5c.js +1 -0
  77. package/dist/editor/assets/scheme-BeGwcela.js +1 -0
  78. package/dist/editor/assets/scss-gp-XZpBa.js +3 -0
  79. package/dist/editor/assets/shell-CC2rA5mh.js +1 -0
  80. package/dist/editor/assets/solidity-BEEn4gHE.js +1 -0
  81. package/dist/editor/assets/sophia-CRfGWb83.js +1 -0
  82. package/dist/editor/assets/sparql-D_Lu-MrJ.js +1 -0
  83. package/dist/editor/assets/sql-NEE52Syq.js +1 -0
  84. package/dist/editor/assets/st-DbInun42.js +1 -0
  85. package/dist/editor/assets/swift-Bxkupp3x.js +1 -0
  86. package/dist/editor/assets/systemverilog-Bz4Y3fRF.js +1 -0
  87. package/dist/editor/assets/tcl-DISqw1ZD.js +1 -0
  88. package/dist/editor/assets/ts.worker-0mEyHVru.js +51339 -0
  89. package/dist/editor/assets/tsMode-Bth1rJwM.js +11 -0
  90. package/dist/editor/assets/twig-De2hgUGE.js +1 -0
  91. package/dist/editor/assets/typescript-tNRuHsoe.js +1 -0
  92. package/dist/editor/assets/typespec-B8J7ngcE.js +1 -0
  93. package/dist/editor/assets/vb-DV3o63ZY.js +1 -0
  94. package/dist/editor/assets/wgsl-DpFanUEy.js +298 -0
  95. package/dist/editor/assets/xml-BCx9e6CK.js +1 -0
  96. package/dist/editor/assets/yaml-Bb-peGP_.js +1 -0
  97. package/dist/editor/index.html +14 -0
  98. package/dist/mcp/archetypes.js +103 -0
  99. package/dist/mcp/cli.js +6 -0
  100. package/dist/mcp/create-project.js +151 -0
  101. package/dist/mcp/introspection.js +201 -0
  102. package/dist/mcp/node_modules/@waica/archetype-platformer/assets/waica-coin.png +0 -0
  103. package/dist/mcp/node_modules/@waica/archetype-platformer/assets/waica-dog.png +0 -0
  104. package/dist/mcp/node_modules/@waica/archetype-platformer/assets/waica-slime.png +0 -0
  105. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/art.d.ts +10 -0
  106. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/art.js +13 -0
  107. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/bundle.d.ts +3 -0
  108. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/bundle.js +10 -0
  109. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/controls.d.ts +5 -0
  110. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/controls.js +12 -0
  111. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/index.d.ts +38 -0
  112. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/index.js +34 -0
  113. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/manifest.d.ts +15 -0
  114. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/manifest.js +26 -0
  115. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/prefabs.d.ts +7 -0
  116. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/prefabs.js +97 -0
  117. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/registry-data.d.ts +5 -0
  118. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/registry-data.js +45 -0
  119. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/registry.d.ts +6 -0
  120. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/registry.js +15 -0
  121. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/scene-default.d.ts +40 -0
  122. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/scene-default.js +93 -0
  123. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/ui.d.ts +10 -0
  124. package/dist/mcp/node_modules/@waica/archetype-platformer/dist/ui.js +24 -0
  125. package/dist/mcp/node_modules/@waica/archetype-platformer/package.json +30 -0
  126. package/dist/mcp/node_modules/@waica/behaviors/dist/chaser.d.ts +59 -0
  127. package/dist/mcp/node_modules/@waica/behaviors/dist/chaser.js +127 -0
  128. package/dist/mcp/node_modules/@waica/behaviors/dist/collectible.d.ts +25 -0
  129. package/dist/mcp/node_modules/@waica/behaviors/dist/collectible.js +27 -0
  130. package/dist/mcp/node_modules/@waica/behaviors/dist/hazard.d.ts +29 -0
  131. package/dist/mcp/node_modules/@waica/behaviors/dist/hazard.js +42 -0
  132. package/dist/mcp/node_modules/@waica/behaviors/dist/index.d.ts +9 -0
  133. package/dist/mcp/node_modules/@waica/behaviors/dist/index.js +9 -0
  134. package/dist/mcp/node_modules/@waica/behaviors/dist/lifetime.d.ts +16 -0
  135. package/dist/mcp/node_modules/@waica/behaviors/dist/lifetime.js +19 -0
  136. package/dist/mcp/node_modules/@waica/behaviors/dist/npc.d.ts +4 -0
  137. package/dist/mcp/node_modules/@waica/behaviors/dist/npc.js +14 -0
  138. package/dist/mcp/node_modules/@waica/behaviors/dist/patrol.d.ts +43 -0
  139. package/dist/mcp/node_modules/@waica/behaviors/dist/patrol.js +68 -0
  140. package/dist/mcp/node_modules/@waica/behaviors/dist/platformer-motor.d.ts +124 -0
  141. package/dist/mcp/node_modules/@waica/behaviors/dist/platformer-motor.js +146 -0
  142. package/dist/mcp/node_modules/@waica/behaviors/dist/player-identity.d.ts +3 -0
  143. package/dist/mcp/node_modules/@waica/behaviors/dist/player-identity.js +5 -0
  144. package/dist/mcp/node_modules/@waica/behaviors/dist/player-states.d.ts +18 -0
  145. package/dist/mcp/node_modules/@waica/behaviors/dist/player-states.js +95 -0
  146. package/dist/mcp/node_modules/@waica/behaviors/dist/respawnable.d.ts +23 -0
  147. package/dist/mcp/node_modules/@waica/behaviors/dist/respawnable.js +27 -0
  148. package/dist/mcp/node_modules/@waica/behaviors/package.json +24 -0
  149. package/dist/mcp/node_modules/@waica/engine/dist/aabb.d.ts +2 -0
  150. package/dist/mcp/node_modules/@waica/engine/dist/aabb.js +4 -0
  151. package/dist/mcp/node_modules/@waica/engine/dist/animation/clip-player.d.ts +20 -0
  152. package/dist/mcp/node_modules/@waica/engine/dist/animation/clip-player.js +24 -0
  153. package/dist/mcp/node_modules/@waica/engine/dist/animation/contract.d.ts +21 -0
  154. package/dist/mcp/node_modules/@waica/engine/dist/animation/contract.js +23 -0
  155. package/dist/mcp/node_modules/@waica/engine/dist/animation/sheet.d.ts +65 -0
  156. package/dist/mcp/node_modules/@waica/engine/dist/animation/sheet.js +44 -0
  157. package/dist/mcp/node_modules/@waica/engine/dist/archetype.d.ts +37 -0
  158. package/dist/mcp/node_modules/@waica/engine/dist/archetype.js +1 -0
  159. package/dist/mcp/node_modules/@waica/engine/dist/camera.d.ts +71 -0
  160. package/dist/mcp/node_modules/@waica/engine/dist/camera.js +59 -0
  161. package/dist/mcp/node_modules/@waica/engine/dist/collision-shape.d.ts +26 -0
  162. package/dist/mcp/node_modules/@waica/engine/dist/collision-shape.js +136 -0
  163. package/dist/mcp/node_modules/@waica/engine/dist/component-registry.d.ts +16 -0
  164. package/dist/mcp/node_modules/@waica/engine/dist/component-registry.js +44 -0
  165. package/dist/mcp/node_modules/@waica/engine/dist/component.d.ts +58 -0
  166. package/dist/mcp/node_modules/@waica/engine/dist/component.js +11 -0
  167. package/dist/mcp/node_modules/@waica/engine/dist/components/animated-sprite.d.ts +80 -0
  168. package/dist/mcp/node_modules/@waica/engine/dist/components/animated-sprite.js +210 -0
  169. package/dist/mcp/node_modules/@waica/engine/dist/components/dynamic-body.d.ts +68 -0
  170. package/dist/mcp/node_modules/@waica/engine/dist/components/dynamic-body.js +189 -0
  171. package/dist/mcp/node_modules/@waica/engine/dist/components/hitbox.d.ts +25 -0
  172. package/dist/mcp/node_modules/@waica/engine/dist/components/hitbox.js +21 -0
  173. package/dist/mcp/node_modules/@waica/engine/dist/components/solid.d.ts +32 -0
  174. package/dist/mcp/node_modules/@waica/engine/dist/components/solid.js +45 -0
  175. package/dist/mcp/node_modules/@waica/engine/dist/components/sprite.d.ts +51 -0
  176. package/dist/mcp/node_modules/@waica/engine/dist/components/sprite.js +112 -0
  177. package/dist/mcp/node_modules/@waica/engine/dist/entity.d.ts +22 -0
  178. package/dist/mcp/node_modules/@waica/engine/dist/entity.js +52 -0
  179. package/dist/mcp/node_modules/@waica/engine/dist/events.d.ts +8 -0
  180. package/dist/mcp/node_modules/@waica/engine/dist/events.js +20 -0
  181. package/dist/mcp/node_modules/@waica/engine/dist/game.d.ts +95 -0
  182. package/dist/mcp/node_modules/@waica/engine/dist/game.js +263 -0
  183. package/dist/mcp/node_modules/@waica/engine/dist/index.d.ts +39 -0
  184. package/dist/mcp/node_modules/@waica/engine/dist/index.js +26 -0
  185. package/dist/mcp/node_modules/@waica/engine/dist/input.d.ts +40 -0
  186. package/dist/mcp/node_modules/@waica/engine/dist/input.js +84 -0
  187. package/dist/mcp/node_modules/@waica/engine/dist/scene.d.ts +80 -0
  188. package/dist/mcp/node_modules/@waica/engine/dist/scene.js +93 -0
  189. package/dist/mcp/node_modules/@waica/engine/dist/solid-axis.d.ts +21 -0
  190. package/dist/mcp/node_modules/@waica/engine/dist/solid-axis.js +77 -0
  191. package/dist/mcp/node_modules/@waica/engine/dist/state/hooks.d.ts +90 -0
  192. package/dist/mcp/node_modules/@waica/engine/dist/state/hooks.js +81 -0
  193. package/dist/mcp/node_modules/@waica/engine/dist/state/state-machine.d.ts +83 -0
  194. package/dist/mcp/node_modules/@waica/engine/dist/state/state-machine.js +173 -0
  195. package/dist/mcp/node_modules/@waica/engine/dist/stats.d.ts +27 -0
  196. package/dist/mcp/node_modules/@waica/engine/dist/stats.js +54 -0
  197. package/dist/mcp/node_modules/@waica/engine/dist/ui.d.ts +47 -0
  198. package/dist/mcp/node_modules/@waica/engine/dist/ui.js +175 -0
  199. package/dist/mcp/node_modules/@waica/engine/package.json +25 -0
  200. package/dist/mcp/package-resolver.js +240 -0
  201. package/dist/mcp/project-path.js +86 -0
  202. package/dist/mcp/scaffolds.js +153 -0
  203. package/dist/mcp/server.js +217 -0
  204. package/dist/mcp/stdio.js +13 -0
  205. package/dist/mcp/template/README.md +22 -0
  206. package/dist/mcp/template/_gitignore +5 -0
  207. package/dist/mcp/template/index.html +25 -0
  208. package/dist/mcp/template/package.json.tpl +20 -0
  209. package/dist/mcp/template/public/waica.params.json +1 -0
  210. package/dist/mcp/template/src/art/waica-coin.png +0 -0
  211. package/dist/mcp/template/src/art/waica-dog.png +0 -0
  212. package/dist/mcp/template/src/art/waica-slime.png +0 -0
  213. package/dist/mcp/template/src/characters/player.character.json +133 -0
  214. package/dist/mcp/template/src/characters/slime.character.json +61 -0
  215. package/dist/mcp/template/src/controls.json +8 -0
  216. package/dist/mcp/template/src/game.json +10 -0
  217. package/dist/mcp/template/src/main.ts +105 -0
  218. package/dist/mcp/template/src/objects/coin.object.json +41 -0
  219. package/dist/mcp/template/src/scenes/main.scene.json +217 -0
  220. package/dist/mcp/template/src/stats.json +7 -0
  221. package/dist/mcp/template/src/tiles/block.tile.json +21 -0
  222. package/dist/mcp/template/src/tiles/decor.tile.json +14 -0
  223. package/dist/mcp/template/src/tiles/platform.tile.json +21 -0
  224. package/dist/mcp/template/src/ui/coin-counter.html +12 -0
  225. package/dist/mcp/template/tsconfig.json +15 -0
  226. package/dist/mcp/template/vite.config.ts +3 -0
  227. package/dist/mcp/validation.js +323 -0
  228. package/dist/mcp/workspace-loader.js +14 -0
  229. package/dist/mcp/workspace-runtime.js +109 -0
  230. package/dist/server.js +210 -0
  231. package/package.json +38 -0
@@ -0,0 +1,112 @@
1
+ import * as THREE from 'three';
2
+ import { Component } from '../component.js';
3
+ const loader = new THREE.TextureLoader();
4
+ /**
5
+ * Textured or flat-color quad. In the unified pipeline, a 2D sprite is a
6
+ * plane in front of the orthographic camera (see DESIGN.md §6, decision 2).
7
+ */
8
+ export class Sprite extends Component {
9
+ static componentName = 'Sprite';
10
+ static params = {
11
+ offsetX: { label: 'x offset' },
12
+ offsetY: { label: 'y offset' },
13
+ layer: { label: 'layer', min: -5, max: 5, step: 1 },
14
+ };
15
+ // Size, color and offset are reactive so inspector edits update the live quad.
16
+ // Texture still needs a rebuild. TODO(H1): fully reactive props.
17
+ _width = 1;
18
+ _height = 1;
19
+ get width() {
20
+ return this._width;
21
+ }
22
+ set width(value) {
23
+ this._width = value;
24
+ this.mesh?.scale.set(this._width, this._height, 1);
25
+ }
26
+ get height() {
27
+ return this._height;
28
+ }
29
+ set height(value) {
30
+ this._height = value;
31
+ this.mesh?.scale.set(this._width, this._height, 1);
32
+ }
33
+ _color = 0xffffff;
34
+ get color() {
35
+ return this._color;
36
+ }
37
+ set color(value) {
38
+ this._color = value;
39
+ this.mesh?.material.color.setHex(value);
40
+ }
41
+ _offsetX = 0;
42
+ _offsetY = 0;
43
+ get offsetX() {
44
+ return this._offsetX;
45
+ }
46
+ set offsetX(value) {
47
+ this._offsetX = value;
48
+ if (this.mesh)
49
+ this.mesh.position.x = value;
50
+ }
51
+ get offsetY() {
52
+ return this._offsetY;
53
+ }
54
+ set offsetY(value) {
55
+ this._offsetY = value;
56
+ if (this.mesh)
57
+ this.mesh.position.y = value;
58
+ }
59
+ /** Optional texture URL; with pixelArt on it filters in nearest. */
60
+ texture;
61
+ pixelArt = false;
62
+ // Draw order among sprites: higher layers render in front. Same-layer
63
+ // sprites fall back to spawn order, so give overlap an explicit layer.
64
+ _layer = 0;
65
+ get layer() {
66
+ return this._layer;
67
+ }
68
+ set layer(value) {
69
+ this._layer = value;
70
+ if (this.mesh)
71
+ this.mesh.position.z = value * 0.01;
72
+ }
73
+ _shape = 'rectangle';
74
+ get shape() {
75
+ return this._shape;
76
+ }
77
+ set shape(value) {
78
+ this._shape = value === 'circle' ? 'circle' : 'rectangle';
79
+ if (!this.mesh)
80
+ return;
81
+ this.mesh.geometry.dispose();
82
+ this.mesh.geometry = this.createGeometry();
83
+ }
84
+ mesh;
85
+ onReady() {
86
+ const material = new THREE.MeshBasicMaterial({ color: this.color, transparent: true });
87
+ if (this.texture) {
88
+ const tex = loader.load(this.texture);
89
+ if (this.pixelArt) {
90
+ tex.magFilter = THREE.NearestFilter;
91
+ tex.minFilter = THREE.NearestFilter;
92
+ }
93
+ tex.colorSpace = THREE.SRGBColorSpace;
94
+ material.map = tex;
95
+ material.color.set(0xffffff);
96
+ }
97
+ this.mesh = new THREE.Mesh(this.createGeometry(), material);
98
+ this.mesh.scale.set(this._width, this._height, 1);
99
+ this.mesh.position.set(this._offsetX, this._offsetY, this.layer * 0.01);
100
+ this.entity.node.add(this.mesh);
101
+ }
102
+ onDestroy() {
103
+ this.mesh?.removeFromParent();
104
+ this.mesh?.geometry.dispose();
105
+ this.mesh?.material.dispose();
106
+ }
107
+ createGeometry() {
108
+ return this._shape === 'circle'
109
+ ? new THREE.CircleGeometry(0.5, 32)
110
+ : new THREE.PlaneGeometry(1, 1);
111
+ }
112
+ }
@@ -0,0 +1,22 @@
1
+ import * as THREE from 'three';
2
+ import type { Component, ComponentClass } from './component.js';
3
+ import type { Game } from './game.js';
4
+ /**
5
+ * A live scene node: a transform (three Group) + components.
6
+ * Created with `game.spawn(name)`.
7
+ */
8
+ export declare class Entity {
9
+ readonly game: Game;
10
+ readonly name: string;
11
+ readonly node: THREE.Group<THREE.Object3DEventMap>;
12
+ readonly components: Component[];
13
+ private destroyed;
14
+ get alive(): boolean;
15
+ constructor(game: Game, name: string);
16
+ get position(): THREE.Vector3;
17
+ get scale(): THREE.Vector3;
18
+ add<T extends Component>(Class: ComponentClass<T>, props?: Partial<T>): T;
19
+ get<T extends Component>(Class: ComponentClass<T>): T | undefined;
20
+ has<T extends Component>(Class: ComponentClass<T>): boolean;
21
+ destroy(): void;
22
+ }
@@ -0,0 +1,52 @@
1
+ import * as THREE from 'three';
2
+ /**
3
+ * A live scene node: a transform (three Group) + components.
4
+ * Created with `game.spawn(name)`.
5
+ */
6
+ export class Entity {
7
+ game;
8
+ name;
9
+ node = new THREE.Group();
10
+ components = [];
11
+ destroyed = false;
12
+ get alive() {
13
+ return !this.destroyed;
14
+ }
15
+ constructor(game, name) {
16
+ this.game = game;
17
+ this.name = name;
18
+ }
19
+ get position() {
20
+ return this.node.position;
21
+ }
22
+ get scale() {
23
+ return this.node.scale;
24
+ }
25
+ add(Class, props) {
26
+ const component = new Class();
27
+ component.entity = this;
28
+ component.game = this.game;
29
+ if (props)
30
+ Object.assign(component, props);
31
+ this.game.applyParamOverrides(this, component);
32
+ this.components.push(component);
33
+ component.onReady?.();
34
+ return component;
35
+ }
36
+ get(Class) {
37
+ return this.components.find((c) => c instanceof Class);
38
+ }
39
+ has(Class) {
40
+ return this.components.some((c) => c instanceof Class);
41
+ }
42
+ destroy() {
43
+ if (this.destroyed)
44
+ return;
45
+ this.destroyed = true;
46
+ for (const c of [...this.components])
47
+ c.onDestroy?.();
48
+ this.components.length = 0;
49
+ this.node.removeFromParent();
50
+ this.game.removeEntity(this);
51
+ }
52
+ }
@@ -0,0 +1,8 @@
1
+ type Handler = (...args: unknown[]) => void;
2
+ /** The game's minimal event bus (e.g. 'collect' when picking up a coin). */
3
+ export declare class Emitter {
4
+ private readonly handlers;
5
+ on(event: string, handler: Handler): () => void;
6
+ emit(event: string, ...args: unknown[]): void;
7
+ }
8
+ export {};
@@ -0,0 +1,20 @@
1
+ /** The game's minimal event bus (e.g. 'collect' when picking up a coin). */
2
+ export class Emitter {
3
+ handlers = new Map();
4
+ on(event, handler) {
5
+ let set = this.handlers.get(event);
6
+ if (!set) {
7
+ set = new Set();
8
+ this.handlers.set(event, set);
9
+ }
10
+ set.add(handler);
11
+ return () => set.delete(handler);
12
+ }
13
+ emit(event, ...args) {
14
+ const set = this.handlers.get(event);
15
+ if (!set)
16
+ return;
17
+ for (const handler of [...set])
18
+ handler(...args);
19
+ }
20
+ }
@@ -0,0 +1,95 @@
1
+ import * as THREE from 'three';
2
+ import { type SceneCameraJson } from './camera.js';
3
+ import type { Component } from './component.js';
4
+ import { Entity } from './entity.js';
5
+ import { Emitter } from './events.js';
6
+ import { Input, type InputBindings } from './input.js';
7
+ import { type SceneRegistry } from './scene.js';
8
+ import { Stats, type StatValue } from './stats.js';
9
+ import { GameUi } from './ui.js';
10
+ /** Fixed game resolution: the view keeps this aspect, letterboxed. */
11
+ export interface GameResolution {
12
+ width: number;
13
+ height: number;
14
+ }
15
+ export interface GameOptions {
16
+ /** Canvas the game draws into. */
17
+ canvas: HTMLCanvasElement;
18
+ /** Scene background color. */
19
+ background?: THREE.ColorRepresentation;
20
+ /** Visible world height in units; the 2D camera frames this. */
21
+ viewHeight?: number;
22
+ /** Fixed resolution (from the project's game.json); absent = fill the canvas. */
23
+ resolution?: GameResolution;
24
+ /** Control overrides (action → key codes) on top of the defaults. */
25
+ bindings?: InputBindings;
26
+ /** Initial stat values (points, lives…) from the project's stats.json. */
27
+ stats?: Record<string, StatValue>;
28
+ }
29
+ export type UpdateFn = (dt: number) => void;
30
+ export interface SpawnPrefabOptions {
31
+ name?: string;
32
+ position?: [number, number];
33
+ }
34
+ /** Persisted overrides: entity → componentName → prop → value. */
35
+ export type ParamOverrides = Record<string, Record<string, Record<string, number | boolean | string>>>;
36
+ /**
37
+ * Engine core: loop, unified 2D/3D three scene, orthographic camera,
38
+ * entities with components, and input. See DESIGN.md.
39
+ */
40
+ export declare class Game {
41
+ readonly scene: THREE.Scene<THREE.Object3DEventMap>;
42
+ readonly camera: THREE.OrthographicCamera;
43
+ readonly input: Input;
44
+ readonly entities: Entity[];
45
+ readonly events: Emitter;
46
+ readonly stats: Stats;
47
+ /** The HTML UI layer: presentation-only pieces toggled from code. */
48
+ readonly ui: GameUi;
49
+ /** Registry retained by loadScene for runtime prefab spawning. */
50
+ registry: SceneRegistry | null;
51
+ paramOverrides: ParamOverrides;
52
+ /**
53
+ * With false, the loop keeps rendering but runs no component updates
54
+ * or collisions — the editor's edit mode.
55
+ */
56
+ simulate: boolean;
57
+ private readonly renderer;
58
+ private readonly resizeObserver;
59
+ private readonly updateFns;
60
+ private readonly resolution;
61
+ private viewHeight;
62
+ private sceneCamera;
63
+ private lastTime;
64
+ constructor(options: GameOptions);
65
+ /** Creates a live entity in the scene. */
66
+ spawn(name: string): Entity;
67
+ /** Instantiates a registered prefab after a scene has supplied the registry. */
68
+ spawnPrefab(prefab: string, options?: SpawnPrefabOptions): Entity | null;
69
+ /** Finds an entity by name. */
70
+ find(name: string): Entity | undefined;
71
+ /** Loads persisted parameter overrides (waica.params.json). */
72
+ loadParams(url: string): Promise<void>;
73
+ /** Applies persisted overrides to a freshly added component. */
74
+ applyParamOverrides(entity: Entity, component: Component): void;
75
+ /** Registers a function that runs once per frame. Returns the unsubscribe. */
76
+ onUpdate(fn: UpdateFn): () => void;
77
+ /**
78
+ * Adopts a scene's camera block: jumps to its framing and, while
79
+ * simulating, follows/clamps per its settings. Called by loadScene.
80
+ */
81
+ setSceneCamera(json?: SceneCameraJson): void;
82
+ start(): void;
83
+ stop(): void;
84
+ /** Internal: called by Entity.destroy(). */
85
+ removeEntity(entity: Entity): void;
86
+ /** Visible world height (2D camera zoom). */
87
+ get view(): number;
88
+ setViewHeight(value: number): void;
89
+ /** Shuts the game down completely (loop, input, GPU). */
90
+ dispose(): void;
91
+ private tick;
92
+ private updateSceneCamera;
93
+ private dispatchCollisions;
94
+ private resize;
95
+ }
@@ -0,0 +1,263 @@
1
+ import * as THREE from 'three';
2
+ import { collisionOverlap } from './collision-shape.js';
3
+ import { resolveSceneCamera, stepSceneCamera } from './camera.js';
4
+ import { Hitbox } from './components/hitbox.js';
5
+ import { Entity } from './entity.js';
6
+ import { Emitter } from './events.js';
7
+ import { Input } from './input.js';
8
+ import { registryEntry, spawnFromJson } from './scene.js';
9
+ import { Stats } from './stats.js';
10
+ import { GameUi } from './ui.js';
11
+ /**
12
+ * Engine core: loop, unified 2D/3D three scene, orthographic camera,
13
+ * entities with components, and input. See DESIGN.md.
14
+ */
15
+ export class Game {
16
+ scene = new THREE.Scene();
17
+ camera;
18
+ input;
19
+ entities = [];
20
+ events = new Emitter();
21
+ stats;
22
+ /** The HTML UI layer: presentation-only pieces toggled from code. */
23
+ ui;
24
+ /** Registry retained by loadScene for runtime prefab spawning. */
25
+ registry = null;
26
+ paramOverrides = {};
27
+ /**
28
+ * With false, the loop keeps rendering but runs no component updates
29
+ * or collisions — the editor's edit mode.
30
+ */
31
+ simulate = true;
32
+ // TODO(H1): migrate to WebGPURenderer (three/webgpu) with automatic WebGL2 fallback.
33
+ renderer;
34
+ resizeObserver;
35
+ updateFns = new Set();
36
+ resolution;
37
+ viewHeight;
38
+ sceneCamera = null;
39
+ lastTime = 0;
40
+ constructor(options) {
41
+ const { canvas, background = 0x1a1a2e, viewHeight = 10 } = options;
42
+ this.viewHeight = viewHeight;
43
+ this.resolution = options.resolution ?? null;
44
+ this.input = new Input(options.bindings);
45
+ this.stats = new Stats(options.stats);
46
+ this.ui = new GameUi(this.stats, () => canvas.parentElement ?? document.body);
47
+ this.renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
48
+ this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
49
+ this.scene.background = new THREE.Color(background);
50
+ this.camera = new THREE.OrthographicCamera();
51
+ this.camera.position.z = 10;
52
+ this.resize();
53
+ this.resizeObserver = new ResizeObserver(() => this.resize());
54
+ this.resizeObserver.observe(canvas);
55
+ }
56
+ /** Creates a live entity in the scene. */
57
+ spawn(name) {
58
+ const entity = new Entity(this, name);
59
+ this.entities.push(entity);
60
+ this.scene.add(entity.node);
61
+ return entity;
62
+ }
63
+ /** Instantiates a registered prefab after a scene has supplied the registry. */
64
+ spawnPrefab(prefab, options = {}) {
65
+ const registry = this.registry;
66
+ if (!registry) {
67
+ console.warn(`[waica] cannot spawn prefab before loadScene: "${prefab}"`);
68
+ return null;
69
+ }
70
+ if (!registryEntry(registry.prefabs, prefab)) {
71
+ console.warn(`[waica] unknown runtime prefab: "${prefab}"`);
72
+ return null;
73
+ }
74
+ const base = prefab.slice(prefab.lastIndexOf('/') + 1) || 'Entity';
75
+ const name = options.name ?? base.charAt(0).toUpperCase() + base.slice(1);
76
+ return spawnFromJson(this, { name, prefab, ...(options.position ? { position: options.position } : {}) }, registry);
77
+ }
78
+ /** Finds an entity by name. */
79
+ find(name) {
80
+ return this.entities.find((e) => e.name === name);
81
+ }
82
+ /** Loads persisted parameter overrides (waica.params.json). */
83
+ async loadParams(url) {
84
+ try {
85
+ const res = await fetch(url);
86
+ if (res.ok)
87
+ this.paramOverrides = (await res.json());
88
+ }
89
+ catch {
90
+ // no params file: the archetype defaults apply
91
+ }
92
+ }
93
+ /** Applies persisted overrides to a freshly added component. */
94
+ applyParamOverrides(entity, component) {
95
+ const Class = component.constructor;
96
+ const override = this.paramOverrides[entity.name]?.[Class.componentName];
97
+ if (override)
98
+ Object.assign(component, override);
99
+ }
100
+ /** Registers a function that runs once per frame. Returns the unsubscribe. */
101
+ onUpdate(fn) {
102
+ this.updateFns.add(fn);
103
+ return () => this.updateFns.delete(fn);
104
+ }
105
+ /**
106
+ * Adopts a scene's camera block: jumps to its framing and, while
107
+ * simulating, follows/clamps per its settings. Called by loadScene.
108
+ */
109
+ setSceneCamera(json) {
110
+ // No camera block: leave the camera to the host (constructor viewHeight).
111
+ if (!json) {
112
+ this.sceneCamera = null;
113
+ return;
114
+ }
115
+ this.sceneCamera = resolveSceneCamera(json);
116
+ // With a follow target the declared position is moot: start centered on
117
+ // the target so play begins framed like the editor shows it.
118
+ const followed = this.sceneCamera.follow ? this.find(this.sceneCamera.follow) : undefined;
119
+ const [x, y] = followed
120
+ ? [followed.position.x, followed.position.y]
121
+ : this.sceneCamera.position;
122
+ this.camera.position.x = x;
123
+ this.camera.position.y = y;
124
+ this.setViewHeight(this.sceneCamera.zoom);
125
+ }
126
+ start() {
127
+ this.renderer.setAnimationLoop((time) => this.tick(time));
128
+ }
129
+ stop() {
130
+ this.renderer.setAnimationLoop(null);
131
+ }
132
+ /** Internal: called by Entity.destroy(). */
133
+ removeEntity(entity) {
134
+ const i = this.entities.indexOf(entity);
135
+ if (i !== -1)
136
+ this.entities.splice(i, 1);
137
+ }
138
+ /** Visible world height (2D camera zoom). */
139
+ get view() {
140
+ return this.viewHeight;
141
+ }
142
+ setViewHeight(value) {
143
+ this.viewHeight = Math.min(Math.max(value, 2), 80);
144
+ this.resize();
145
+ }
146
+ /** Shuts the game down completely (loop, input, GPU). */
147
+ dispose() {
148
+ this.stop();
149
+ this.input.dispose();
150
+ this.resizeObserver.disconnect();
151
+ this.ui.dispose();
152
+ for (const entity of [...this.entities])
153
+ entity.destroy();
154
+ this.renderer.dispose();
155
+ }
156
+ tick(time) {
157
+ // Clamp dt: switching tabs or pausing doesn't fast-forward the simulation.
158
+ const dt = Math.min((time - this.lastTime) / 1000, 0.1);
159
+ this.lastTime = time;
160
+ if (this.simulate) {
161
+ for (const entity of [...this.entities]) {
162
+ for (const component of [...entity.components])
163
+ component.onUpdate?.(dt);
164
+ }
165
+ this.dispatchCollisions();
166
+ this.updateSceneCamera(dt);
167
+ }
168
+ // The UI must react to the pause itself (hide until resumed).
169
+ this.ui.setActive(this.simulate);
170
+ for (const fn of this.updateFns)
171
+ fn(dt);
172
+ this.input.endFrame();
173
+ if (this.resolution) {
174
+ // Letterbox bars: clear the whole canvas, then render inside the scissor.
175
+ this.renderer.setScissorTest(false);
176
+ this.renderer.setClearColor(0x000000, 1);
177
+ this.renderer.clear(true, false, false);
178
+ this.renderer.setScissorTest(true);
179
+ }
180
+ this.renderer.render(this.scene, this.camera);
181
+ }
182
+ updateSceneCamera(dt) {
183
+ const cam = this.sceneCamera;
184
+ if (!cam)
185
+ return;
186
+ const followed = cam.follow ? this.find(cam.follow) : undefined;
187
+ const mover = followed?.components.find((c) => typeof c.vx === 'number');
188
+ const next = stepSceneCamera(cam, {
189
+ x: this.camera.position.x,
190
+ y: this.camera.position.y,
191
+ halfW: (this.camera.right - this.camera.left) / 2,
192
+ halfH: this.viewHeight / 2,
193
+ target: followed ? { x: followed.position.x, y: followed.position.y } : null,
194
+ vx: mover?.vx ?? 0,
195
+ dt,
196
+ });
197
+ this.camera.position.x = next.x;
198
+ this.camera.position.y = next.y;
199
+ }
200
+ dispatchCollisions() {
201
+ const boxed = this.entities.filter((e) => e.has(Hitbox));
202
+ for (let i = 0; i < boxed.length; i++) {
203
+ for (let j = i + 1; j < boxed.length; j++) {
204
+ const a = boxed[i];
205
+ const b = boxed[j];
206
+ if (!a?.alive || !b?.alive)
207
+ continue;
208
+ const ha = a.get(Hitbox);
209
+ const hb = b.get(Hitbox);
210
+ if (!ha || !hb)
211
+ continue;
212
+ const hit = collisionOverlap({
213
+ x: a.position.x + ha.offsetX,
214
+ y: a.position.y + ha.offsetY,
215
+ width: ha.width,
216
+ height: ha.height,
217
+ shape: ha.shape,
218
+ points: ha.points,
219
+ }, {
220
+ x: b.position.x + hb.offsetX,
221
+ y: b.position.y + hb.offsetY,
222
+ width: hb.width,
223
+ height: hb.height,
224
+ shape: hb.shape,
225
+ points: hb.points,
226
+ });
227
+ if (!hit)
228
+ continue;
229
+ for (const c of [...a.components])
230
+ c.onCollide?.(b);
231
+ if (!a.alive || !b.alive)
232
+ continue;
233
+ for (const c of [...b.components])
234
+ c.onCollide?.(a);
235
+ }
236
+ }
237
+ }
238
+ resize() {
239
+ const canvas = this.renderer.domElement;
240
+ const { clientWidth: w, clientHeight: h } = canvas;
241
+ if (w === 0 || h === 0)
242
+ return;
243
+ this.renderer.setSize(w, h, false);
244
+ let aspect = w / h;
245
+ if (this.resolution) {
246
+ // Fixed resolution: the largest rect with its aspect, centered (letterbox).
247
+ aspect = this.resolution.width / this.resolution.height;
248
+ const vw = Math.min(w, h * aspect);
249
+ const vh = vw / aspect;
250
+ const vx = (w - vw) / 2;
251
+ const vy = (h - vh) / 2;
252
+ this.renderer.setViewport(vx, vy, vw, vh);
253
+ this.renderer.setScissor(vx, vy, vw, vh);
254
+ }
255
+ const halfH = this.viewHeight / 2;
256
+ const halfW = halfH * aspect;
257
+ this.camera.left = -halfW;
258
+ this.camera.right = halfW;
259
+ this.camera.top = halfH;
260
+ this.camera.bottom = -halfH;
261
+ this.camera.updateProjectionMatrix();
262
+ }
263
+ }
@@ -0,0 +1,39 @@
1
+ export { Game } from './game.js';
2
+ export type { GameOptions, GameResolution, SpawnPrefabOptions, UpdateFn, ParamOverrides, } from './game.js';
3
+ export { CAMERA_DEFAULTS, resolveSceneCamera, stepSceneCamera } from './camera.js';
4
+ export type { SceneCameraJson, CameraLimitsJson, ResolvedSceneCamera } from './camera.js';
5
+ export { Entity } from './entity.js';
6
+ export { Component } from './component.js';
7
+ export type { ComponentClass, ContactNormal, ParamSpec, SolidContact, } from './component.js';
8
+ export { collectModuleComponents, mergeRegistryComponents } from './component-registry.js';
9
+ export type { ComponentModule } from './component-registry.js';
10
+ export { Input, DEFAULT_BINDINGS } from './input.js';
11
+ export type { ActionName, InputBindings } from './input.js';
12
+ export type { ArchetypeArt, ArchetypeManifest, BrowserArchetypeManifest, EntityTemplate, } from './archetype.js';
13
+ export { Stats } from './stats.js';
14
+ export type { StatValue } from './stats.js';
15
+ export { GameUi } from './ui.js';
16
+ export { Sprite } from './components/sprite.js';
17
+ export { Solid } from './components/solid.js';
18
+ export { Hitbox } from './components/hitbox.js';
19
+ export { DynamicBody } from './components/dynamic-body.js';
20
+ export { AnimatedSprite } from './components/animated-sprite.js';
21
+ export { aabbOverlap } from './aabb.js';
22
+ export { resolveSolidAxis } from './solid-axis.js';
23
+ export type { CollisionAxis, SolidAxisOptions } from './solid-axis.js';
24
+ export { COLLISION_SHAPES, DEFAULT_COLLISION_POLYGON, collisionBounds, collisionOverlap, collisionVertices, resolveCollisionPoints, } from './collision-shape.js';
25
+ export type { CollisionBody, CollisionBounds, CollisionPoint, CollisionShape, } from './collision-shape.js';
26
+ export { Emitter } from './events.js';
27
+ export { loadScene, spawnFromJson, resolveEntityComponents, resolveProps } from './scene.js';
28
+ export type { SceneJson, SceneEntityJson, SceneComponentJson, SceneRegistry, PrefabJson } from './scene.js';
29
+ export { ClipPlayer } from './animation/clip-player.js';
30
+ export type { ClipDef } from './animation/clip-player.js';
31
+ export { sheetCell, sheetFrameCount, locateFrame } from './animation/sheet.js';
32
+ export type { SheetGridParams, SheetCell, SheetDef } from './animation/sheet.js';
33
+ export { resolveClip, missingClips } from './animation/contract.js';
34
+ export type { AnimationContract } from './animation/contract.js';
35
+ export { StateMachine, evaluateTrigger, nextTransition } from './state/state-machine.js';
36
+ export type { StateJson, StateTransitionJson, TriggerEnv } from './state/state-machine.js';
37
+ export { defineRole, defineStates, installArchetype, logicSet, registeredLogicSets, registeredRoles, resetRegistries, roleDefinition, } from './state/hooks.js';
38
+ export type { ArchetypeBundle, RoleDefinition, RoleGraph, StateContext, StateHooks, StateLogic, } from './state/hooks.js';
39
+ export * as THREE from 'three';
@@ -0,0 +1,26 @@
1
+ export { Game } from './game.js';
2
+ export { CAMERA_DEFAULTS, resolveSceneCamera, stepSceneCamera } from './camera.js';
3
+ export { Entity } from './entity.js';
4
+ export { Component } from './component.js';
5
+ export { collectModuleComponents, mergeRegistryComponents } from './component-registry.js';
6
+ export { Input, DEFAULT_BINDINGS } from './input.js';
7
+ export { Stats } from './stats.js';
8
+ export { GameUi } from './ui.js';
9
+ export { Sprite } from './components/sprite.js';
10
+ export { Solid } from './components/solid.js';
11
+ export { Hitbox } from './components/hitbox.js';
12
+ export { DynamicBody } from './components/dynamic-body.js';
13
+ export { AnimatedSprite } from './components/animated-sprite.js';
14
+ export { aabbOverlap } from './aabb.js';
15
+ export { resolveSolidAxis } from './solid-axis.js';
16
+ export { COLLISION_SHAPES, DEFAULT_COLLISION_POLYGON, collisionBounds, collisionOverlap, collisionVertices, resolveCollisionPoints, } from './collision-shape.js';
17
+ export { Emitter } from './events.js';
18
+ export { loadScene, spawnFromJson, resolveEntityComponents, resolveProps } from './scene.js';
19
+ export { ClipPlayer } from './animation/clip-player.js';
20
+ export { sheetCell, sheetFrameCount, locateFrame } from './animation/sheet.js';
21
+ export { resolveClip, missingClips } from './animation/contract.js';
22
+ export { StateMachine, evaluateTrigger, nextTransition } from './state/state-machine.js';
23
+ export { defineRole, defineStates, installArchetype, logicSet, registeredLogicSets, registeredRoles, resetRegistries, roleDefinition, } from './state/hooks.js';
24
+ // Explicit escape hatch while our own API grows: a single source of three
25
+ // for the whole workspace. The thesis is that three stays an implementation detail.
26
+ export * as THREE from 'three';
@@ -0,0 +1,40 @@
1
+ export type ActionName = string;
2
+ /** Action → KeyboardEvent.code list. */
3
+ export type InputBindings = Record<string, string[]>;
4
+ /** Neutral engine baseline; archetypes own their action vocabulary. */
5
+ export declare const DEFAULT_BINDINGS: Readonly<InputBindings>;
6
+ /**
7
+ * Action-based input with archetype default bindings.
8
+ * v0: keyboard. TODO(H1): gamepad and touch.
9
+ */
10
+ export declare class Input {
11
+ private readonly bindings;
12
+ private readonly down;
13
+ private readonly justDown;
14
+ private readonly used;
15
+ /** Installs exactly the action map supplied by the active archetype/project. */
16
+ constructor(bindings?: Readonly<InputBindings>);
17
+ /** Is the action held this frame? */
18
+ held(action: ActionName): boolean;
19
+ /** Was the action pressed exactly this frame? */
20
+ justPressed(action: ActionName): boolean;
21
+ /** -1..1 axis from two actions (left/right by default). */
22
+ axis(negative?: ActionName, positive?: ActionName): number;
23
+ /**
24
+ * Marks this frame's press of the action as spent, so consumers that
25
+ * honor consumption (state-machine 'input:' triggers) ignore it. One
26
+ * press does one thing: the press that launches a ground jump can't
27
+ * also fire a "key press jump" transition on the very same frame.
28
+ */
29
+ consume(action: ActionName): void;
30
+ /** Was this frame's press already spent by someone? */
31
+ consumed(action: ActionName): boolean;
32
+ /** Called by the Game at the end of each frame. */
33
+ endFrame(): void;
34
+ dispose(): void;
35
+ private isActive;
36
+ private releaseAll;
37
+ private onVisibilityChange;
38
+ private onKeyDown;
39
+ private onKeyUp;
40
+ }