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
@@ -0,0 +1,491 @@
1
+ import type { TileMap2D, TileSet2D } from '../../tilemap/types';
2
+ import { rotatedHalfExtents2D } from '../../camera2d/extents';
3
+
4
+ /**
5
+ * Tile presentation binding (T16-F3/F4).
6
+ *
7
+ * Pure module shared between the JS thread and UI-runtime worklets:
8
+ *
9
+ * - `buildFrameTable` runs ONCE on JS at bind time and produces a flat,
10
+ * worklet-safe numeric lookup (`frameFlat[id*4..id*4+3]`) — no `Map`,
11
+ * no objects, no per-frame lookups on the UI runtime.
12
+ * - `buildTileWindowSnapshot` runs on JS whenever the visible cell window
13
+ * or source binding changes and produces a BOUNDED snapshot sized by the
14
+ * viewport capacity, never by map dimensions.
15
+ * - `writeLayerVisibleBounds` / `fillTileSlots` are worklet-callable and
16
+ * allocation-free: camera interpolation inside the transferred window
17
+ * only reads scalars and pre-transferred arrays.
18
+ *
19
+ * Full map authority stays on the simulation side; the UI runtime never
20
+ * sees `layer.data`, the chunk index, or the map value itself.
21
+ */
22
+
23
+ /** Flat numeric frame lookup: frameFlat[tileId*4] = x, [+1]=y, [+2]=w, [+3]=h. */
24
+ export type TileFrameTable = readonly number[];
25
+
26
+ /**
27
+ * Resolve every declared tile to sheet-frame rectangles ONCE at bind time.
28
+ *
29
+ * Throws a structured error when a referenced frame is missing from the
30
+ * bound sheet OR when its size differs from the map cell — v1 requires
31
+ * frame dimensions to equal cell dimensions (T16-F3).
32
+ */
33
+ export function buildFrameTable(
34
+ tileset: TileSet2D,
35
+ frames: Readonly<Record<string, { x: number; y: number; width: number; height: number }>>,
36
+ cellWidth: number,
37
+ cellHeight: number,
38
+ ): TileFrameTable {
39
+ const maxId = tileset.names.length;
40
+ const flat: number[] = new Array((maxId + 1) * 4).fill(0);
41
+ for (let id = 1; id <= maxId; id++) {
42
+ const name = tileset.nameOfId[id]!;
43
+ const def = tileset.tiles[name]!;
44
+ const rect = frames[def.frame];
45
+ if (rect === undefined) {
46
+ throw new Error(
47
+ `[rn-gamekit/tilemap] frame "${def.frame}" for tile "${name}" is missing from the bound sheet`,
48
+ );
49
+ }
50
+ if (rect.width !== cellWidth || rect.height !== cellHeight) {
51
+ throw new Error(
52
+ `[rn-gamekit/tilemap] frame "${def.frame}" for tile "${name}" is ${rect.width}x${rect.height} but the map cell is ${cellWidth}x${cellHeight}; v1 requires frame dimensions to equal cell dimensions`,
53
+ );
54
+ }
55
+ flat[id * 4] = rect.x;
56
+ flat[id * 4 + 1] = rect.y;
57
+ flat[id * 4 + 2] = rect.width;
58
+ flat[id * 4 + 3] = rect.height;
59
+ }
60
+ return Object.freeze(flat);
61
+ }
62
+
63
+ /** Bounded visible-window snapshot transferred to the UI runtime. */
64
+ export interface TileWindowSnapshot {
65
+ /** Window origin in cell coordinates. */
66
+ readonly x0: number;
67
+ readonly y0: number;
68
+ /** Window extent in cells (ids.length === w*h). */
69
+ readonly w: number;
70
+ readonly h: number;
71
+ /** Row-major tile ids for the window; 0 = empty. */
72
+ readonly ids: readonly number[];
73
+ /** Flat frame lookup shared by all windows of one binding. */
74
+ readonly frameFlat: readonly number[];
75
+ /**
76
+ * Binding generation that published this window (GS-TILE-01). Stamp
77
+ * applied by the binding when it publishes; snapshots built directly
78
+ * (tests, initial empty) carry no generation and never satisfy a bound
79
+ * update. A generation mismatch means a same-size replacement or a
80
+ * remount happened: the window is ignored, never displayed.
81
+ */
82
+ readonly gen?: number;
83
+ }
84
+
85
+ export const EMPTY_TILE_WINDOW: TileWindowSnapshot = Object.freeze({
86
+ x0: 0,
87
+ y0: 0,
88
+ w: 0,
89
+ h: 0,
90
+ ids: Object.freeze([]),
91
+ frameFlat: Object.freeze([]),
92
+ });
93
+
94
+ /**
95
+ * Build a bounded snapshot for the inclusive cell range [x0..x1]×[y0..y1].
96
+ * The range is clamped to the layer; the result size depends ONLY on the
97
+ * requested range (bounded by viewport capacity), never on map size.
98
+ */
99
+ export function buildTileWindowSnapshot(
100
+ map: TileMap2D,
101
+ layerId: string,
102
+ x0: number, y0: number, x1: number, y1: number,
103
+ frameFlat: TileFrameTable,
104
+ ): TileWindowSnapshot {
105
+ const layer = map.layerById[layerId];
106
+ if (layer === undefined) return EMPTY_TILE_WINDOW;
107
+ const cx0 = Math.max(0, Math.min(x0, x1));
108
+ const cy0 = Math.max(0, Math.min(y0, y1));
109
+ const cx1 = Math.min(layer.width - 1, Math.max(x0, x1));
110
+ const cy1 = Math.min(layer.height - 1, Math.max(y0, y1));
111
+ if (cx0 > cx1 || cy0 > cy1) return EMPTY_TILE_WINDOW;
112
+ const w = cx1 - cx0 + 1;
113
+ const h = cy1 - cy0 + 1;
114
+ const ids: number[] = new Array(w * h).fill(0);
115
+ for (let cy = cy0; cy <= cy1; cy++) {
116
+ for (let cx = cx0; cx <= cx1; cx++) {
117
+ const id = layer.data[cy * layer.width + cx]!;
118
+ if (id !== 0) ids[(cy - cy0) * w + (cx - cx0)] = id;
119
+ }
120
+ }
121
+ return Object.freeze({
122
+ x0: cx0,
123
+ y0: cy0,
124
+ w,
125
+ h,
126
+ ids: Object.freeze(ids),
127
+ frameFlat,
128
+ });
129
+ }
130
+
131
+ /** Whether the snapshot fully covers the inclusive cell range. */
132
+ export function windowCovers(
133
+ snap: TileWindowSnapshot,
134
+ x0: number, y0: number, x1: number, y1: number,
135
+ ): boolean {
136
+ 'worklet';
137
+ if (snap.w === 0 || snap.h === 0) return false;
138
+ return snap.x0 <= x0 && snap.y0 <= y0 && snap.x0 + snap.w - 1 >= x1 && snap.y0 + snap.h - 1 >= y1;
139
+ }
140
+
141
+ // Minimal structural mirrors of the shared refs, keeping this pure module
142
+ // free of Reanimated/RN imports while accepting real SharedValues.
143
+ interface SharedLike<T> {
144
+ readonly value?: T;
145
+ }
146
+ export type SharedCameraRef = SharedLike<
147
+ { camera?: { center: { x: number; y: number }; zoom: number; rotationRadians: number } } | undefined
148
+ >;
149
+ export type SharedViewportRef = SharedLike<
150
+ { visibleLogicalBounds?: { x: number; y: number; width: number; height: number } } | undefined
151
+ >;
152
+
153
+ export interface LayerBounds {
154
+ minX: number;
155
+ minY: number;
156
+ maxX: number;
157
+ maxY: number;
158
+ }
159
+
160
+ /**
161
+ * Write the conservative world-space bounds visible through the PRESENTED
162
+ * camera into `out` (T16-F3, reworked per T16-RF2).
163
+ *
164
+ * - With a presented camera: the logical view rect is rotated/zoomed by the
165
+ * camera, so its axis-aligned world bounds are the center plus rotated
166
+ * half-extents; the GameLayer2D parallax model applies ONCE afterwards
167
+ * (effective layer center C′ = L + (C − L)·p; zoom and rotation apply
168
+ * fully at every factor). Padding is world units.
169
+ * - WITHOUT a presented camera, GameWorld2D's viewport-only path applies:
170
+ * the bounds are `viewport.visibleLogicalBounds` expanded by the padding.
171
+ *
172
+ * Worklet-callable and allocation-free on the steady path: scalars only,
173
+ * results written into the caller-owned `out` scratch object. Returns false
174
+ * when no viewport bounds exist yet.
175
+ */
176
+ export function writeLayerVisibleBounds(
177
+ camera: SharedCameraRef | null,
178
+ viewport: SharedViewportRef | null,
179
+ parallaxX: number,
180
+ parallaxY: number,
181
+ paddingWorld: number,
182
+ ): LayerBounds | null {
183
+ 'worklet';
184
+ const view = viewport?.value?.visibleLogicalBounds;
185
+ if (view === undefined) return null;
186
+ const cam = camera?.value?.camera;
187
+ if (cam === undefined) {
188
+ // Viewport-only world: no zoom, no rotation, no parallax correction.
189
+ return {
190
+ minX: view.x - paddingWorld,
191
+ minY: view.y - paddingWorld,
192
+ maxX: view.x + view.width + paddingWorld,
193
+ maxY: view.y + view.height + paddingWorld,
194
+ };
195
+ }
196
+ const hx = view.width / (2 * cam.zoom);
197
+ const hy = view.height / (2 * cam.zoom);
198
+ const extent = rotatedHalfExtents2D(hx, hy, cam.rotationRadians);
199
+ const ex = extent.x + paddingWorld;
200
+ const ey = extent.y + paddingWorld;
201
+ // Parallax AFTER base bounds: shift the center contribution only.
202
+ let centerX = cam.center.x;
203
+ let centerY = cam.center.y;
204
+ if (parallaxX !== 1 || parallaxY !== 1) {
205
+ const logicalCx = view.x + view.width / 2;
206
+ const logicalCy = view.y + view.height / 2;
207
+ centerX = logicalCx + (centerX - logicalCx) * parallaxX;
208
+ centerY = logicalCy + (centerY - logicalCy) * parallaxY;
209
+ }
210
+ return {
211
+ minX: centerX - ex,
212
+ minY: centerY - ey,
213
+ maxX: centerX + ex,
214
+ maxY: centerY + ey,
215
+ };
216
+ }
217
+
218
+ /** Slot-buffer contract shared by the component and tests. */
219
+ export interface TileSlotBuffers {
220
+ readonly rects: readonly (SlotRect | undefined)[];
221
+ readonly xforms: readonly (SlotXform | undefined)[];
222
+ }
223
+ export interface SlotRect {
224
+ setXYWH(x: number, y: number, w: number, h: number): void;
225
+ }
226
+ export interface SlotXform {
227
+ set(scos: number, ssin: number, tx: number, ty: number): void;
228
+ }
229
+
230
+ export interface FillParams {
231
+ readonly cw: number;
232
+ readonly ch: number;
233
+ readonly originX: number;
234
+ readonly originY: number;
235
+ readonly layerWidth: number;
236
+ readonly layerHeight: number;
237
+ readonly capacity: number;
238
+ }
239
+
240
+ /**
241
+ * Fill Atlas slot buffers from the transferred window for the currently
242
+ * visible cell span (worklet-callable, T16-F3/F4).
243
+ *
244
+ * - Cell range derives from `bounds` (already camera+parallax+padding).
245
+ * - Tiles place UNROTATED at their CELL TOP-LEFT: the RSXform translation
246
+ * is the cell's world top-left corner.
247
+ * - Stale slots past the filled count are hidden atomically (zero-size).
248
+ * - Returns the filled slot count on success; returns -1 when the window
249
+ * does not cover the visible span (caller should request a new window)
250
+ * and -2 when the visible span exceeds the fixed capacity (caller must
251
+ * hide the whole layer and never claim partial success) — T16-SF2.
252
+ */
253
+ export function fillTileSlots(
254
+ snap: TileWindowSnapshot,
255
+ bounds: LayerBounds,
256
+ rects: readonly (SlotRect | undefined)[],
257
+ xforms: readonly (SlotXform | undefined)[],
258
+ params: FillParams,
259
+ ): number {
260
+ 'worklet';
261
+ const { cw, ch, originX, originY, layerWidth, layerHeight, capacity } = params;
262
+ let cx0 = Math.floor((bounds.minX - originX) / cw);
263
+ let cy0 = Math.floor((bounds.minY - originY) / ch);
264
+ let cx1 = Math.floor((bounds.maxX - originX) / cw);
265
+ let cy1 = Math.floor((bounds.maxY - originY) / ch);
266
+ cx0 = Math.max(0, cx0);
267
+ cy0 = Math.max(0, cy0);
268
+ cx1 = Math.min(layerWidth - 1, cx1);
269
+ cy1 = Math.min(layerHeight - 1, cy1);
270
+ if (cx0 > cx1 || cy0 > cy1) {
271
+ hideRange(rects, 0, capacity);
272
+ return 0;
273
+ }
274
+ // Preflight the span against capacity so a rotated AABB never produces a
275
+ // partial visible region (T16-SF2). Every cell in the span could be
276
+ // occupied, so compare the worst-case span size to the fixed buffer.
277
+ const spanCells = (cx1 - cx0 + 1) * (cy1 - cy0 + 1);
278
+ if (spanCells > capacity) {
279
+ hideRange(rects, 0, capacity);
280
+ return -2;
281
+ }
282
+ if (!windowCovers(snap, cx0, cy0, cx1, cy1)) {
283
+ return -1;
284
+ }
285
+ let slot = 0;
286
+ for (let cy = cy0; cy <= cy1; cy++) {
287
+ for (let cx = cx0; cx <= cx1; cx++) {
288
+ const id = snap.ids[(cy - snap.y0) * snap.w + (cx - snap.x0)]!;
289
+ if (id === 0) continue;
290
+ if (slot >= capacity) {
291
+ hideRange(rects, 0, capacity);
292
+ return -2;
293
+ }
294
+ const rectSlot = rects[slot];
295
+ const xformSlot = xforms[slot];
296
+ if (rectSlot === undefined || xformSlot === undefined) continue;
297
+ rectSlot.setXYWH(
298
+ snap.frameFlat[id * 4]!,
299
+ snap.frameFlat[id * 4 + 1]!,
300
+ snap.frameFlat[id * 4 + 2]!,
301
+ snap.frameFlat[id * 4 + 3]!,
302
+ );
303
+ // Unrotated placement at the cell's world TOP-LEFT corner.
304
+ xformSlot.set(1, 0, originX + cx * cw, originY + cy * ch);
305
+ slot++;
306
+ }
307
+ }
308
+ // Hide remaining stale slots atomically.
309
+ for (let i = slot; i < capacity; i++) {
310
+ rects[i]?.setXYWH(0, 0, 0, 0);
311
+ }
312
+ return slot;
313
+ }
314
+
315
+ function hideRange(rects: readonly (SlotRect | undefined)[], from: number, to: number): void {
316
+ 'worklet';
317
+ for (let i = from; i < to; i++) {
318
+ rects[i]?.setXYWH(0, 0, 0, 0);
319
+ }
320
+ }
321
+
322
+ /** Stable per-binding generation from object identity (GS-TILE-01). */
323
+ const bindingGenerations = new WeakMap<object, number>();
324
+ let nextBindingGeneration = 1;
325
+
326
+ /**
327
+ * Mint (or recall) the generation for one binding identity object. The
328
+ * component creates a fresh identity per binding-affecting prop change, so
329
+ * each binding gets a distinct generation with no counters in React state.
330
+ */
331
+ export function bindingGeneration(binding: object): number {
332
+ let gen = bindingGenerations.get(binding);
333
+ if (gen === undefined) {
334
+ gen = nextBindingGeneration;
335
+ nextBindingGeneration += 1;
336
+ bindingGenerations.set(binding, gen);
337
+ }
338
+ return gen;
339
+ }
340
+
341
+ /** Shared-value mirrors kept structural so headless fakes can drive updates. */
342
+ export interface TileWindowShared {
343
+ value: TileWindowSnapshot;
344
+ }
345
+ export interface TileNumberShared {
346
+ value: number;
347
+ }
348
+ export interface TileBooleanShared {
349
+ value: boolean;
350
+ }
351
+
352
+ /**
353
+ * Inputs for one tile-layer UI update (GS-TILE-01).
354
+ *
355
+ * Everything the update may touch is listed here: scalars, shared values,
356
+ * buffers, and callbacks. Map, layer, and frame-table objects are
357
+ * deliberately absent — the UI closure provably cannot capture layer data
358
+ * because it is never passed (scalar layer dims travel in `layerWidth` /
359
+ * `layerHeight`). The binding `generation` gates every window and request.
360
+ */
361
+ export interface TileLayerUIParams {
362
+ readonly camera: SharedCameraRef | null;
363
+ readonly viewport: SharedViewportRef | null;
364
+ readonly window: TileWindowShared;
365
+ /** Generation of the in-flight request, or -1 when none is pending. */
366
+ readonly pendingGen: TileNumberShared;
367
+ readonly warnedCapacity: TileBooleanShared;
368
+ readonly capacityWarnPending: TileBooleanShared;
369
+ readonly rects: { value: readonly (SlotRect | undefined)[] };
370
+ readonly xforms: { value: readonly (SlotXform | undefined)[] };
371
+ /**
372
+ * Publish a window for `gen` (JS side). Stale deliveries whose `gen`
373
+ * predates the publisher's binding are rejected before publishing; the
374
+ * update additionally refuses to display any window whose stamp differs
375
+ * from the live generation.
376
+ */
377
+ readonly requestWindow: (gen: number, x0: number, y0: number, x1: number, y1: number) => void;
378
+ /** Bridge crossing to the JS side (scheduleOnRN in production). */
379
+ readonly scheduleOnRN: (fn: () => void) => void;
380
+ readonly onBeyondCapacity: () => void;
381
+ readonly generation: number;
382
+ readonly capacity: number;
383
+ readonly originX: number;
384
+ readonly originY: number;
385
+ readonly cw: number;
386
+ readonly ch: number;
387
+ readonly layerWidth: number;
388
+ readonly layerHeight: number;
389
+ readonly padWorld: number;
390
+ readonly px: number;
391
+ readonly py: number;
392
+ readonly minZoom: number;
393
+ }
394
+
395
+ /**
396
+ * One tile-layer UI update: the body of the layer's derived value,
397
+ * extracted so binding identity, stale-request rejection, and capacity
398
+ * policy execute identically in tests and on the UI runtime (GS-TILE-01).
399
+ *
400
+ * Returns the filled slot count; -1 when a window was requested, -2 when
401
+ * the span exceeds capacity or zoom left the declared bounds, 0 when
402
+ * nothing is visible. A window whose generation stamp differs from the
403
+ * live binding is treated exactly like a missing window.
404
+ */
405
+ export function updateTileLayerUI(params: TileLayerUIParams): number {
406
+ 'worklet';
407
+ const {
408
+ camera,
409
+ viewport,
410
+ window,
411
+ pendingGen,
412
+ warnedCapacity,
413
+ capacityWarnPending,
414
+ rects,
415
+ xforms,
416
+ requestWindow,
417
+ scheduleOnRN,
418
+ onBeyondCapacity,
419
+ generation,
420
+ capacity,
421
+ originX,
422
+ originY,
423
+ cw,
424
+ ch,
425
+ layerWidth,
426
+ layerHeight,
427
+ padWorld,
428
+ px,
429
+ py,
430
+ minZoom,
431
+ } = params;
432
+ // Rejected camera state: zoomed out beyond the declared capacity.
433
+ const camZoom = camera?.value?.camera?.zoom;
434
+ if (camZoom !== undefined && camZoom < minZoom * (1 - 1e-3)) {
435
+ for (let i = 0; i < capacity; i++) {
436
+ rects.value[i]?.setXYWH(0, 0, 0, 0);
437
+ }
438
+ if (!warnedCapacity.value && !capacityWarnPending.value) {
439
+ capacityWarnPending.value = true;
440
+ scheduleOnRN(onBeyondCapacity);
441
+ }
442
+ return -2;
443
+ }
444
+ const bounds = writeLayerVisibleBounds(camera, viewport, px, py, padWorld);
445
+ if (bounds === null) {
446
+ return 0;
447
+ }
448
+ const cx0 = Math.max(0, Math.floor((bounds.minX - originX) / cw));
449
+ const cy0 = Math.max(0, Math.floor((bounds.minY - originY) / ch));
450
+ const cx1 = Math.min(layerWidth - 1, Math.floor((bounds.maxX - originX) / cw));
451
+ const cy1 = Math.min(layerHeight - 1, Math.floor((bounds.maxY - originY) / ch));
452
+ if (cx0 > cx1 || cy0 > cy1) {
453
+ // Off-map view: hide everything.
454
+ for (let i = 0; i < capacity; i++) {
455
+ rects.value[i]?.setXYWH(0, 0, 0, 0);
456
+ }
457
+ return 0;
458
+ }
459
+ const snap = window.value;
460
+ // GS-TILE-01: the generation stamp decides before coordinates do. A stale
461
+ // window (same-size replacement, remount, late delivery) takes the
462
+ // request path exactly like a missing window.
463
+ if (snap.gen !== generation) {
464
+ if (pendingGen.value !== generation) {
465
+ pendingGen.value = generation;
466
+ scheduleOnRN(() => requestWindow(generation, cx0, cy0, cx1, cy1));
467
+ }
468
+ return -1;
469
+ }
470
+ const filled = fillTileSlots(
471
+ snap,
472
+ bounds,
473
+ rects.value,
474
+ xforms.value,
475
+ { cw, ch, originX, originY, layerWidth, layerHeight, capacity },
476
+ );
477
+ if (filled === -1 && pendingGen.value !== generation) {
478
+ pendingGen.value = generation;
479
+ scheduleOnRN(() => requestWindow(generation, cx0, cy0, cx1, cy1));
480
+ return -1;
481
+ }
482
+ if (filled === -2) {
483
+ // Capacity insufficient even at a valid zoom (e.g. extreme rotation
484
+ // on a fully occupied span) — hide everything, never partial.
485
+ for (let i = 0; i < capacity; i++) {
486
+ rects.value[i]?.setXYWH(0, 0, 0, 0);
487
+ }
488
+ return -2;
489
+ }
490
+ return filled;
491
+ }
@@ -0,0 +1,90 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { createGameSession } from '../core/session/createGameSession';
3
+ import type { GameSession } from '../core/session/types';
4
+ import type { GameDefinition, InputMap, SceneMap } from '../definition/types';
5
+
6
+ type SessionCreator<TScenes extends SceneMap, TInput extends InputMap> = (
7
+ definition: GameDefinition<TScenes, TInput>,
8
+ ) => GameSession<TScenes, TInput>;
9
+
10
+ interface OwnedSession<TScenes extends SceneMap, TInput extends InputMap> {
11
+ /** The definition this session was created from, compared by identity. */
12
+ readonly definition: GameDefinition<TScenes, TInput>;
13
+ /** The live session owned by this hook instance. */
14
+ readonly session: GameSession<TScenes, TInput>;
15
+ }
16
+
17
+ /**
18
+ * Create and own a `GameSession` for a `GameDefinition`, with React
19
+ * ownership.
20
+ *
21
+ * The hook creates an idle session during the commit phase, publishes it,
22
+ * and disposes it exactly once when it is replaced or the owner unmounts.
23
+ * React Strict Mode's development setup/cleanup rehearsal is safe: every
24
+ * rehearsal session is disposed exactly once and a disposed session is never
25
+ * published.
26
+ *
27
+ * Ownership rules:
28
+ *
29
+ * - The return value is `undefined` until React commits a live session for
30
+ * the current definition: the initial render, and the boundary while a
31
+ * definition replacement is being created. Render a deliberate fallback
32
+ * instead of hiding it.
33
+ * - The same definition object returns the same session across re-renders.
34
+ * A different definition object unpublishes the old session, disposes it,
35
+ * and publishes a fresh one. Disposed sessions are never revived, so
36
+ * declaring definitions at module scope keeps identity stable.
37
+ * - The hook owns terminal disposal. Do not call `session.dispose()` on a
38
+ * hook-owned session.
39
+ * - The hook does not start the session. Pass it to `GameView`, which binds,
40
+ * starts, pauses on unmount/backgrounding, and never terminally disposes a
41
+ * borrowed session.
42
+ * - For an asset-backed game, mount the component that calls this hook only
43
+ * after `useGameAssets()` reports `ready`; this hook does not load assets.
44
+ *
45
+ * Use `createGameSession()` with explicit `try/finally` disposal for headless
46
+ * tests, non-React programs, and custom surface controllers that need to own
47
+ * sessions imperatively.
48
+ */
49
+ export function useGameSession<TScenes extends SceneMap, TInput extends InputMap>(
50
+ definition: GameDefinition<TScenes, TInput>,
51
+ ): GameSession<TScenes, TInput> | undefined {
52
+ return useOwnedGameSession(definition, createGameSession);
53
+ }
54
+
55
+ /**
56
+ * @internal
57
+ *
58
+ * The injectable-creator seam behind `useGameSession`, exported from this
59
+ * module only (never from the `rn-gamekit/react` barrel). Tests supply a
60
+ * deterministic creator (for example `createGameSessionWithDriver` with a
61
+ * `ManualFrameDriver`, since node has no `requestAnimationFrame`) and must
62
+ * pass a stable factory identity across renders.
63
+ */
64
+ export function useOwnedGameSession<TScenes extends SceneMap, TInput extends InputMap>(
65
+ definition: GameDefinition<TScenes, TInput>,
66
+ create: SessionCreator<TScenes, TInput>,
67
+ ): GameSession<TScenes, TInput> | undefined {
68
+ const [owned, setOwned] = useState<OwnedSession<TScenes, TInput> | undefined>(undefined);
69
+
70
+ // Render-phase selector: publish a session only while its definition is
71
+ // the current prop and its status is not disposed. A replacement render
72
+ // therefore unpublishes the old session before any effect runs, and
73
+ // `undefined` is the only other value.
74
+ const session =
75
+ owned !== undefined &&
76
+ owned.definition === definition &&
77
+ owned.session.status !== 'disposed'
78
+ ? owned.session
79
+ : undefined;
80
+
81
+ useEffect(() => {
82
+ const next = create(definition);
83
+ setOwned({ definition, session: next });
84
+ return () => {
85
+ next.dispose();
86
+ };
87
+ }, [definition, create]);
88
+
89
+ return session;
90
+ }
@@ -0,0 +1,53 @@
1
+ import { useCallback, useSyncExternalStore } from 'react';
2
+ import type { GameSession, GameSessionStatus } from '../core/session/types';
3
+ import type { InputMap, SceneMap } from '../definition/types';
4
+
5
+ /** Stable no-op cleanup for the absent/disposed session branch. */
6
+ const unsubscribeNothing = (): void => {};
7
+
8
+ /**
9
+ * Observe a session's lifecycle status from React.
10
+ *
11
+ * Returns the current `session.status` on the render that observes a
12
+ * session, and re-renders once per actual lifecycle transition. `undefined`
13
+ * means no session is currently available — the same meaning Task 9's
14
+ * `useGameSession()` gives its pre-commit value, so both hooks compose
15
+ * unconditionally:
16
+ *
17
+ * ```ts
18
+ * const session = useGameSession(game);
19
+ * const status = useGameSessionStatus(session);
20
+ * ```
21
+ *
22
+ * The hook subscribes through `addStatusListener` and never polls; it owns
23
+ * no session and never disposes one. Replacing the session argument detaches
24
+ * the old subscription before the replacement's status is reported, and
25
+ * idempotent lifecycle commands do not cause redundant re-renders.
26
+ */
27
+ export function useGameSessionStatus<
28
+ TScenes extends SceneMap,
29
+ TInput extends InputMap,
30
+ >(session: GameSession<TScenes, TInput> | undefined): GameSessionStatus | undefined {
31
+ // The callbacks are memoized on the session identity only, so unrelated
32
+ // parent renders never tear down and recreate the subscription; a session
33
+ // prop change produces new identities and React detaches the old session
34
+ // before attaching the replacement.
35
+ const subscribe = useCallback(
36
+ (onStoreChange: () => void) => {
37
+ // Never subscribe to a disposed session: its terminal notification is
38
+ // already delivered, and addStatusListener follows the disposed-error
39
+ // policy for new subscribers.
40
+ if (session === undefined || session.status === 'disposed') {
41
+ return unsubscribeNothing;
42
+ }
43
+ const subscription = session.addStatusListener(onStoreChange);
44
+ return () => {
45
+ subscription.remove();
46
+ };
47
+ },
48
+ [session],
49
+ );
50
+ const getSnapshot = useCallback(() => session?.status, [session]);
51
+
52
+ return useSyncExternalStore(subscribe, getSnapshot);
53
+ }
@@ -76,7 +76,11 @@ export class ViewportBinding {
76
76
  };
