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
@@ -1,9 +1,27 @@
1
+ import type { GameEventDescriptor, InferGameEventMap } from '../events/types';
1
2
  import type { SceneDefinition } from './types';
2
3
 
3
4
  /**
4
5
  * Define a synchronous functional scene while inferring its state, snapshot,
5
6
  * action, and transition types.
6
7
  *
8
+ * To get typed event emission in a standalone scene, pass the same
9
+ * `events` object that will be passed to `defineGame({ events })`:
10
+ *
11
+ * ```ts
12
+ * const events = defineGameEvents({ 'brick-hit': gameEvent<{ id: string }>() });
13
+ * const play = defineScene({
14
+ * actions: ['primary'],
15
+ * emits: ['brick-hit'],
16
+ * events,
17
+ * update: ({ events }) => {
18
+ * events.emit('brick-hit', { id: '1' }); // typed, wrong payload fails
19
+ * },
20
+ * // ...
21
+ * });
22
+ * const game = defineGame({ events, scenes: { play }, initialScene: 'play' });
23
+ * ```
24
+ *
7
25
  * @example
8
26
  * ```ts
9
27
  * const ready = defineScene({
@@ -25,14 +43,38 @@ export function defineScene<
25
43
  TState,
26
44
  TSnapshot,
27
45
  const TTransitions extends readonly string[] = [],
46
+ const TEmits extends readonly (keyof InferGameEventMap<TEventDefs> & string)[] = [],
47
+ const TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
28
48
  >(
29
49
  definition: Omit<
30
- SceneDefinition<TState, TSnapshot, TActions[number], TTransitions[number]>,
31
- 'kind' | '__actionType' | '__transitionType' | '__snapshotType' | 'actions' | 'transitions'
32
- > & { readonly actions: TActions; readonly transitions?: TTransitions },
33
- ): SceneDefinition<TState, TSnapshot, TActions[number], TTransitions[number]> {
50
+ SceneDefinition<
51
+ TState,
52
+ TSnapshot,
53
+ TActions[number],
54
+ TTransitions[number],
55
+ TEmits[number],
56
+ TEventDefs
57
+ >,
58
+ | 'kind'
59
+ | '__actionType'
60
+ | '__transitionType'
61
+ | '__snapshotType'
62
+ | '__emitType'
63
+ | '__eventMapType'
64
+ | '__eventDefsType'
65
+ | 'actions'
66
+ | 'transitions'
67
+ | 'emits'
68
+ | 'events'
69
+ > & {
70
+ readonly actions: TActions;
71
+ readonly transitions?: TTransitions;
72
+ readonly emits?: TEmits;
73
+ readonly events?: TEventDefs;
74
+ },
75
+ ): SceneDefinition<TState, TSnapshot, TActions[number], TTransitions[number], TEmits[number], TEventDefs> {
34
76
  return {
35
77
  kind: 'gamekit.scene',
36
78
  ...definition,
37
- };
79
+ } as SceneDefinition<TState, TSnapshot, TActions[number], TTransitions[number], TEmits[number], TEventDefs>;
38
80
  }
@@ -1,4 +1,9 @@
1
1
  import type { InputFrame } from '../core/input/types';
2
+ import type {
3
+ GameEventDescriptor,
4
+ GameEventEmitter,
5
+ InferGameEventMap,
6
+ } from '../events/types';
2
7
 
3
8
  /**
4
9
  * Update-scoped scene transition controls.
@@ -20,13 +25,21 @@ export interface SceneTransitionController<TTransitionName extends string> {
20
25
  }
21
26
 
22
27
  /** Values supplied to a scene for one deterministic simulation tick. */
