rn-gamekit 0.1.0 → 0.2.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 (601) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +97 -16
  3. package/lib/module/assets/defineAssets.js +28 -3
  4. package/lib/module/assets/defineAssets.js.map +1 -1
  5. package/lib/module/assets.js +11 -0
  6. package/lib/module/assets.js.map +1 -0
  7. package/lib/module/audio/createGameAudio.js +784 -0
  8. package/lib/module/audio/createGameAudio.js.map +1 -0
  9. package/lib/module/audio/errors.js +12 -0
  10. package/lib/module/audio/errors.js.map +1 -0
  11. package/lib/module/audio/index.js +5 -0
  12. package/lib/module/audio/index.js.map +1 -0
  13. package/lib/module/audio/resolver.js +37 -0
  14. package/lib/module/audio/resolver.js.map +1 -0
  15. package/lib/module/audio/types.js +4 -0
  16. package/lib/module/audio/types.js.map +1 -0
  17. package/lib/module/audio.js +9 -0
  18. package/lib/module/audio.js.map +1 -0
  19. package/lib/module/camera2d/bounds.js +59 -0
  20. package/lib/module/camera2d/bounds.js.map +1 -0
  21. package/lib/module/camera2d/extents.js +25 -0
  22. package/lib/module/camera2d/extents.js.map +1 -0
  23. package/lib/module/camera2d/follow.js +138 -0
  24. package/lib/module/camera2d/follow.js.map +1 -0
  25. package/lib/module/camera2d/index.js +20 -0
  26. package/lib/module/camera2d/index.js.map +1 -0
  27. package/lib/module/camera2d/interpolation.js +98 -0
  28. package/lib/module/camera2d/interpolation.js.map +1 -0
  29. package/lib/module/camera2d/shake.js +85 -0
  30. package/lib/module/camera2d/shake.js.map +1 -0
  31. package/lib/module/camera2d/transform.js +151 -0
  32. package/lib/module/camera2d/transform.js.map +1 -0
  33. package/lib/module/camera2d/types.js +4 -0
  34. package/lib/module/camera2d/types.js.map +1 -0
  35. package/lib/module/camera2d/validation.js +98 -0
  36. package/lib/module/camera2d/validation.js.map +1 -0
  37. package/lib/module/camera2d/visibility.js +138 -0
  38. package/lib/module/camera2d/visibility.js.map +1 -0
  39. package/lib/module/camera2d.js +9 -0
  40. package/lib/module/camera2d.js.map +1 -0
  41. package/lib/module/collision2d/colliders.js +266 -0
  42. package/lib/module/collision2d/colliders.js.map +1 -0
  43. package/lib/module/collision2d/debug.js +105 -0
  44. package/lib/module/collision2d/debug.js.map +1 -0
  45. package/lib/module/collision2d/filters.js +40 -0
  46. package/lib/module/collision2d/filters.js.map +1 -0
  47. package/lib/module/collision2d/index.js +12 -0
  48. package/lib/module/collision2d/index.js.map +1 -0
  49. package/lib/module/collision2d/intersections.js +67 -0
  50. package/lib/module/collision2d/intersections.js.map +1 -0
  51. package/lib/module/collision2d/manifolds.js +218 -0
  52. package/lib/module/collision2d/manifolds.js.map +1 -0
  53. package/lib/module/collision2d/segments.js +187 -0
  54. package/lib/module/collision2d/segments.js.map +1 -0
  55. package/lib/module/collision2d/spatialHash.js +167 -0
  56. package/lib/module/collision2d/spatialHash.js.map +1 -0
  57. package/lib/module/collision2d/sweeps.js +255 -0
  58. package/lib/module/collision2d/sweeps.js.map +1 -0
  59. package/lib/module/collision2d.js +9 -0
  60. package/lib/module/collision2d.js.map +1 -0
  61. package/lib/module/core/input/buttonPad.js +214 -0
  62. package/lib/module/core/input/buttonPad.js.map +1 -0
  63. package/lib/module/core/input/createInputBuffer.js +66 -14
  64. package/lib/module/core/input/createInputBuffer.js.map +1 -1
  65. package/lib/module/core/session/createGameSession.js +454 -50
  66. package/lib/module/core/session/createGameSession.js.map +1 -1
  67. package/lib/module/core/session/deepFreeze.js +92 -2
  68. package/lib/module/core/session/deepFreeze.js.map +1 -1
  69. package/lib/module/core/session/types.js +12 -0
  70. package/lib/module/core/session/types.js.map +1 -1
  71. package/lib/module/definition/defineGame.js +23 -0
  72. package/lib/module/definition/defineGame.js.map +1 -1
  73. package/lib/module/events/defineGameEvents.js +46 -0
  74. package/lib/module/events/defineGameEvents.js.map +1 -0
  75. package/lib/module/events/errors.js +16 -0
  76. package/lib/module/events/errors.js.map +1 -0
  77. package/lib/module/events/index.js +7 -0
  78. package/lib/module/events/index.js.map +1 -0
  79. package/lib/module/events/payload.js +219 -0
  80. package/lib/module/events/payload.js.map +1 -0
  81. package/lib/module/events/seed.js +33 -0
  82. package/lib/module/events/seed.js.map +1 -0
  83. package/lib/module/events/types.js +4 -0
  84. package/lib/module/events/types.js.map +1 -0
  85. package/lib/module/events.js +13 -0
  86. package/lib/module/events.js.map +1 -0
  87. package/lib/module/geometry/helpers.js +140 -0
  88. package/lib/module/geometry/helpers.js.map +1 -0
  89. package/lib/module/geometry/index.js +5 -0
  90. package/lib/module/geometry/index.js.map +1 -0
  91. package/lib/module/geometry/validation.js +104 -0
  92. package/lib/module/geometry/validation.js.map +1 -0
  93. package/lib/module/geometry.js +9 -0
  94. package/lib/module/geometry.js.map +1 -0
  95. package/lib/module/haptics/createGameHaptics.js +214 -0
  96. package/lib/module/haptics/createGameHaptics.js.map +1 -0
  97. package/lib/module/haptics/errors.js +12 -0
  98. package/lib/module/haptics/errors.js.map +1 -0
  99. package/lib/module/haptics/index.js +5 -0
  100. package/lib/module/haptics/index.js.map +1 -0
  101. package/lib/module/haptics/resolver.js +37 -0
  102. package/lib/module/haptics/resolver.js.map +1 -0
  103. package/lib/module/haptics/types.js +4 -0
  104. package/lib/module/haptics/types.js.map +1 -0
  105. package/lib/module/haptics.js +9 -0
  106. package/lib/module/haptics.js.map +1 -0
  107. package/lib/module/index.js +8 -1
  108. package/lib/module/index.js.map +1 -1
  109. package/lib/module/particles/createParticleSystem.js +481 -0
  110. package/lib/module/particles/createParticleSystem.js.map +1 -0
  111. package/lib/module/particles/defineParticleEffect.js +178 -0
  112. package/lib/module/particles/defineParticleEffect.js.map +1 -0
  113. package/lib/module/particles/errors.js +9 -0
  114. package/lib/module/particles/errors.js.map +1 -0
  115. package/lib/module/particles/index.js +8 -0
  116. package/lib/module/particles/index.js.map +1 -0
  117. package/lib/module/particles/sampling.js +121 -0
  118. package/lib/module/particles/sampling.js.map +1 -0
  119. package/lib/module/particles/types.js +4 -0
  120. package/lib/module/particles/types.js.map +1 -0
  121. package/lib/module/particles.js +4 -0
  122. package/lib/module/particles.js.map +1 -0
  123. package/lib/module/react/GameButtonPad.js +344 -0
  124. package/lib/module/react/GameButtonPad.js.map +1 -0
  125. package/lib/module/react/GamePointerInput.js +74 -16
  126. package/lib/module/react/GamePointerInput.js.map +1 -1
  127. package/lib/module/react/GameView.js +139 -60
  128. package/lib/module/react/GameView.js.map +1 -1
  129. package/lib/module/react/assets/createGameAssetStore.js +145 -95
  130. package/lib/module/react/assets/createGameAssetStore.js.map +1 -1
  131. package/lib/module/react/assets/useGameAssets.js +60 -35
  132. package/lib/module/react/assets/useGameAssets.js.map +1 -1
  133. package/lib/module/react/bindAppLifecycle.js +46 -17
  134. package/lib/module/react/bindAppLifecycle.js.map +1 -1
  135. package/lib/module/react/bindGameSession.js +13 -2
  136. package/lib/module/react/bindGameSession.js.map +1 -1
  137. package/lib/module/react/camera2d/GameLayer2D.js +50 -0
  138. package/lib/module/react/camera2d/GameLayer2D.js.map +1 -0
  139. package/lib/module/react/camera2d/defineGameCamera2D.js +30 -0
  140. package/lib/module/react/camera2d/defineGameCamera2D.js.map +1 -0
  141. package/lib/module/react/camera2d/usePresentedCameraBinding.js +177 -0
  142. package/lib/module/react/camera2d/usePresentedCameraBinding.js.map +1 -0
  143. package/lib/module/react/cleanupList.js +38 -0
  144. package/lib/module/react/cleanupList.js.map +1 -0
  145. package/lib/module/react/lifecycleSource.js +49 -0
  146. package/lib/module/react/lifecycleSource.js.map +1 -0
  147. package/lib/module/react/particles/ParticleView.js +308 -0
  148. package/lib/module/react/particles/ParticleView.js.map +1 -0
  149. package/lib/module/react/particles/culling.js +115 -0
  150. package/lib/module/react/particles/culling.js.map +1 -0
  151. package/lib/module/react/particles/index.js +7 -0
  152. package/lib/module/react/particles/index.js.map +1 -0
  153. package/lib/module/react/particles/spriteXForm.js +45 -0
  154. package/lib/module/react/particles/spriteXForm.js.map +1 -0
  155. package/lib/module/react/particles/useParticlePresentation.js +204 -0
  156. package/lib/module/react/particles/useParticlePresentation.js.map +1 -0
  157. package/lib/module/react/pointerBinding.js +55 -17
  158. package/lib/module/react/pointerBinding.js.map +1 -1
  159. package/lib/module/react/pointerCamera.js +28 -0
  160. package/lib/module/react/pointerCamera.js.map +1 -0
  161. package/lib/module/react/pointerCoalescer.js +16 -9
  162. package/lib/module/react/pointerCoalescer.js.map +1 -1
  163. package/lib/module/react/sprites/GameSprite.js +5 -17
  164. package/lib/module/react/sprites/GameSprite.js.map +1 -1
  165. package/lib/module/react/sprites/GameWorld2D.js +112 -9
  166. package/lib/module/react/sprites/GameWorld2D.js.map +1 -1
  167. package/lib/module/react/sprites/Sprite.js +48 -63
  168. package/lib/module/react/sprites/Sprite.js.map +1 -1
  169. package/lib/module/react/sprites/SpriteBatch.js +53 -28
  170. package/lib/module/react/sprites/SpriteBatch.js.map +1 -1
  171. package/lib/module/react/sprites/batchVisibility.js +58 -0
  172. package/lib/module/react/sprites/batchVisibility.js.map +1 -0
  173. package/lib/module/react/sprites/spriteSelection.js +103 -0
  174. package/lib/module/react/sprites/spriteSelection.js.map +1 -0
  175. package/lib/module/react/sprites/spriteTransform.js +46 -25
  176. package/lib/module/react/sprites/spriteTransform.js.map +1 -1
  177. package/lib/module/react/tilemap/TileMapLayer2D.js +217 -0
  178. package/lib/module/react/tilemap/TileMapLayer2D.js.map +1 -0
  179. package/lib/module/react/tilemap/tilePresentation.js +374 -0
  180. package/lib/module/react/tilemap/tilePresentation.js.map +1 -0
  181. package/lib/module/react/useGameSession.js +70 -0
  182. package/lib/module/react/useGameSession.js.map +1 -0
  183. package/lib/module/react/useGameSessionStatus.js +46 -0
  184. package/lib/module/react/useGameSessionStatus.js.map +1 -0
  185. package/lib/module/react/viewportBinding.js +5 -1
  186. package/lib/module/react/viewportBinding.js.map +1 -1
  187. package/lib/module/react.js +12 -1
  188. package/lib/module/react.js.map +1 -1
  189. package/lib/module/scene/defineScene.js +17 -0
  190. package/lib/module/scene/defineScene.js.map +1 -1
  191. package/lib/module/sprites/sampleSpriteClip.js +66 -6
  192. package/lib/module/sprites/sampleSpriteClip.js.map +1 -1
  193. package/lib/module/sprites/spriteAnimationState.js +10 -20
  194. package/lib/module/sprites/spriteAnimationState.js.map +1 -1
  195. package/lib/module/sprites.js +11 -0
  196. package/lib/module/sprites.js.map +1 -0
  197. package/lib/module/storage/adapters/asyncStorage.js +57 -0
  198. package/lib/module/storage/adapters/asyncStorage.js.map +1 -0
  199. package/lib/module/storage/adapters/memory.js +50 -0
  200. package/lib/module/storage/adapters/memory.js.map +1 -0
  201. package/lib/module/storage/errors.js +34 -0
  202. package/lib/module/storage/errors.js.map +1 -0
  203. package/lib/module/storage/index.js +11 -0
  204. package/lib/module/storage/index.js.map +1 -0
  205. package/lib/module/storage/schema.js +151 -0
  206. package/lib/module/storage/schema.js.map +1 -0
  207. package/lib/module/storage/serialization.js +249 -0
  208. package/lib/module/storage/serialization.js.map +1 -0
  209. package/lib/module/storage/store.js +387 -0
  210. package/lib/module/storage/store.js.map +1 -0
  211. package/lib/module/storage/types.js +16 -0
  212. package/lib/module/storage/types.js.map +1 -0
  213. package/lib/module/storage/validation.js +111 -0
  214. package/lib/module/storage/validation.js.map +1 -0
  215. package/lib/module/storage.js +4 -0
  216. package/lib/module/storage.js.map +1 -0
  217. package/lib/module/testing.js +4 -0
  218. package/lib/module/testing.js.map +1 -1
  219. package/lib/module/tilemap/chunkStats.js +27 -0
  220. package/lib/module/tilemap/chunkStats.js.map +1 -0
  221. package/lib/module/tilemap/definitions.js +308 -0
  222. package/lib/module/tilemap/definitions.js.map +1 -0
  223. package/lib/module/tilemap/errors.js +13 -0
  224. package/lib/module/tilemap/errors.js.map +1 -0
  225. package/lib/module/tilemap/index.js +10 -0
  226. package/lib/module/tilemap/index.js.map +1 -0
  227. package/lib/module/tilemap/movement.js +379 -0
  228. package/lib/module/tilemap/movement.js.map +1 -0
  229. package/lib/module/tilemap/queries.js +114 -0
  230. package/lib/module/tilemap/queries.js.map +1 -0
  231. package/lib/module/tilemap/tiledAdapter.js +141 -0
  232. package/lib/module/tilemap/tiledAdapter.js.map +1 -0
  233. package/lib/module/tilemap/types.js +4 -0
  234. package/lib/module/tilemap/types.js.map +1 -0
  235. package/lib/module/tilemap.js +4 -0
  236. package/lib/module/tilemap.js.map +1 -0
  237. package/lib/typescript/src/assets/defineAssets.d.ts +1 -1
  238. package/lib/typescript/src/assets/defineAssets.d.ts.map +1 -1
  239. package/lib/typescript/src/assets.d.ts +11 -0
  240. package/lib/typescript/src/assets.d.ts.map +1 -0
  241. package/lib/typescript/src/audio/createGameAudio.d.ts +5 -0
  242. package/lib/typescript/src/audio/createGameAudio.d.ts.map +1 -0
  243. package/lib/typescript/src/audio/errors.d.ts +6 -0
  244. package/lib/typescript/src/audio/errors.d.ts.map +1 -0
  245. package/lib/typescript/src/audio/index.d.ts +4 -0
  246. package/lib/typescript/src/audio/index.d.ts.map +1 -0
  247. package/lib/typescript/src/audio/resolver.d.ts +44 -0
  248. package/lib/typescript/src/audio/resolver.d.ts.map +1 -0
  249. package/lib/typescript/src/audio/types.d.ts +42 -0
  250. package/lib/typescript/src/audio/types.d.ts.map +1 -0
  251. package/lib/typescript/src/audio.d.ts +8 -0
  252. package/lib/typescript/src/audio.d.ts.map +1 -0
  253. package/lib/typescript/src/camera2d/bounds.d.ts +25 -0
  254. package/lib/typescript/src/camera2d/bounds.d.ts.map +1 -0
  255. package/lib/typescript/src/camera2d/extents.d.ts +17 -0
  256. package/lib/typescript/src/camera2d/extents.d.ts.map +1 -0
  257. package/lib/typescript/src/camera2d/follow.d.ts +24 -0
  258. package/lib/typescript/src/camera2d/follow.d.ts.map +1 -0
  259. package/lib/typescript/src/camera2d/index.d.ts +19 -0
  260. package/lib/typescript/src/camera2d/index.d.ts.map +1 -0
  261. package/lib/typescript/src/camera2d/interpolation.d.ts +17 -0
  262. package/lib/typescript/src/camera2d/interpolation.d.ts.map +1 -0
  263. package/lib/typescript/src/camera2d/shake.d.ts +20 -0
  264. package/lib/typescript/src/camera2d/shake.d.ts.map +1 -0
  265. package/lib/typescript/src/camera2d/transform.d.ts +44 -0
  266. package/lib/typescript/src/camera2d/transform.d.ts.map +1 -0
  267. package/lib/typescript/src/camera2d/types.d.ts +74 -0
  268. package/lib/typescript/src/camera2d/types.d.ts.map +1 -0
  269. package/lib/typescript/src/camera2d/validation.d.ts +30 -0
  270. package/lib/typescript/src/camera2d/validation.d.ts.map +1 -0
  271. package/lib/typescript/src/camera2d/visibility.d.ts +47 -0
  272. package/lib/typescript/src/camera2d/visibility.d.ts.map +1 -0
  273. package/lib/typescript/src/camera2d.d.ts +7 -0
  274. package/lib/typescript/src/camera2d.d.ts.map +1 -0
  275. package/lib/typescript/src/collision2d/colliders.d.ts +120 -0
  276. package/lib/typescript/src/collision2d/colliders.d.ts.map +1 -0
  277. package/lib/typescript/src/collision2d/debug.d.ts +67 -0
  278. package/lib/typescript/src/collision2d/debug.d.ts.map +1 -0
  279. package/lib/typescript/src/collision2d/filters.d.ts +28 -0
  280. package/lib/typescript/src/collision2d/filters.d.ts.map +1 -0
  281. package/lib/typescript/src/collision2d/index.d.ts +17 -0
  282. package/lib/typescript/src/collision2d/index.d.ts.map +1 -0
  283. package/lib/typescript/src/collision2d/intersections.d.ts +24 -0
  284. package/lib/typescript/src/collision2d/intersections.d.ts.map +1 -0
  285. package/lib/typescript/src/collision2d/manifolds.d.ts +39 -0
  286. package/lib/typescript/src/collision2d/manifolds.d.ts.map +1 -0
  287. package/lib/typescript/src/collision2d/segments.d.ts +24 -0
  288. package/lib/typescript/src/collision2d/segments.d.ts.map +1 -0
  289. package/lib/typescript/src/collision2d/spatialHash.d.ts +50 -0
  290. package/lib/typescript/src/collision2d/spatialHash.d.ts.map +1 -0
  291. package/lib/typescript/src/collision2d/sweeps.d.ts +60 -0
  292. package/lib/typescript/src/collision2d/sweeps.d.ts.map +1 -0
  293. package/lib/typescript/src/collision2d.d.ts +7 -0
  294. package/lib/typescript/src/collision2d.d.ts.map +1 -0
  295. package/lib/typescript/src/core/input/buttonPad.d.ts +59 -0
  296. package/lib/typescript/src/core/input/buttonPad.d.ts.map +1 -0
  297. package/lib/typescript/src/core/input/createInputBuffer.d.ts +1 -1
  298. package/lib/typescript/src/core/input/createInputBuffer.d.ts.map +1 -1
  299. package/lib/typescript/src/core/input/types.d.ts +7 -0
  300. package/lib/typescript/src/core/input/types.d.ts.map +1 -1
  301. package/lib/typescript/src/core/session/createGameSession.d.ts +4 -2
  302. package/lib/typescript/src/core/session/createGameSession.d.ts.map +1 -1
  303. package/lib/typescript/src/core/session/deepFreeze.d.ts +21 -1
  304. package/lib/typescript/src/core/session/deepFreeze.d.ts.map +1 -1
  305. package/lib/typescript/src/core/session/diagnostics.d.ts +2 -0
  306. package/lib/typescript/src/core/session/diagnostics.d.ts.map +1 -1
  307. package/lib/typescript/src/core/session/types.d.ts +69 -4
  308. package/lib/typescript/src/core/session/types.d.ts.map +1 -1
  309. package/lib/typescript/src/definition/defineGame.d.ts +12 -1
  310. package/lib/typescript/src/definition/defineGame.d.ts.map +1 -1
  311. package/lib/typescript/src/definition/types.d.ts +10 -1
  312. package/lib/typescript/src/definition/types.d.ts.map +1 -1
  313. package/lib/typescript/src/events/defineGameEvents.d.ts +26 -0
  314. package/lib/typescript/src/events/defineGameEvents.d.ts.map +1 -0
  315. package/lib/typescript/src/events/errors.d.ts +12 -0
  316. package/lib/typescript/src/events/errors.d.ts.map +1 -0
  317. package/lib/typescript/src/events/index.d.ts +6 -0
  318. package/lib/typescript/src/events/index.d.ts.map +1 -0
  319. package/lib/typescript/src/events/payload.d.ts +21 -0
  320. package/lib/typescript/src/events/payload.d.ts.map +1 -0
  321. package/lib/typescript/src/events/seed.d.ts +3 -0
  322. package/lib/typescript/src/events/seed.d.ts.map +1 -0
  323. package/lib/typescript/src/events/types.d.ts +42 -0
  324. package/lib/typescript/src/events/types.d.ts.map +1 -0
  325. package/lib/typescript/src/events.d.ts +12 -0
  326. package/lib/typescript/src/events.d.ts.map +1 -0
  327. package/lib/typescript/src/geometry/helpers.d.ts +35 -0
  328. package/lib/typescript/src/geometry/helpers.d.ts.map +1 -0
  329. package/lib/typescript/src/geometry/index.d.ts +4 -0
  330. package/lib/typescript/src/geometry/index.d.ts.map +1 -0
  331. package/lib/typescript/src/geometry/types.d.ts +49 -0
  332. package/lib/typescript/src/geometry/types.d.ts.map +1 -1
  333. package/lib/typescript/src/geometry/validation.d.ts +44 -0
  334. package/lib/typescript/src/geometry/validation.d.ts.map +1 -0
  335. package/lib/typescript/src/geometry.d.ts +7 -0
  336. package/lib/typescript/src/geometry.d.ts.map +1 -0
  337. package/lib/typescript/src/haptics/createGameHaptics.d.ts +3 -0
  338. package/lib/typescript/src/haptics/createGameHaptics.d.ts.map +1 -0
  339. package/lib/typescript/src/haptics/errors.d.ts +6 -0
  340. package/lib/typescript/src/haptics/errors.d.ts.map +1 -0
  341. package/lib/typescript/src/haptics/index.d.ts +4 -0
  342. package/lib/typescript/src/haptics/index.d.ts.map +1 -0
  343. package/lib/typescript/src/haptics/resolver.d.ts +22 -0
  344. package/lib/typescript/src/haptics/resolver.d.ts.map +1 -0
  345. package/lib/typescript/src/haptics/types.d.ts +37 -0
  346. package/lib/typescript/src/haptics/types.d.ts.map +1 -0
  347. package/lib/typescript/src/haptics.d.ts +8 -0
  348. package/lib/typescript/src/haptics.d.ts.map +1 -0
  349. package/lib/typescript/src/index.d.ts +10 -2
  350. package/lib/typescript/src/index.d.ts.map +1 -1
  351. package/lib/typescript/src/particles/createParticleSystem.d.ts +5 -0
  352. package/lib/typescript/src/particles/createParticleSystem.d.ts.map +1 -0
  353. package/lib/typescript/src/particles/defineParticleEffect.d.ts +3 -0
  354. package/lib/typescript/src/particles/defineParticleEffect.d.ts.map +1 -0
  355. package/lib/typescript/src/particles/errors.d.ts +5 -0
  356. package/lib/typescript/src/particles/errors.d.ts.map +1 -0
  357. package/lib/typescript/src/particles/index.d.ts +6 -0
  358. package/lib/typescript/src/particles/index.d.ts.map +1 -0
  359. package/lib/typescript/src/particles/sampling.d.ts +54 -0
  360. package/lib/typescript/src/particles/sampling.d.ts.map +1 -0
  361. package/lib/typescript/src/particles/types.d.ts +292 -0
  362. package/lib/typescript/src/particles/types.d.ts.map +1 -0
  363. package/lib/typescript/src/particles.d.ts +2 -0
  364. package/lib/typescript/src/particles.d.ts.map +1 -0
  365. package/lib/typescript/src/react/GameButtonPad.d.ts +84 -0
  366. package/lib/typescript/src/react/GameButtonPad.d.ts.map +1 -0
  367. package/lib/typescript/src/react/GamePointerInput.d.ts.map +1 -1
  368. package/lib/typescript/src/react/GameView.d.ts +27 -1
  369. package/lib/typescript/src/react/GameView.d.ts.map +1 -1
  370. package/lib/typescript/src/react/assets/createGameAssetStore.d.ts.map +1 -1
  371. package/lib/typescript/src/react/assets/useGameAssets.d.ts.map +1 -1
  372. package/lib/typescript/src/react/bindAppLifecycle.d.ts +7 -1
  373. package/lib/typescript/src/react/bindAppLifecycle.d.ts.map +1 -1
  374. package/lib/typescript/src/react/bindGameSession.d.ts.map +1 -1
  375. package/lib/typescript/src/react/camera2d/GameLayer2D.d.ts +24 -0
  376. package/lib/typescript/src/react/camera2d/GameLayer2D.d.ts.map +1 -0
  377. package/lib/typescript/src/react/camera2d/defineGameCamera2D.d.ts +44 -0
  378. package/lib/typescript/src/react/camera2d/defineGameCamera2D.d.ts.map +1 -0
  379. package/lib/typescript/src/react/camera2d/usePresentedCameraBinding.d.ts +22 -0
  380. package/lib/typescript/src/react/camera2d/usePresentedCameraBinding.d.ts.map +1 -0
  381. package/lib/typescript/src/react/cleanupList.d.ts +21 -0
  382. package/lib/typescript/src/react/cleanupList.d.ts.map +1 -0
  383. package/lib/typescript/src/react/instrumentation.d.ts +33 -3
  384. package/lib/typescript/src/react/instrumentation.d.ts.map +1 -1
  385. package/lib/typescript/src/react/lifecycleSource.d.ts +21 -0
  386. package/lib/typescript/src/react/lifecycleSource.d.ts.map +1 -0
  387. package/lib/typescript/src/react/particles/ParticleView.d.ts +65 -0
  388. package/lib/typescript/src/react/particles/ParticleView.d.ts.map +1 -0
  389. package/lib/typescript/src/react/particles/culling.d.ts +70 -0
  390. package/lib/typescript/src/react/particles/culling.d.ts.map +1 -0
  391. package/lib/typescript/src/react/particles/index.d.ts +7 -0
  392. package/lib/typescript/src/react/particles/index.d.ts.map +1 -0
  393. package/lib/typescript/src/react/particles/spriteXForm.d.ts +28 -0
  394. package/lib/typescript/src/react/particles/spriteXForm.d.ts.map +1 -0
  395. package/lib/typescript/src/react/particles/useParticlePresentation.d.ts +48 -0
  396. package/lib/typescript/src/react/particles/useParticlePresentation.d.ts.map +1 -0
  397. package/lib/typescript/src/react/pointerBinding.d.ts +38 -8
  398. package/lib/typescript/src/react/pointerBinding.d.ts.map +1 -1
  399. package/lib/typescript/src/react/pointerCamera.d.ts +20 -0
  400. package/lib/typescript/src/react/pointerCamera.d.ts.map +1 -0
  401. package/lib/typescript/src/react/pointerCoalescer.d.ts +17 -1
  402. package/lib/typescript/src/react/pointerCoalescer.d.ts.map +1 -1
  403. package/lib/typescript/src/react/sprites/GameSprite.d.ts +3 -10
  404. package/lib/typescript/src/react/sprites/GameSprite.d.ts.map +1 -1
  405. package/lib/typescript/src/react/sprites/GameWorld2D.d.ts +51 -6
  406. package/lib/typescript/src/react/sprites/GameWorld2D.d.ts.map +1 -1
  407. package/lib/typescript/src/react/sprites/Sprite.d.ts.map +1 -1
  408. package/lib/typescript/src/react/sprites/SpriteBatch.d.ts +22 -1
  409. package/lib/typescript/src/react/sprites/SpriteBatch.d.ts.map +1 -1
  410. package/lib/typescript/src/react/sprites/batchVisibility.d.ts +28 -0
  411. package/lib/typescript/src/react/sprites/batchVisibility.d.ts.map +1 -0
  412. package/lib/typescript/src/react/sprites/spriteSelection.d.ts +58 -0
  413. package/lib/typescript/src/react/sprites/spriteSelection.d.ts.map +1 -0
  414. package/lib/typescript/src/react/sprites/spriteTransform.d.ts +27 -12
  415. package/lib/typescript/src/react/sprites/spriteTransform.d.ts.map +1 -1
  416. package/lib/typescript/src/react/tilemap/TileMapLayer2D.d.ts +69 -0
  417. package/lib/typescript/src/react/tilemap/TileMapLayer2D.d.ts.map +1 -0
  418. package/lib/typescript/src/react/tilemap/tilePresentation.d.ts +217 -0
  419. package/lib/typescript/src/react/tilemap/tilePresentation.d.ts.map +1 -0
  420. package/lib/typescript/src/react/useGameSession.d.ts +48 -0
  421. package/lib/typescript/src/react/useGameSession.d.ts.map +1 -0
  422. package/lib/typescript/src/react/useGameSessionStatus.d.ts +23 -0
  423. package/lib/typescript/src/react/useGameSessionStatus.d.ts.map +1 -0
  424. package/lib/typescript/src/react/viewportBinding.d.ts +5 -1
  425. package/lib/typescript/src/react/viewportBinding.d.ts.map +1 -1
  426. package/lib/typescript/src/react.d.ts +18 -1
  427. package/lib/typescript/src/react.d.ts.map +1 -1
  428. package/lib/typescript/src/scene/defineScene.d.ts +22 -2
  429. package/lib/typescript/src/scene/defineScene.d.ts.map +1 -1
  430. package/lib/typescript/src/scene/types.d.ts +24 -4
  431. package/lib/typescript/src/scene/types.d.ts.map +1 -1
  432. package/lib/typescript/src/sprites/sampleSpriteClip.d.ts +26 -2
  433. package/lib/typescript/src/sprites/sampleSpriteClip.d.ts.map +1 -1
  434. package/lib/typescript/src/sprites/spriteAnimationState.d.ts +6 -7
  435. package/lib/typescript/src/sprites/spriteAnimationState.d.ts.map +1 -1
  436. package/lib/typescript/src/sprites.d.ts +10 -0
  437. package/lib/typescript/src/sprites.d.ts.map +1 -0
  438. package/lib/typescript/src/storage/adapters/asyncStorage.d.ts +18 -0
  439. package/lib/typescript/src/storage/adapters/asyncStorage.d.ts.map +1 -0
  440. package/lib/typescript/src/storage/adapters/memory.d.ts +16 -0
  441. package/lib/typescript/src/storage/adapters/memory.d.ts.map +1 -0
  442. package/lib/typescript/src/storage/errors.d.ts +37 -0
  443. package/lib/typescript/src/storage/errors.d.ts.map +1 -0
  444. package/lib/typescript/src/storage/index.d.ts +11 -0
  445. package/lib/typescript/src/storage/index.d.ts.map +1 -0
  446. package/lib/typescript/src/storage/schema.d.ts +22 -0
  447. package/lib/typescript/src/storage/schema.d.ts.map +1 -0
  448. package/lib/typescript/src/storage/serialization.d.ts +23 -0
  449. package/lib/typescript/src/storage/serialization.d.ts.map +1 -0
  450. package/lib/typescript/src/storage/store.d.ts +3 -0
  451. package/lib/typescript/src/storage/store.d.ts.map +1 -0
  452. package/lib/typescript/src/storage/types.d.ts +69 -0
  453. package/lib/typescript/src/storage/types.d.ts.map +1 -0
  454. package/lib/typescript/src/storage/validation.d.ts +24 -0
  455. package/lib/typescript/src/storage/validation.d.ts.map +1 -0
  456. package/lib/typescript/src/storage.d.ts +2 -0
  457. package/lib/typescript/src/storage.d.ts.map +1 -0
  458. package/lib/typescript/src/testing.d.ts +1 -0
  459. package/lib/typescript/src/testing.d.ts.map +1 -1
  460. package/lib/typescript/src/tilemap/chunkStats.d.ts +14 -0
  461. package/lib/typescript/src/tilemap/chunkStats.d.ts.map +1 -0
  462. package/lib/typescript/src/tilemap/definitions.d.ts +38 -0
  463. package/lib/typescript/src/tilemap/definitions.d.ts.map +1 -0
  464. package/lib/typescript/src/tilemap/errors.d.ts +7 -0
  465. package/lib/typescript/src/tilemap/errors.d.ts.map +1 -0
  466. package/lib/typescript/src/tilemap/index.d.ts +8 -0
  467. package/lib/typescript/src/tilemap/index.d.ts.map +1 -0
  468. package/lib/typescript/src/tilemap/movement.d.ts +52 -0
  469. package/lib/typescript/src/tilemap/movement.d.ts.map +1 -0
  470. package/lib/typescript/src/tilemap/queries.d.ts +21 -0
  471. package/lib/typescript/src/tilemap/queries.d.ts.map +1 -0
  472. package/lib/typescript/src/tilemap/tiledAdapter.d.ts +32 -0
  473. package/lib/typescript/src/tilemap/tiledAdapter.d.ts.map +1 -0
  474. package/lib/typescript/src/tilemap/types.d.ts +127 -0
  475. package/lib/typescript/src/tilemap/types.d.ts.map +1 -0
  476. package/lib/typescript/src/tilemap.d.ts +2 -0
  477. package/lib/typescript/src/tilemap.d.ts.map +1 -0
  478. package/package.json +100 -10
  479. package/src/assets/defineAssets.ts +31 -5
  480. package/src/assets.ts +27 -0
  481. package/src/audio/createGameAudio.ts +749 -0
  482. package/src/audio/errors.ts +12 -0
  483. package/src/audio/index.ts +9 -0
  484. package/src/audio/resolver.ts +74 -0
  485. package/src/audio/types.ts +47 -0
  486. package/src/audio.ts +13 -0
  487. package/src/camera2d/bounds.ts +69 -0
  488. package/src/camera2d/extents.ts +25 -0
  489. package/src/camera2d/follow.ts +165 -0
  490. package/src/camera2d/index.ts +29 -0
  491. package/src/camera2d/interpolation.ts +113 -0
  492. package/src/camera2d/shake.ts +90 -0
  493. package/src/camera2d/transform.ts +148 -0
  494. package/src/camera2d/types.ts +73 -0
  495. package/src/camera2d/validation.ts +126 -0
  496. package/src/camera2d/visibility.ts +181 -0
  497. package/src/camera2d.ts +6 -0
  498. package/src/collision2d/colliders.ts +292 -0
  499. package/src/collision2d/debug.ts +133 -0
  500. package/src/collision2d/filters.ts +48 -0
  501. package/src/collision2d/index.ts +74 -0
  502. package/src/collision2d/intersections.ts +82 -0
  503. package/src/collision2d/manifolds.ts +191 -0
  504. package/src/collision2d/segments.ts +176 -0
  505. package/src/collision2d/spatialHash.ts +211 -0
  506. package/src/collision2d/sweeps.ts +269 -0
  507. package/src/collision2d.ts +6 -0
  508. package/src/core/input/buttonPad.ts +235 -0
  509. package/src/core/input/createInputBuffer.ts +95 -14
  510. package/src/core/input/types.ts +7 -0
  511. package/src/core/session/createGameSession.ts +480 -53
  512. package/src/core/session/deepFreeze.ts +104 -3
  513. package/src/core/session/diagnostics.ts +2 -0
  514. package/src/core/session/types.ts +77 -4
  515. package/src/definition/defineGame.ts +61 -3
  516. package/src/definition/types.ts +10 -0
  517. package/src/events/defineGameEvents.ts +46 -0
  518. package/src/events/errors.ts +14 -0
  519. package/src/events/index.ts +14 -0
  520. package/src/events/payload.ts +234 -0
  521. package/src/events/seed.ts +33 -0
  522. package/src/events/types.ts +53 -0
  523. package/src/events.ts +20 -0
  524. package/src/geometry/helpers.ts +136 -0
  525. package/src/geometry/index.ts +14 -0
  526. package/src/geometry/types.ts +54 -0
  527. package/src/geometry/validation.ts +131 -0
  528. package/src/geometry.ts +6 -0
  529. package/src/haptics/createGameHaptics.ts +214 -0
  530. package/src/haptics/errors.ts +12 -0
  531. package/src/haptics/index.ts +3 -0
  532. package/src/haptics/resolver.ts +58 -0
  533. package/src/haptics/types.ts +48 -0
  534. package/src/haptics.ts +7 -0
  535. package/src/index.ts +37 -1
  536. package/src/particles/createParticleSystem.ts +505 -0
  537. package/src/particles/defineParticleEffect.ts +164 -0
  538. package/src/particles/errors.ts +6 -0
  539. package/src/particles/index.ts +5 -0
  540. package/src/particles/sampling.ts +141 -0
  541. package/src/particles/types.ts +327 -0
  542. package/src/particles.ts +1 -0
  543. package/src/react/GameButtonPad.tsx +436 -0
  544. package/src/react/GamePointerInput.tsx +73 -8
  545. package/src/react/GameView.tsx +160 -61
  546. package/src/react/assets/createGameAssetStore.ts +140 -107
  547. package/src/react/assets/useGameAssets.ts +63 -31
  548. package/src/react/bindAppLifecycle.ts +55 -19
  549. package/src/react/bindGameSession.ts +12 -2
  550. package/src/react/camera2d/GameLayer2D.tsx +43 -0
  551. package/src/react/camera2d/defineGameCamera2D.ts +59 -0
  552. package/src/react/camera2d/usePresentedCameraBinding.ts +185 -0
  553. package/src/react/cleanupList.ts +48 -0
  554. package/src/react/instrumentation.ts +31 -3
  555. package/src/react/lifecycleSource.ts +58 -0
  556. package/src/react/particles/ParticleView.tsx +358 -0
  557. package/src/react/particles/culling.ts +145 -0
  558. package/src/react/particles/index.ts +6 -0
  559. package/src/react/particles/spriteXForm.ts +72 -0
  560. package/src/react/particles/useParticlePresentation.ts +261 -0
  561. package/src/react/pointerBinding.ts +74 -16
  562. package/src/react/pointerCamera.ts +33 -0
  563. package/src/react/pointerCoalescer.ts +36 -10
  564. package/src/react/sprites/GameSprite.tsx +4 -33
  565. package/src/react/sprites/GameWorld2D.tsx +113 -7
  566. package/src/react/sprites/Sprite.tsx +51 -72
  567. package/src/react/sprites/SpriteBatch.tsx +74 -22
  568. package/src/react/sprites/batchVisibility.ts +76 -0
  569. package/src/react/sprites/spriteSelection.ts +133 -0
  570. package/src/react/sprites/spriteTransform.ts +46 -26
  571. package/src/react/tilemap/TileMapLayer2D.tsx +274 -0
  572. package/src/react/tilemap/tilePresentation.ts +491 -0
  573. package/src/react/useGameSession.ts +90 -0
  574. package/src/react/useGameSessionStatus.ts +53 -0
  575. package/src/react/viewportBinding.ts +5 -1
  576. package/src/react.ts +18 -1
  577. package/src/scene/defineScene.ts +47 -5
  578. package/src/scene/types.ts +37 -3
  579. package/src/sprites/sampleSpriteClip.ts +82 -14
  580. package/src/sprites/spriteAnimationState.ts +29 -25
  581. package/src/sprites.ts +22 -0
  582. package/src/storage/adapters/asyncStorage.ts +77 -0
  583. package/src/storage/adapters/memory.ts +58 -0
  584. package/src/storage/errors.ts +88 -0
  585. package/src/storage/index.ts +18 -0
  586. package/src/storage/schema.ts +147 -0
  587. package/src/storage/serialization.ts +248 -0
  588. package/src/storage/store.ts +380 -0
  589. package/src/storage/types.ts +76 -0
  590. package/src/storage/validation.ts +102 -0
  591. package/src/storage.ts +1 -0
  592. package/src/testing.ts +4 -0
  593. package/src/tilemap/chunkStats.ts +24 -0
  594. package/src/tilemap/definitions.ts +327 -0
  595. package/src/tilemap/errors.ts +11 -0
  596. package/src/tilemap/index.ts +10 -0
  597. package/src/tilemap/movement.ts +368 -0
  598. package/src/tilemap/queries.ts +136 -0
  599. package/src/tilemap/tiledAdapter.ts +165 -0
  600. package/src/tilemap/types.ts +119 -0
  601. package/src/tilemap.ts +1 -0