77
77
  }
78
78
 
79
- /** Release subscribers. The binding becomes inert. */
79
+ /**
80
+ * Release current subscribers (GS-VIEWPORT-01). This is not a lifecycle
81
+ * gate: late subscriptions still register and setSurfaceSize still
82
+ * resolves. Discard the binding after disposal instead of reusing it.
83
+ */
80
84
  dispose(): void {
81
85
  this.#listeners.clear();
82
86
  }
package/src/react.ts CHANGED
@@ -1,8 +1,15 @@
1
1
  export { GameView } from './react/GameView';
2
+ export { useGameSession } from './react/useGameSession';
3
+ export { useGameSessionStatus } from './react/useGameSessionStatus';
4
+ export { createGameLifecycleSource, GameLifecycleProvider, useGameLifecycleSource } from './react/lifecycleSource';
5
+ export type { GameLifecycleSource } from './core/session/types';
2
6
  export { createGameAssetStore } from './react/assets/decodeSkiaImage';
3
7
  export { useGameAssets, stableGroupsKey } from './react/assets/useGameAssets';
4
8
  export type { GameAssetsState } from './react/assets/useGameAssets';
5
- export { GameWorld2D, viewportTransform } from './react/sprites/GameWorld2D';
9
+ export { GameWorld2D, viewportTransform, cameraViewportTransform2D, layerParallaxTransform2D } from './react/sprites/GameWorld2D';
10
+ export { GameLayer2D } from './react/camera2d/GameLayer2D';
11
+ export { defineGameCamera2D } from './react/camera2d/defineGameCamera2D';
12
+ export type { GameCamera2DDefinition } from './react/camera2d/defineGameCamera2D';
6
13
  export { Sprite, resolveSpriteFrameRect } from './react/sprites/Sprite';