23
- export interface SceneUpdate<TState, TActionName extends string, TTransitionName extends string> {
28
+ export interface SceneUpdate<
29
+ TState,
30
+ TActionName extends string,
31
+ TTransitionName extends string,
32
+ TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
33
+ TEmits extends keyof InferGameEventMap<TEventDefs> & string = keyof InferGameEventMap<TEventDefs> & string,
34
+ > {
24
35
  /** The authoritative state produced by the previous tick. */
25
36
  readonly state: Readonly<TState>;
26
37
  /** One immutable semantic input snapshot for this tick. */
27
38
  readonly input: InputFrame<TActionName>;
28
39
  /** Update-scoped transition controls restricted to declared targets. */
29
40
  readonly transition: SceneTransitionController<TTransitionName>;
41
+ /** Update-scoped emitter for declared game events (T13). Invalid after the update returns or throws. */
42
+ readonly events: GameEventEmitter<Pick<InferGameEventMap<TEventDefs>, TEmits>>;
30
43
  /** One-based global simulation tick number. */
31
44
  readonly tick: number;
32
45
  /** One-based tick number within the current scene instance. */
@@ -51,6 +64,8 @@ export interface SceneDefinition<
51
64
  TSnapshot,
52
65
  TActionName extends string = never,
53
66
  TTransitionName extends string = never,
67
+ TEmits extends string = never,
68
+ TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
54
69
  > {
55
70
  /** Internal scene-definition discriminator. */
56
71
  readonly kind: 'gamekit.scene';
@@ -60,15 +75,34 @@ export interface SceneDefinition<
60
75
  readonly __actionType?: TActionName;
61
76
  /** @internal Type witness used to validate scene transition targets. */
62
77
  readonly __transitionType?: TTransitionName;
78
+ /** @internal Type witness for emitted event names. */
79
+ readonly __emitType?: TEmits;
80
+ /** @internal Type witness for the game event map. */
81
+ readonly __eventMapType?: InferGameEventMap<TEventDefs>;
82
+ /** @internal Type witness for the branded event definitions identity. */
83
+ readonly __eventDefsType?: TEventDefs;
63
84
  /** Semantic input actions this scene may read. */
64
85
  readonly actions: readonly TActionName[];
65
86
  /** Declared scene names this scene may transition to. */
66
87
  readonly transitions?: readonly TTransitionName[];
88
+ /** Declared event names this scene may emit (subset of the game's event map). */
89
+ readonly emits?: readonly TEmits[];
90
+ /** The branded event definitions this scene is bound to (for standalone type safety). */
91
+ readonly events?: TEventDefs;
67
92
  /** Create the scene's initial authoritative state. */
68
93
  readonly create: () => TState;
69
94
  /** Produce the next state for one fixed simulation tick. */
70
- readonly update: (frame: SceneUpdate<TState, TActionName, TTransitionName>) => TState;
71
- /** Extract a compact renderer-specific snapshot from current state. */
95
+ readonly update: (
96
+ frame: SceneUpdate<TState, TActionName, TTransitionName, TEventDefs, TEmits>,
97
+ ) => TState;
98
+ /**
99
+ * Extract a compact renderer-specific snapshot from current state.
100
+ *
101
+ * The snapshot domain is plain records, arrays, and scalars; anything
102
+ * else fails with a `SnapshotDomainError` carrying the key path before
103
+ * publication. Returning a state reference transfers it into immutable
104
+ * snapshot ownership — it is frozen in place.
105
+ */
72
106
  readonly snapshot: (context: SceneSnapshotContext<TState>) => TSnapshot;
73
107
  /** Release scene-owned resources exactly once. */
74
108
  readonly dispose?: (state: Readonly<TState>) => void;
@@ -4,28 +4,65 @@
4
4
  * Pure, allocation-free, worklet-compatible frame selection. The same clip
5
5
  * metadata and elapsed time always select the same frame, so equivalent
6
6
  * game time produces identical presentation at 30/60/90/120 Hz.
7
+ *
8
+ * Single-contract rule (GS-ANIMATION-01): every renderer path resolves
9
+ * frames through these helpers — never duplicated arithmetic. Negative
10
+ * elapsed clamps uniformly (loops wrap, one-shots pin to frame zero);
11
+ * non-finite elapsed, empty clips, and non-positive durations fail clearly
12
+ * instead of masking invalid data as frame zero. Unknown clip names throw
13
+ * a plain `[ASSET_UNKNOWN_CLIP]` error: the UI-reachable call graph must
14
+ * stay free of error-class construction so failure branches execute on the
15
+ * UI runtime exactly as they do headlessly (GS-ANIMATION-02).
7
16
  */
8
17
  import type { SpriteClip } from '../assets/types';
9
18
 
19
+ /** Reject elapsed values the sampler cannot define a frame for. */
20
+ function assertFiniteElapsed(elapsedMs: number): void {
21
+ 'worklet';
22
+ if (typeof elapsedMs !== 'number' || !Number.isFinite(elapsedMs)) {
23
+ throw new Error(
24
+ `sprite clip elapsed time must be a finite number of milliseconds, got ${String(elapsedMs)}`,
25
+ );
26
+ }
27
+ }
28
+
29
+ /** Reject clips with no selectable frame or no positive pace. */
30
+ function assertSelectableClip(clip: SpriteClip): number {
31
+ 'worklet';
32
+ const frameCount = clip.frames.length;
33
+ const duration = clip.frameDurationMs;
34
+ if (frameCount === 0) {
35
+ throw new Error('sprite clip must reference at least one frame');
36
+ }
37
+ if (typeof duration !== 'number' || !Number.isFinite(duration) || duration <= 0) {
38
+ throw new Error(
39
+ `sprite clip frame duration must be a finite number greater than zero, got ${String(duration)}`,
40
+ );
41
+ }
42
+ return frameCount;
43
+ }
44
+
10
45
  /**
11
46
  * Select the frame index for `elapsedMs` of playback.
12
47
  *
13
48
  * Loop clips wrap with modulo — the boundary frame is never duplicated and
14
- * no zero-length boundary frame exists. One-shot clips clamp to their final
15
- * frame; completion is reported separately.
49
+ * no zero-length boundary frame exists; negative elapsed wraps into range.
50
+ * One-shot clips clamp to `[0, frameCount - 1]`; completion is reported
51
+ * separately by the playback state.
16
52
  */
17
- export function sampleSpriteClipFrame(
18
- clip: SpriteClip,
19
- elapsedMs: number,
20
- ): number {
53
+ export function sampleSpriteClipFrame(clip: SpriteClip, elapsedMs: number): number {
21
54
  'worklet';
22
- const frameCount = clip.frames.length;
55
+ assertFiniteElapsed(elapsedMs);
56
+ const frameCount = assertSelectableClip(clip);
23
57
  const duration = clip.frameDurationMs;
24
58
  if (clip.mode === 'loop') {
25
59
  const index = Math.floor(elapsedMs / duration) % frameCount;
26
- return index >= 0 ? index : index + frameCount;
60
+ return (index + frameCount) % frameCount;
27
61
  }
28
62
  const index = Math.floor(elapsedMs / duration);
63
+ if (index < 0) {
64
+ return 0;
65
+ }
29
66
  return index >= frameCount ? frameCount - 1 : index;
30
67
  }
31
68
 
@@ -33,15 +70,11 @@ export function sampleSpriteClipFrame(
33
70
  * The frame NAME selected for `elapsedMs` of playback (the ordered frame
34
71
  * references of the clip).
35
72
  */
36
- export function sampleSpriteClipFrameName(
37
- clip: SpriteClip,
38
- elapsedMs: number,
39
- ): string {
73
+ export function sampleSpriteClipFrameName(clip: SpriteClip, elapsedMs: number): string {
40
74
  'worklet';
41
75
  const frames = clip.frames;
42
76
  const index = sampleSpriteClipFrame(clip, elapsedMs);
43
- const frame = frames[index];
44
- return frame === undefined ? frames[0] ?? '' : frame;
77
+ return frames[index] ?? '';
45
78
  }
46
79
 
47
80
  /** Total clip duration in milliseconds (one-shot: its full timeline). */
@@ -49,3 +82,38 @@ export function spriteClipDurationMs(clip: SpriteClip): number {
49
82
  'worklet';
50
83
  return clip.frames.length * clip.frameDurationMs;
51
84
  }
85
+
86
+ /**
87
+ * Select the frame name for a clip + elapsed time (loop/once semantics).
88
+ *
89
+ * Reads the descriptor's animation table with the single sampler contract
90
+ * above. An absent clip table entry is an invalid clip — it throws instead
91
+ * of returning the clip string as if it were a frame name. Absent
92
+ * *selection* (no clip chosen yet) is distinct: callers keep that path and
93
+ * present nothing without calling this helper.
94
+ */
95
+ export function spriteFrameNameForClip(
96
+ animations: Readonly<
97
+ Record<
98
+ string,
99
+ {
100
+ readonly frames: readonly string[];
101
+ readonly frameDurationMs: number;
102
+ readonly mode: 'loop' | 'once';
103
+ }
104
+ >
105
+ >,
106
+ clip: string,
107
+ elapsedMs: number,
108
+ ): string {
109
+ 'worklet';
110
+ const animation = animations[clip];
111
+ if (animation === undefined) {
112
+ throw new Error(`[ASSET_UNKNOWN_CLIP] unknown animation clip ${JSON.stringify(clip)}`);
113
+ }
114
+ const name = sampleSpriteClipFrameName(animation, elapsedMs);
115
+ if (name === '') {
116
+ throw new Error(`[ASSET_EMPTY_CLIP] clip ${JSON.stringify(clip)} selects no frame`);
117
+ }
118
+ return name;
119
+ }
@@ -8,6 +8,13 @@
8
8
  * elapsed game time always select the same presented frame (see
9
9
  * `sampleSpriteClip`).
10
10
  *
11
+ * Simulation-only execution (GS-ANIMATION-02): these state transitions run
12
+ * on fixed-step game time in the simulation, never on the UI runtime, so
13
+ * they carry no worklet directive — a directive here would promise UI
14
+ * execution the error branches (structured error classes) cannot keep.
15
+ * The UI-reachable frame-selection helpers live in `sampleSpriteClip` and
16
+ * `react/sprites/spriteSelection` with a UI-safe call graph.
17
+ *
11
18
  * Separation of concerns: gameplay-significant animation state lives in the
12
19
  * scene snapshot and advances from fixed-step game time; a renderer-only
13
20
  * loop may interpolate presentation from the latest committed state plus
@@ -54,7 +61,6 @@ function clipOf(
54
61
  descriptor: SpriteSheetDescriptor,
55
62
  clip: string,
56
63
  ): SpriteSheetDescriptor['animations'][string] {
57
- 'worklet';
58
64
  const animation = descriptor.animations[clip];
59
65
  if (animation === undefined) {
60
66
  throw new GameAssetError(
@@ -67,16 +73,14 @@ function clipOf(
67
73
  }
68
74
 
69
75
  /**
70
- * Start playback of `clip` from its beginning. The clip name is preserved
71
- * as a string literal in the returned state; unknown clips are rejected at
72
- * runtime (the manifest descriptor keeps the sheet-level frame and clip
73
- * names literal via the spriteSheet contract).
76
+ * Start playback of `clip` from its beginning. The clip name is constrained
77
+ * to the descriptor's animation keys, so a misspelled clip fails compilation;
78
+ * untyped callers still hit the runtime check below.
74
79
  */
75
- export function startSpriteAnimation<TClipName extends string>(
76
- descriptor: SpriteSheetDescriptor,
77
- clip: TClipName,
78
- ): SpriteAnimationState<TClipName> {
79
- 'worklet';
80
+ export function startSpriteAnimation<TDescriptor extends SpriteSheetDescriptor>(
81
+ descriptor: TDescriptor,
82
+ clip: SpriteClipNames<TDescriptor>,
83
+ ): SpriteAnimationState<SpriteClipNames<TDescriptor>> {
80
84
  clipOf(descriptor, clip);
81
85
  return {
82
86
  clip,
@@ -94,12 +98,14 @@ export function startSpriteAnimation<TClipName extends string>(
94
98
  * clearly. Loop clips keep their elapsed time bounded within one timeline
95
99
  * (modulo), so arbitrarily large deltas cost constant arithmetic.
96
100
  */
97
- export function advanceSpriteAnimation<TClipName extends string>(
98
- descriptor: SpriteSheetDescriptor,
99
- state: SpriteAnimationState<TClipName>,
101
+ export function advanceSpriteAnimation<
102
+ TDescriptor extends SpriteSheetDescriptor,
103
+ TClip extends SpriteClipNames<TDescriptor>,
104
+ >(
105
+ descriptor: TDescriptor,
106
+ state: SpriteAnimationState<TClip>,
100
107
  deltaSeconds: number,
101
- ): SpriteAnimationState<TClipName> {
102
- 'worklet';
108
+ ): SpriteAnimationState<TClip> {
103
109
  assertFiniteDelta(deltaSeconds);
104
110
  if (state.paused || state.completed) {
105
111
  return state;
@@ -122,12 +128,14 @@ export function advanceSpriteAnimation<TClipName extends string>(
122
128
  * Switch playback to `clip`, restarting it from the beginning. The clip
123
129
  * name is typed against the descriptor's animation table.
124
130
  */
125
- export function playSpriteAnimation<TClipName extends string>(
126
- descriptor: SpriteSheetDescriptor,
127
- state: SpriteAnimationState<TClipName>,
128
- clip: TClipName,
129
- ): SpriteAnimationState<TClipName> {
130
- 'worklet';
131
+ export function playSpriteAnimation<
132
+ TDescriptor extends SpriteSheetDescriptor,
133
+ TClip extends SpriteClipNames<TDescriptor>,
134
+ >(
135
+ descriptor: TDescriptor,
136
+ state: SpriteAnimationState<TClip>,
137
+ clip: SpriteClipNames<TDescriptor>,
138
+ ): SpriteAnimationState<SpriteClipNames<TDescriptor>> {
131
139
  if (clip === state.clip) {
132
140
  return state;
133
141
  }
@@ -145,7 +153,6 @@ export function playSpriteAnimation<TClipName extends string>(
145
153
  export function pauseSpriteAnimation<TClipName extends string>(
146
154
  state: SpriteAnimationState<TClipName>,
147
155
  ): SpriteAnimationState<TClipName> {
148
- 'worklet';
149
156
  return state.paused ? state : { ...state, paused: true };
150
157
  }
151
158
 
@@ -153,7 +160,6 @@ export function pauseSpriteAnimation<TClipName extends string>(
153
160
  export function resumeSpriteAnimation<TClipName extends string>(
154
161
  state: SpriteAnimationState<TClipName>,
155
162
  ): SpriteAnimationState<TClipName> {
156
- 'worklet';
157
163
  return state.paused ? { ...state, paused: false } : state;
158
164
  }
159
165
 
@@ -161,7 +167,6 @@ export function resumeSpriteAnimation<TClipName extends string>(
161
167
  export function resetSpriteAnimation<TClipName extends string>(
162
168
  state: SpriteAnimationState<TClipName>,
163
169
  ): SpriteAnimationState<TClipName> {
164
- 'worklet';
165
170
  return { ...state, elapsedMs: 0, completed: false };
166
171
  }
167
172
 
@@ -170,7 +175,6 @@ export function setSpriteAnimationSpeed<TClipName extends string>(
170
175
  state: SpriteAnimationState<TClipName>,
171
176
  speed: number,
172
177
  ): SpriteAnimationState<TClipName> {
173
- 'worklet';
174
178
  assertFinitePositiveSpeed(speed);
175
179
  return state.speed === speed ? state : { ...state, speed };
176
180
  }
package/src/sprites.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Subpath entry for `rn-gamekit/sprites`.
3
+ *
4
+ * Deterministic sprite-clip sampling and immutable playback-state helpers.
5
+ * React components (Sprite, GameSprite, SpriteBatch) remain in `rn-gamekit/react`.
6
+ */
7
+ export {
8
+ sampleSpriteClipFrame,
9
+ sampleSpriteClipFrameName,
10
+ spriteClipDurationMs,
11
+ spriteFrameNameForClip,
12
+ } from './sprites/sampleSpriteClip';
13
+ export {
14
+ advanceSpriteAnimation,
15
+ pauseSpriteAnimation,
16
+ playSpriteAnimation,
17
+ resetSpriteAnimation,
18
+ resumeSpriteAnimation,
19
+ setSpriteAnimationSpeed,
20
+ startSpriteAnimation,
21
+ } from './sprites/spriteAnimationState';
22
+ export type { SpriteAnimationState, SpriteClipNames } from './sprites/spriteAnimationState';
@@ -0,0 +1,77 @@
1
+ import type { GameStorageAdapter } from '../types';
2
+ import { GameStorageError } from '../errors';
3
+
4
+ export type LoadedAsyncStorage = {
5
+ getItem(key: string): Promise<string | null>;
6
+ setItem(key: string, value: string): Promise<void>;
7
+ removeItem(key: string): Promise<void>;
8
+ };
9
+
10
+ type Loader = () => Promise<LoadedAsyncStorage>;
11
+ let loader: Loader | null = null;
12
+
13
+ export function __setAsyncStorageLoader(fn: Loader | null): void {
14
+ loader = fn;
15
+ }
16
+
17
+ export function __getAsyncStorageLoader(): Loader | null {
18
+ return loader;
19
+ }
20
+
21
+ async function loadAsyncStorage(): Promise<LoadedAsyncStorage> {
22
+ if (loader) return loader();
23
+ try {
24
+ const mod = (await import('@react-native-async-storage/async-storage')) as unknown as {
25
+ default?: LoadedAsyncStorage;
26
+ } & LoadedAsyncStorage;
27
+ const resolved: LoadedAsyncStorage | undefined =
28
+ (mod as LoadedAsyncStorage).getItem !== undefined
29
+ ? (mod as LoadedAsyncStorage)
30
+ : mod.default?.getItem !== undefined
31
+ ? mod.default
32
+ : undefined;
33
+ if (!resolved) {
34
+ throw new Error('AsyncStorage module did not export getItem/setItem/removeItem');
35
+ }
36
+ return resolved;
37
+ } catch (cause) {
38
+ throw new GameStorageError(
39
+ '@react-native-async-storage/async-storage is not installed. Run `npx expo install @react-native-async-storage/async-storage` and rebuild with `npx expo prebuild` (or `expo run:ios` / `expo run:android`). See https://react-native-async-storage.github.io/async-storage/docs/install/',
40
+ {
41
+ code: 'BACKEND_READ_FAILED',
42
+ cause,
43
+ },
44
+ );
45
+ }
46
+ }
47
+
48
+ /**
49
+ * RN adapter backed by AsyncStorage.
50
+ *
51
+ * Importing `rn-gamekit/storage` does not eagerly import AsyncStorage —
52
+ * the dynamic import happens on the first read/write/remove.
53
+ */
54
+ export function createGameStorageAdapter(): GameStorageAdapter {
55
+ let cached: LoadedAsyncStorage | null = null;
56
+ const get = async (): Promise<LoadedAsyncStorage> => {
57
+ if (cached) return cached;
58
+ cached = await loadAsyncStorage();
59
+ return cached;
60
+ };
61
+
62
+ return {
63
+ async read(key: string): Promise<string | undefined> {
64
+ const storage = await get();
65
+ const value = await storage.getItem(key);
66
+ return value === null ? undefined : value;
67
+ },
68
+ async write(key: string, value: string): Promise<void> {
69
+ const storage = await get();
70
+ await storage.setItem(key, value);
71
+ },
72
+ async remove(key: string): Promise<void> {
73
+ const storage = await get();
74
+ await storage.removeItem(key);
75
+ },
76
+ };
77
+ }
@@ -0,0 +1,58 @@
1
+ import type { GameStorageAdapter } from '../types';
2
+
3
+ /**
4
+ * In-memory adapter for tests and apps that own storage elsewhere.
5
+ * Each instance owns its map.
6
+ */
7
+ export function createMemoryStorageAdapter(initial?: Record<string, string>): GameStorageAdapter {
8
+ const map = new Map<string, string>(initial ? Object.entries(initial) : []);
9
+
10
+ return {
11
+ async read(key: string): Promise<string | undefined> {
12
+ return map.get(key);
13
+ },
14
+ async write(key: string, value: string): Promise<void> {
15
+ map.set(key, value);
16
+ },
17
+ async remove(key: string): Promise<void> {
18
+ map.delete(key);
19
+ },
20
+ };
21
+ }
22
+
23
+ /**
24
+ * Programmable failure adapter for tests — wraps another adapter and injects failures.
25
+ */
26
+ export function createFailingStorageAdapter(
27
+ inner: GameStorageAdapter,
28
+ opts: {
29
+ failRead?: (key: string) => Error | null;
30
+ failWrite?: (key: string, value: string) => Error | null;
31
+ failRemove?: (key: string) => Error | null;
32
+ delayMs?: number;
33
+ } = {},
34
+ ): GameStorageAdapter {
35
+ const delay = async (): Promise<void> => {
36
+ if (opts.delayMs) await new Promise((r) => setTimeout(r, opts.delayMs));
37
+ };
38
+ return {
39
+ async read(key: string): Promise<string | undefined> {
40
+ await delay();
41
+ const err = opts.failRead?.(key) ?? null;
42
+ if (err) throw err;
43
+ return inner.read(key);
44
+ },
45
+ async write(key: string, value: string): Promise<void> {
46
+ await delay();
47
+ const err = opts.failWrite?.(key, value) ?? null;
48
+ if (err) throw err;
49
+ return inner.write(key, value);
50
+ },
51
+ async remove(key: string): Promise<void> {
52
+ await delay();
53
+ const err = opts.failRemove?.(key) ?? null;
54
+ if (err) throw err;
55
+ return inner.remove(key);
56
+ },
57
+ };
58
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * V1 storage errors — stable codes, operation, namespace/slot, schema context,
3
+ * exact path where relevant, and original cause.
4
+ */
5
+ export type GameStorageErrorCode =
6
+ | 'INVALID_NAMESPACE'
7
+ | 'INVALID_SLOT'
8
+ | 'INVALID_SCHEMA_ID'
9
+ | 'INVALID_SCHEMA_VERSION'
10
+ | 'INVALID_MIGRATION'
11
+ | 'UNSUPPORTED_VALUE'
12
+ | 'SERIALIZATION_FAILED'
13
+ | 'SIZE_EXCEEDED'
14
+ | 'DEPTH_EXCEEDED'
15
+ | 'BACKEND_READ_FAILED'
16
+ | 'BACKEND_WRITE_FAILED'
17
+ | 'BACKEND_REMOVE_FAILED'
18
+ | 'CORRUPT_ENVELOPE'
19
+ | 'SCHEMA_ID_MISMATCH'
20
+ | 'FUTURE_VERSION'
21
+ | 'MISSING_MIGRATION'
22
+ | 'MIGRATION_FAILED'
23
+ | 'VALIDATION_FAILED'
24
+ | 'DISPOSED';
25
+
26
+ export type GameStorageOperation = 'load' | 'save' | 'remove' | 'delete' | 'flush' | 'dispose' | 'validate' | 'migrate' | 'serialize' | 'parse';
27
+
28
+ export class GameStorageError extends Error {
29
+ override readonly name = 'GameStorageError';
30
+
31
+ readonly code: GameStorageErrorCode;
32
+ readonly operation: GameStorageOperation | undefined;
33
+ readonly namespace: string | undefined;
34
+ readonly slot: string | undefined;
35
+ readonly schemaId: string | undefined;
36
+ readonly schemaVersion: number | undefined;
37
+ readonly path: string | undefined;
38
+ override readonly cause: unknown | undefined;
39
+
40
+ constructor(
41
+ message: string,
42
+ options: {
43
+ code: GameStorageErrorCode;
44
+ operation?: GameStorageOperation | undefined;
45
+ namespace?: string | undefined;
46
+ slot?: string | undefined;
47
+ schemaId?: string | undefined;
48
+ schemaVersion?: number | undefined;
49
+ path?: string | undefined;
50
+ cause?: unknown | undefined;
51
+ },
52
+ ) {
53
+ super(message);
54
+ this.code = options.code;
55
+ this.operation = options.operation;
56
+ this.namespace = options.namespace;
57
+ this.slot = options.slot;
58
+ this.schemaId = options.schemaId;
59
+ this.schemaVersion = options.schemaVersion;
60
+ this.path = options.path;
61
+ this.cause = options.cause;
62
+ }
63
+ }
64
+
65
+ export function storageError(
66
+ message: string,
67
+ code: GameStorageErrorCode,
68
+ opts: {
69
+ operation?: GameStorageOperation | undefined;
70
+ namespace?: string | undefined;
71
+ slot?: string | undefined;
72
+ schemaId?: string | undefined;
73
+ schemaVersion?: number | undefined;
74
+ path?: string | undefined;
75
+ cause?: unknown | undefined;
76
+ } = {},
77
+ ): GameStorageError {
78
+ return new GameStorageError(message, {
79
+ code,
80
+ operation: opts.operation,
81
+ namespace: opts.namespace,
82
+ slot: opts.slot,
83
+ schemaId: opts.schemaId,
84
+ schemaVersion: opts.schemaVersion,
85
+ path: opts.path,
86
+ cause: opts.cause,
87
+ });
88
+ }
@@ -0,0 +1,18 @@
1
+ export { GameStorageError } from './errors';
2
+ export type { GameStorageErrorCode, GameStorageOperation } from './errors';
3
+ export { defineGameSave } from './schema';
4
+ export { createGameSaveStore } from './store';
5
+ export { createMemoryStorageAdapter } from './adapters/memory';
6
+ export { createGameStorageAdapter } from './adapters/asyncStorage';
7
+ export { __setAsyncStorageLoader, __getAsyncStorageLoader } from './adapters/asyncStorage';
8
+ export type {
9
+ GameSaveSchema,
10
+ GameStorageAdapter,
11
+ StoredGameEnvelope,
12
+ GameSaveLoadResult,
13
+ GameSaveLoadStatus,
14
+ CreateGameSaveStoreOptions,
15
+ GameSaveStore,
16
+ } from './types';
17
+ export { STORAGE_LIMITS } from './types';
18
+ export { STORAGE_ENVELOPE_FORMAT } from './serialization';