@@ -22,6 +22,39 @@
22
22
 
23
23
  import type { DeepReadonly } from './types';
24
24
 
25
+ /**
26
+ * Supported snapshot domain (GS-SCENE-03): plain records
27
+ * (`Object.prototype` or `null` prototype), arrays, and scalar values.
28
+ * Everything else — functions, symbols, bigints, and class instances
29
+ * (Map, Set, Date, typed arrays, custom classes, …) — is rejected at the
30
+ * publication boundary because freezing cannot secure it (`Object.freeze`
31
+ * on a Map does not freeze its entries; a frozen function stays callable).
32
+ */
33
+ export class SnapshotDomainError extends Error {
34
+ /** Dot/bracket path from the snapshot root to the offending value. */
35
+ readonly path: string;
36
+ /** The scene whose snapshot was rejected, when the session supplied it. */
37
+ readonly scene?: string;
38
+ constructor(path: string, detail: string, scene?: string) {
39
+ super(
40
+ `Unsupported snapshot value at ${path}: ${detail}${
41
+ scene === undefined ? '' : ` (scene "${scene}")`
42
+ }. Snapshots must contain only plain records, arrays, and scalar values.`,
43
+ );
44
+ this.name = 'SnapshotDomainError';
45
+ this.path = path;
46
+ if (scene !== undefined) {
47
+ this.scene = scene;
48
+ }
49
+ }
50
+ }
51
+
52
+ /** Context the session attaches so rejections name the offending scene. */
53
+ export interface SnapshotFreezeContext {
54
+ readonly scene?: string;
55
+ readonly tick?: number;
56
+ }
57
+
25
58
  /** Whether a string is a canonical array index (`0 <= i < 2^32 - 1`). */