7
14
  export type { SpriteAnimatable, SpriteAnimatableBoolean, SpriteProps } from './react/sprites/Sprite';
8
15
  export { GameSprite, spriteFrameNameForClip } from './react/sprites/GameSprite';
@@ -34,4 +41,14 @@ export type {
34
41
  export type { GameRendererProps, GameViewProps } from './react/GameView';
35
42
  export { GamePointerInput } from './react/GamePointerInput';
36
43
  export type { GamePointerInputProps } from './react/GamePointerInput';
44
+ export { GameButtonPad, GameButton } from './react/GameButtonPad';
45
+ export type { GameButtonPadProps, GameButtonProps, ButtonActionName } from './react/GameButtonPad';
37
46
  export type { GamePointerInstrumentation, GameViewInstrumentation } from './react/instrumentation';
47
+ export { ParticleView } from './react/particles/ParticleView';
48
+ export type { ParticleViewProps } from './react/particles/ParticleView';
49
+ export { useParticlePresentation } from './react/particles/useParticlePresentation';
50
+ export type { ParticlePresentation } from './react/particles/useParticlePresentation';
51
+ export { particleSpriteXform, assertUniformParticleSpriteRatio } from './react/particles/spriteXForm';
52
+ export { cameraVisibleWorldBounds, visibleInBounds, PARTICLE_CULL_PADDING } from './react/particles/culling';
53
+ export { TileMapLayer2D } from './react/tilemap/TileMapLayer2D';
54
+ export type { TileMapLayer2DProps } from './react/tilemap/TileMapLayer2D';