26
59
  /** Decimal digit count of a non-negative integer (0 <= value < 1e11). */
27
60
  function digitLength(value: number): number {
@@ -80,19 +113,77 @@ function isArrayIndexKey(key: string): boolean {
80
113
  return value <= 0xffffffff - 1;
81
114
  }
82
115
 
116
+ /** Whether a value is a plain record (`Object.prototype` or `null` prototype). */
117
+ function isPlainRecord(node: object): boolean {
118
+ const prototype = Object.getPrototypeOf(node);
119
+ return prototype === Object.prototype || prototype === null;
120
+ }
121
+
122
+ /** Name an unsupported value for an actionable rejection message. */
123
+ function describeUnsupported(node: unknown): string {
124
+ if (typeof node === 'function') {
125
+ return 'functions are not part of the snapshot domain';
126
+ }
127
+ if (typeof node === 'symbol') {
128
+ return 'symbols are not part of the snapshot domain';
129
+ }
130
+ if (typeof node === 'bigint') {
131
+ return 'bigints are not part of the snapshot domain';
132
+ }
133
+ const name =
134
+ typeof node === 'object' && node !== null
135
+ ? (node as { constructor?: { name?: unknown } }).constructor?.name
136
+ : undefined;
137
+ const label = typeof name === 'string' && name !== '' ? `${name} instances` : 'class instances';
138
+ return `${label} are not part of the snapshot domain (only plain records and arrays are supported)`;
139
+ }
140
+
141
+ /** Format a key-path segment stack as `a.b[0]` (root renders `<root>`). */
142
+ function formatPath(path: readonly (string | number | symbol)[]): string {
143
+ if (path.length === 0) {
144
+ return '<root>';
145
+ }
146
+ let out = '';
147
+ for (const segment of path) {
148
+ if (typeof segment === 'number') {
149
+ out += `[${segment}]`;
150
+ } else if (typeof segment === 'symbol') {
151
+ out += `[${String(segment)}]`;
152
+ } else if (out === '') {
153
+ out = segment;
154
+ } else {
155
+ out += `.${segment}`;
156
+ }
157
+ }
158
+ return out;
159
+ }
160
+
83
161
  export interface DeepFreezer {
84
- <T>(value: T): DeepReadonly<T>;
162
+ <T>(value: T, context?: SnapshotFreezeContext): DeepReadonly<T>;
85
163
  }
86
164
 
87
165
  export function createDeepFreeze(): DeepFreezer { const trusted = new WeakSet<object>();
88
166
 
89
- return function deepFreeze<T>(value: T): DeepReadonly<T> {
167
+ return function deepFreeze<T>(value: T, context?: SnapshotFreezeContext): DeepReadonly<T> {
168
+ // Key path from the snapshot root, maintained as a segment stack and
169
+ // formatted only when a rejection needs it. try/finally is unnecessary:
170
+ // a throw abandons the traversal, and the stack is per call.
171
+ const path: (string | number | symbol)[] = [];
172
+ const reject = (node: unknown): never => {
173
+ throw new SnapshotDomainError(formatPath(path), describeUnsupported(node), context?.scene);
174
+ };
90
175
  if (typeof value !== 'object' || value === null) {
176
+ if (typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint') {
177
+ reject(value);
178
+ }
91
179
  return value as DeepReadonly<T>;
92
180
  }
93
181
  const visiting = new WeakSet<object>();
94
182
  const freeze = (node: unknown): void => {
95
183
  if (typeof node !== 'object' || node === null) {
184
+ if (typeof node === 'function' || typeof node === 'symbol' || typeof node === 'bigint') {
185
+ reject(node);
186
+ }
96
187
  return;
97
188
  }
98
189
  if (trusted.has(node) || visiting.has(node)) {
@@ -102,7 +193,9 @@ export function createDeepFreeze(): DeepFreezer { const trusted = new WeakSet<o
102
193
  if (Array.isArray(node)) {
103
194
  // Index fast path: avoids materialising an index-key array per array.
104
195
  for (let index = 0; index < node.length; index += 1) {
196
+ path.push(index);
105
197
  freeze(node[index]);
198
+ path.pop();
106
199
  }
107
200
  // F5: legal JavaScript arrays may also carry values on non-index
108
201
  // string keys and symbol keys. Only own keys are reachable snapshot
@@ -134,20 +227,28 @@ export function createDeepFreeze(): DeepFreezer { const trusted = new WeakSet<o
134
227
  continue;
135
228
  }
136
229
  if (!isArrayIndexKey(name)) {
230
+ path.push(name);
137
231
  freeze((node as unknown as Record<PropertyKey, unknown>)[name]);
232
+ path.pop();
138
233
  }
139
234
  }
140
235
  const symbols = Object.getOwnPropertySymbols(node);
141
236
  for (let index = 0; index < symbols.length; index += 1) {
142
237
  const symbol = symbols[index];
143
238
  if (symbol !== undefined) {
239
+ path.push(symbol);
144
240
  freeze((node as unknown as Record<PropertyKey, unknown>)[symbol]);
241
+ path.pop();
145
242
  }
146
243
  }
147
- } else {
244
+ } else if (isPlainRecord(node)) {
148
245
  for (const key of Reflect.ownKeys(node)) {
246
+ path.push(key);
149
247
  freeze((node as Record<PropertyKey, unknown>)[key]);
248
+ path.pop();
150
249
  }
250
+ } else {
251
+ reject(node);
151
252
  }
152
253
  Object.freeze(node);
153
254
  trusted.add(node);
@@ -32,4 +32,6 @@ export interface SessionDiagnostics {
32
32
  onCommitNotification(): void;
33
33
  /** Listener count at publish time. */
34
34
  onListenerCount(count: number): void;
35
+ /** Status-listener count after registration or removal (T10 control plane). */
36
+ onStatusListenerCount?(count: number): void;
35
37
  }
@@ -1,4 +1,5 @@
1
1
  import type { InputMap, SceneMap } from '../../definition/types';
2
+ import type { GameEventDescriptor, GameEventEnvelope, InferGameEventMap } from '../../events/types';
2
3
  import type { SceneSnapshot } from '../../scene/types';
3
4
  import type { Viewport } from '../../viewport2d/types';
4
5
  import type { InputController } from '../input/types';
@@ -15,6 +16,29 @@ export type DeepReadonly<T> = T extends (...arguments_: never[]) => unknown
15
16
  /** Lifecycle states of a headless game session. */
16
17
  export type GameSessionStatus = 'idle' | 'running' | 'paused' | 'disposed';
17
18
 
19
+ /**
20
+ * Minimal read-only lifecycle surface for presentation layers (T20.3).
21
+ *
22
+ * Exposes exactly what a renderer-side consumer needs to follow its owning
23
+ * session — the current status and a way to observe transitions — and
24
+ * nothing it must not have: no `start`, `pause`, `press`, `setScene`, event
25
+ * subscription, or other session internals. `GameView` owns one source per
26
+ * session and supplies it to its renderer subtree; haptics and particle
27
+ * presentation consume it instead of casting to private session methods or
28
+ * reaching for module-global coordinators.
29
+ */
30
+ export interface GameLifecycleSource {
31
+ /** The owning session's current lifecycle status. */
32
+ getStatus(): GameSessionStatus;
33
+ /**
34
+ * Observe lifecycle transitions. Returns a detach function. Subscribing
35
+ * to a disposed session returns a no-op detach: the terminal notification
36
+ * was already delivered, and `addStatusListener` follows the
37
+ * disposed-error policy for new subscribers.
38
+ */
39
+ subscribe(listener: (status: GameSessionStatus) => void): () => void;
40
+ }
41
+
18
42
  /** One renderer-neutral simulation commit produced by a game session. */
19
43
  export interface CommitFrameBase<TSnapshot> {
20
44
  /** Snapshot immediately before the latest simulation update. */
@@ -60,7 +84,11 @@ export interface GameSubscription {
60
84
  }
61
85
 
62
86
  /** A closure-backed, headless running instance of one game definition. */
63
- export interface GameSession<TScenes extends SceneMap = SceneMap, TInput extends InputMap = InputMap> {
87
+ export interface GameSession<
88
+ TScenes extends SceneMap = SceneMap,
89
+ TInput extends InputMap = InputMap,
90
+ TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
91
+ > {
64
92
  /** Current lifecycle status. */
65
93
  readonly status: GameSessionStatus;
66
94
  /** The active scene name, updated by transitions and restarts. */
@@ -73,12 +101,28 @@ export interface GameSession<TScenes extends SceneMap = SceneMap, TInput extends
73
101
  start(): void;
74
102
  /** Pause simulation and discard suspended wall time. */
75
103
  pause(): void;
104
+ /**
105
+ * Observe lifecycle transitions at control frequency.
106
+ *
107
+ * The listener receives each actual status transition after it becomes
108
+ * authoritative (`idle`, `running`, `paused`, `disposed`); idempotent
109
+ * commands emit nothing, and no initial value is emitted on subscribe —
110
+ * read `status` for the snapshot. `disposed` is delivered exactly once
111
+ * before listeners are released. Listeners are called from a snapshot and
112
+ * a listener that issues another lifecycle command observes complete
113
+ * states; a throwing listener does not abort delivery, and the first
114
+ * failure is rethrown from the command after the pass completes. Status
115
+ * notifications are not render commits.
116
+ */
117
+ addStatusListener(listener: (status: GameSessionStatus) => void): GameSubscription;
76
118
  /**
77
119
  * Transition to a declared scene.
78
120
  *
79
- * While running, the transition commits at the next fixed-step boundary.
80
- * While idle or paused, it commits synchronously and publishes the new
81
- * frame. Setting the current scene is an idempotent no-op.
121
+ * While running, the transition commits at the next frame-driver callback
122
+ * — even when no fixed step is due — without advancing simulation tick or
123
+ * time. The target scene first updates at the next due fixed step. While
124
+ * idle or paused, it commits synchronously and publishes the new frame.
125
+ * Setting the current scene is an idempotent no-op.
82
126
  */
83
127
  setScene(name: keyof TScenes): void;
84
128
  /** Recreate the active scene with fresh state. */
@@ -93,10 +137,39 @@ export interface GameSession<TScenes extends SceneMap = SceneMap, TInput extends
93
137
  * accumulated timing fraction at call time and is only meaningful for
94
138
  * headless inspection. Rendering uses the UI-owned alpha clock; the
95
139
  * envelope fields never change between commits.
140
+ *
141
+ * Event-time authority (GS-EVENT-02): this frame is the most recently
142
+ * PUBLISHED presentation frame, which can lag the authoritative tick
143
+ * when several simulation ticks run in one driver callback. Inside a
144
+ * game-event listener, the envelope (tick, scene, ordinal, payload) is
145
+ * the authority for that event — never re-read this frame to place the
146
+ * event. Put the data an effect needs into its small payload.
96
147
  */
97
148
  getRenderFrame(): GameRenderFrame<TScenes>;
98
149
  /** Observe simulation commits at commit frequency (never per display frame). */
99
150
  addCommitListener(listener: (frame: CommitFrame<TScenes>) => void): GameSubscription;
151
+ /**
152
+ * Observe deterministic game events after they commit (T13).
153
+ *
154
+ * Each listener receives committed envelopes for the subscribed name in
155
+ * deterministic `(tick, ordinal)` order. Delivery happens after the
156
+ * source tick's authoritative state commits and never during the update
157
+ * itself. Listeners run from a per-tick snapshot taken before the
158
+ * tick's first delivery (GS-EVENT-01): a listener added during delivery
159
+ * receives only later ticks, and a removal prevents only future ticks —
160
+ * neither affects the envelopes already staged for the running tick.
161
+ * Lifecycle calls during delivery (pause, setScene, dispose) take
162
+ * effect after the staged batch completes: every snapshotted listener
163
+ * still runs exactly once for the tick. Removing a listener is
164
+ * idempotent. A throwing listener does not suppress siblings or alter
165
+ * simulation; the error is reported via a visible non-recursive sink
166
+ * (`console.error`). Simulation never awaits an async effect started
167
+ * by a listener.
168
+ */
169
+ addGameEventListener<TName extends keyof InferGameEventMap<TEventDefs> & string>(
170
+ name: TName,
171
+ listener: (event: GameEventEnvelope<TName, InferGameEventMap<TEventDefs>[TName]>) => void | Promise<void>,
172
+ ): GameSubscription;
100
173
  }
101
174
 
102
175
  /** Error thrown when live work is requested from a disposed session. */
@@ -1,4 +1,5 @@
1
1
  import type { AssetGroupMap } from '../assets/types';
2
+ import type { GameEventDescriptor } from '../events/types';
2
3
  import type { GameDefinition, InputMap, SceneMap } from './types';
3
4
 
4
5
  type SceneActions<TScene> = TScene extends { readonly __actionType?: infer TAction }
@@ -29,6 +30,33 @@ type ValidateSceneTransitions<TScenes extends SceneMap> =
29
30
  ? unknown
30
31
  : { readonly __undeclaredSceneTransitions: UndeclaredSceneTransitions<TScenes> };
31
32
 
33
+ type SceneEmits<TScene> = TScene extends { readonly __emitType?: infer TEmits }
34
+ ? Exclude<TEmits, undefined>
35
+ : never;
36
+
37
+ type UndeclaredSceneEmits<
38
+ TScenes extends SceneMap,
39
+ TEventDefs extends Record<string, GameEventDescriptor<unknown>>,
40
+ > = TEventDefs extends Record<string, never>
41
+ ? SceneEmits<TScenes[keyof TScenes]>
42
+ : Exclude<SceneEmits<TScenes[keyof TScenes]>, keyof TEventDefs & string>;
43
+
44
+ type ValidateSceneEmits<
45
+ TScenes extends SceneMap,
46
+ TEventDefs extends Record<string, GameEventDescriptor<unknown>>,
47
+ > = UndeclaredSceneEmits<TScenes, TEventDefs> extends never
48
+ ? unknown
49
+ : { readonly __undeclaredSceneEmits: UndeclaredSceneEmits<TScenes, TEventDefs> };
50
+
51
+ type ValidateEventsWhenScenesEmit<
52
+ TScenes extends SceneMap,
53
+ TEventDefs extends Record<string, GameEventDescriptor<unknown>>,
54
+ > = SceneEmits<TScenes[keyof TScenes]> extends never
55
+ ? unknown
56
+ : TEventDefs extends Record<string, never>
57
+ ? { readonly __eventsRequired: 'scenes declare emits but game has no events map' }
58
+ : unknown;
59
+
32
60
  /**
33
61
  * Declare a game.
34
62
  *
@@ -81,14 +109,44 @@ export function defineGame<
81
109
  const TInput extends InputMap = InputMap,
82
110
  const TInitialScene extends keyof TScenes = keyof TScenes,
83
111
  const TAssets extends AssetGroupMap = AssetGroupMap,
112
+ const TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
84
113
  >(
85
- definition: GameDefinition<TScenes, TInput, TInitialScene, TAssets> &
114
+ definition: GameDefinition<TScenes, TInput, TInitialScene, TAssets, TEventDefs> &
86
115
  ValidateSceneActions<TScenes, TInput> &
87
- ValidateSceneTransitions<TScenes>,
88
- ): GameDefinition<TScenes, TInput, TInitialScene, TAssets> {
116
+ ValidateSceneTransitions<TScenes> &
117
+ ValidateSceneEmits<TScenes, TEventDefs> &
118
+ ValidateEventsWhenScenesEmit<TScenes, TEventDefs>,
119
+ ): GameDefinition<TScenes, TInput, TInitialScene, TAssets, TEventDefs> {
89
120
  // The viewport config is part of the public session surface; freeze it so a
90
121
  // caller cannot mutate a live game's coordinate authority.
91
122
  Object.freeze(definition.viewport.logicalSize);
92
123
  Object.freeze(definition.viewport);
124
+ if (definition.events !== undefined) {
125
+ Object.freeze(definition.events);
126
+ // Runtime identity check: every scene that declares `events` must reference
127
+ // the same object as the game's `events`. This catches two different
128
+ // `defineGameEvents` instances with compatible shapes that would otherwise
129
+ // be structurally compatible at the type level.
130
+ for (const [name, scene] of Object.entries(definition.scenes)) {
131
+ const s = scene as unknown as { events?: unknown; emits?: readonly string[] };
132
+ if (s.events !== undefined && s.events !== definition.events) {
133
+ throw new Error(
134
+ `Scene "${name}" is bound to a different events object than the game. Pass the same defineGameEvents() result to both defineScene({ events }) and defineGame({ events }).`,
135
+ );
136
+ }
137
+ if (s.events === undefined && s.emits !== undefined && s.emits.length > 0) {
138
+ throw new Error(
139
+ `Scene "${name}" declares emits but is not bound to the game's events. Pass \`events\` to defineScene.`,
140
+ );
141
+ }
142
+ }
143
+ } else {
144
+ for (const [name, scene] of Object.entries(definition.scenes)) {
145
+ const s = scene as unknown as { events?: unknown; emits?: readonly string[] };
146
+ if (s.events !== undefined) {
147
+ throw new Error(`Scene "${name}" is bound to events but the game has no events map`);
148
+ }
149
+ }
150
+ }
93
151
  return definition;
94
152
  }
@@ -1,4 +1,5 @@
1
1
  import type { AssetGroupMap, GameAssetManifest } from '../assets/types';
2
+ import type { GameEventDescriptor } from '../events/types';
2
3
  import type { Viewport } from '../viewport2d/types';
3
4
 
4
5
  /** The button action supported by the runtime. */
@@ -37,6 +38,12 @@ export interface SceneDefinitionMarker {
37
38
  readonly __actionType?: string;
38
39
  /** @internal Type witness for transition targets declared by this scene. */
39
40
  readonly __transitionType?: string;
41
+ /** @internal Type witness for emitted event names. */
42
+ readonly __emitType?: string;
43
+ /** @internal Type witness for the game event map. */
44
+ readonly __eventMapType?: Record<string, unknown>;
45
+ /** @internal Type witness for the branded event definitions identity. */
46
+ readonly __eventDefsType?: Record<string, GameEventDescriptor<unknown>>;
40
47
  }
41
48
 
42
49
  /** The collection of functional scenes declared by a game. */
@@ -53,6 +60,7 @@ export interface GameDefinition<
53
60
  TInput extends InputMap = InputMap,
54
61
  TInitialScene extends keyof TScenes = keyof TScenes,
55
62
  TAssets extends AssetGroupMap = AssetGroupMap,
63
+ TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
56
64
  > {
57
65
  /** The viewport configuration of the game. */
58
66
  readonly viewport: Viewport;
@@ -64,4 +72,6 @@ export interface GameDefinition<
64
72
  readonly scenes: TScenes;
65
73
  /** The scene created first when a session starts. */
66
74
  readonly initialScene: TInitialScene;
75
+ /** Typed game event declarations (T13). Absence keeps the no-event fast path. */
76
+ readonly events?: TEventDefs;
67
77
  }
@@ -0,0 +1,46 @@
1
+ import type { BrandedGameEventDefs, GameEventDescriptor } from './types';
2
+
3
+ /**
4
+ * Create a type witness for one event payload.
5
+ *
6
+ * `gameEvent` owns no runtime resource — it returns a frozen empty
7
+ * descriptor whose generic preserves the payload type. Payload shapes are
8
+ * validated when events are staged, not when they are declared.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const events = defineGameEvents({
13
+ * 'brick-hit': gameEvent<{ brickId: string; point: Point2D }>(),
14
+ * });
15
+ * ```
16
+ */
17
+ export function gameEvent<TPayload>(): GameEventDescriptor<TPayload> {
18
+ return Object.freeze({}) as GameEventDescriptor<TPayload>;
19
+ }
20
+
21
+ function isValidEventName(name: string): boolean {
22
+ return name.length > 0 && name.length <= 128 && !name.includes('\0');
23
+ }
24
+
25
+ /**
26
+ * Define and freeze a game event map.
27
+ *
28
+ * Validates every name, freezes the declaration map and its entries,
29
+ * and preserves literal inference so `keyof typeof events` and the
30
+ * payload types flow through `defineGame`, scenes, and subscriptions
31
+ * without duplicate author-written unions.
32
+ */
33
+ export function defineGameEvents<const T extends Record<string, GameEventDescriptor<unknown>>>(
34
+ definitions: T,
35
+ ): BrandedGameEventDefs<T> {
36
+ for (const [name, descriptor] of Object.entries(definitions)) {
37
+ if (!isValidEventName(name)) {
38
+ throw new Error(`Invalid game event name: "${name}"`);
39
+ }
40
+ if (descriptor === null || typeof descriptor !== 'object') {
41
+ throw new Error(`Game event "${name}" descriptor must be an object`);
42
+ }
43
+ Object.freeze(descriptor);
44
+ }
45
+ return Object.freeze({ ...definitions }) as BrandedGameEventDefs<T>;
46
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Game event payload validation errors (T13).
3
+ *
4
+ * Every rejection identifies the event name and the exact payload path
5
+ * that caused the failure. The payload never captures React or native
6
+ * handles, sparse holes, cycles, or non-finite numbers.
7
+ */
8
+ export class GameEventError extends Error {
9
+ override readonly name = 'GameEventError';
10
+
11
+ constructor(message: string) {
12
+ super(message);
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ export { GameEventError } from './errors';
2
+ export { cloneAndValidatePayload, PAYLOAD_LIMITS } from './payload';
3
+ export { defineGameEvents, gameEvent } from './defineGameEvents';
4
+ export { seedGameEvent } from './seed';
5
+ export type {
6
+ AnyGameEventEnvelope,
7
+ GameEventDefinitions,
8
+ GameEventDescriptor,
9
+ GameEventEmitter,
10
+ GameEventEnvelope,
11
+ GameEventListener,
12
+ GameEventMap,
13
+ InferGameEventMap,
14
+ } from './types';