rn-gamekit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +21 -0
  3. package/README.md +131 -0
  4. package/lib/module/assets/defineAssets.js +48 -0
  5. package/lib/module/assets/defineAssets.js.map +1 -0
  6. package/lib/module/assets/errors.js +38 -0
  7. package/lib/module/assets/errors.js.map +1 -0
  8. package/lib/module/assets/types.js +2 -0
  9. package/lib/module/assets/types.js.map +1 -0
  10. package/lib/module/assets/validation.js +99 -0
  11. package/lib/module/assets/validation.js.map +1 -0
  12. package/lib/module/core/frameDriver.js +20 -0
  13. package/lib/module/core/frameDriver.js.map +1 -0
  14. package/lib/module/core/input/createInputBuffer.js +296 -0
  15. package/lib/module/core/input/createInputBuffer.js.map +1 -0
  16. package/lib/module/core/input/types.js +4 -0
  17. package/lib/module/core/input/types.js.map +1 -0
  18. package/lib/module/core/session/createGameSession.js +554 -0
  19. package/lib/module/core/session/createGameSession.js.map +1 -0
  20. package/lib/module/core/session/deepFreeze.js +155 -0
  21. package/lib/module/core/session/deepFreeze.js.map +1 -0
  22. package/lib/module/core/session/diagnostics.js +2 -0
  23. package/lib/module/core/session/diagnostics.js.map +1 -0
  24. package/lib/module/core/session/types.js +43 -0
  25. package/lib/module/core/session/types.js.map +1 -0
  26. package/lib/module/definition/defineGame.js +57 -0
  27. package/lib/module/definition/defineGame.js.map +1 -0
  28. package/lib/module/definition/types.js +4 -0
  29. package/lib/module/definition/types.js.map +1 -0
  30. package/lib/module/geometry/types.js +2 -0
  31. package/lib/module/geometry/types.js.map +1 -0
  32. package/lib/module/index.js +12 -0
  33. package/lib/module/index.js.map +1 -0
  34. package/lib/module/package.json +1 -0
  35. package/lib/module/react/GamePointerInput.js +385 -0
  36. package/lib/module/react/GamePointerInput.js.map +1 -0
  37. package/lib/module/react/GameView.js +223 -0
  38. package/lib/module/react/GameView.js.map +1 -0
  39. package/lib/module/react/alphaClock.js +42 -0
  40. package/lib/module/react/alphaClock.js.map +1 -0
  41. package/lib/module/react/assets/createGameAssetStore.js +358 -0
  42. package/lib/module/react/assets/createGameAssetStore.js.map +1 -0
  43. package/lib/module/react/assets/decodeSkiaImage.js +54 -0
  44. package/lib/module/react/assets/decodeSkiaImage.js.map +1 -0
  45. package/lib/module/react/assets/errors.js +10 -0
  46. package/lib/module/react/assets/errors.js.map +1 -0
  47. package/lib/module/react/assets/useGameAssets.js +160 -0
  48. package/lib/module/react/assets/useGameAssets.js.map +1 -0
  49. package/lib/module/react/bindAppLifecycle.js +58 -0
  50. package/lib/module/react/bindAppLifecycle.js.map +1 -0
  51. package/lib/module/react/bindGameSession.js +37 -0
  52. package/lib/module/react/bindGameSession.js.map +1 -0
  53. package/lib/module/react/gestureLifecycle.js +68 -0
  54. package/lib/module/react/gestureLifecycle.js.map +1 -0
  55. package/lib/module/react/instrumentation.js +4 -0
  56. package/lib/module/react/instrumentation.js.map +1 -0
  57. package/lib/module/react/pointerBinding.js +196 -0
  58. package/lib/module/react/pointerBinding.js.map +1 -0
  59. package/lib/module/react/pointerCoalescer.js +224 -0
  60. package/lib/module/react/pointerCoalescer.js.map +1 -0
  61. package/lib/module/react/pointerContainment.js +27 -0
  62. package/lib/module/react/pointerContainment.js.map +1 -0
  63. package/lib/module/react/sprites/GameSprite.js +116 -0
  64. package/lib/module/react/sprites/GameSprite.js.map +1 -0
  65. package/lib/module/react/sprites/GameWorld2D.js +44 -0
  66. package/lib/module/react/sprites/GameWorld2D.js.map +1 -0
  67. package/lib/module/react/sprites/Sprite.js +147 -0
  68. package/lib/module/react/sprites/Sprite.js.map +1 -0
  69. package/lib/module/react/sprites/SpriteBatch.js +173 -0
  70. package/lib/module/react/sprites/SpriteBatch.js.map +1 -0
  71. package/lib/module/react/sprites/spriteBatchPolicy.js +25 -0
  72. package/lib/module/react/sprites/spriteBatchPolicy.js.map +1 -0
  73. package/lib/module/react/sprites/spriteTransform.js +135 -0
  74. package/lib/module/react/sprites/spriteTransform.js.map +1 -0
  75. package/lib/module/react/viewportBinding.js +101 -0
  76. package/lib/module/react/viewportBinding.js.map +1 -0
  77. package/lib/module/react.js +13 -0
  78. package/lib/module/react.js.map +1 -0
  79. package/lib/module/scene/defineScene.js +29 -0
  80. package/lib/module/scene/defineScene.js.map +1 -0
  81. package/lib/module/scene/types.js +4 -0
  82. package/lib/module/scene/types.js.map +1 -0
  83. package/lib/module/sprites/sampleSpriteClip.js +50 -0
  84. package/lib/module/sprites/sampleSpriteClip.js.map +1 -0
  85. package/lib/module/sprites/spriteAnimationState.js +165 -0
  86. package/lib/module/sprites/spriteAnimationState.js.map +1 -0
  87. package/lib/module/testing.js +57 -0
  88. package/lib/module/testing.js.map +1 -0
  89. package/lib/module/viewport2d/index.js +4 -0
  90. package/lib/module/viewport2d/index.js.map +1 -0
  91. package/lib/module/viewport2d/math.js +129 -0
  92. package/lib/module/viewport2d/math.js.map +1 -0
  93. package/lib/module/viewport2d/types.js +2 -0
  94. package/lib/module/viewport2d/types.js.map +1 -0
  95. package/lib/typescript/package.json +1 -0
  96. package/lib/typescript/src/assets/defineAssets.d.ts +20 -0
  97. package/lib/typescript/src/assets/defineAssets.d.ts.map +1 -0
  98. package/lib/typescript/src/assets/errors.d.ts +20 -0
  99. package/lib/typescript/src/assets/errors.d.ts.map +1 -0
  100. package/lib/typescript/src/assets/types.d.ts +138 -0
  101. package/lib/typescript/src/assets/types.d.ts.map +1 -0
  102. package/lib/typescript/src/assets/validation.d.ts +15 -0
  103. package/lib/typescript/src/assets/validation.d.ts.map +1 -0
  104. package/lib/typescript/src/core/frameDriver.d.ts +12 -0
  105. package/lib/typescript/src/core/frameDriver.d.ts.map +1 -0
  106. package/lib/typescript/src/core/input/createInputBuffer.d.ts +12 -0
  107. package/lib/typescript/src/core/input/createInputBuffer.d.ts.map +1 -0
  108. package/lib/typescript/src/core/input/types.d.ts +64 -0
  109. package/lib/typescript/src/core/input/types.d.ts.map +1 -0
  110. package/lib/typescript/src/core/session/createGameSession.d.ts +18 -0
  111. package/lib/typescript/src/core/session/createGameSession.d.ts.map +1 -0
  112. package/lib/typescript/src/core/session/deepFreeze.d.ts +27 -0
  113. package/lib/typescript/src/core/session/deepFreeze.d.ts.map +1 -0
  114. package/lib/typescript/src/core/session/diagnostics.d.ts +36 -0
  115. package/lib/typescript/src/core/session/diagnostics.d.ts.map +1 -0
  116. package/lib/typescript/src/core/session/types.d.ts +104 -0
  117. package/lib/typescript/src/core/session/types.d.ts.map +1 -0
  118. package/lib/typescript/src/definition/defineGame.d.ts +66 -0
  119. package/lib/typescript/src/definition/defineGame.d.ts.map +1 -0
  120. package/lib/typescript/src/definition/types.d.ts +56 -0
  121. package/lib/typescript/src/definition/types.d.ts.map +1 -0
  122. package/lib/typescript/src/geometry/types.d.ts +8 -0
  123. package/lib/typescript/src/geometry/types.d.ts.map +1 -0
  124. package/lib/typescript/src/index.d.ts +18 -0
  125. package/lib/typescript/src/index.d.ts.map +1 -0
  126. package/lib/typescript/src/react/GamePointerInput.d.ts +37 -0
  127. package/lib/typescript/src/react/GamePointerInput.d.ts.map +1 -0
  128. package/lib/typescript/src/react/GameView.d.ts +61 -0
  129. package/lib/typescript/src/react/GameView.d.ts.map +1 -0
  130. package/lib/typescript/src/react/alphaClock.d.ts +29 -0
  131. package/lib/typescript/src/react/alphaClock.d.ts.map +1 -0
  132. package/lib/typescript/src/react/assets/createGameAssetStore.d.ts +33 -0
  133. package/lib/typescript/src/react/assets/createGameAssetStore.d.ts.map +1 -0
  134. package/lib/typescript/src/react/assets/decodeSkiaImage.d.ts +12 -0
  135. package/lib/typescript/src/react/assets/decodeSkiaImage.d.ts.map +1 -0
  136. package/lib/typescript/src/react/assets/errors.d.ts +8 -0
  137. package/lib/typescript/src/react/assets/errors.d.ts.map +1 -0
  138. package/lib/typescript/src/react/assets/useGameAssets.d.ts +35 -0
  139. package/lib/typescript/src/react/assets/useGameAssets.d.ts.map +1 -0
  140. package/lib/typescript/src/react/bindAppLifecycle.d.ts +32 -0
  141. package/lib/typescript/src/react/bindAppLifecycle.d.ts.map +1 -0
  142. package/lib/typescript/src/react/bindGameSession.d.ts +14 -0
  143. package/lib/typescript/src/react/bindGameSession.d.ts.map +1 -0
  144. package/lib/typescript/src/react/gestureLifecycle.d.ts +37 -0
  145. package/lib/typescript/src/react/gestureLifecycle.d.ts.map +1 -0
  146. package/lib/typescript/src/react/instrumentation.d.ts +47 -0
  147. package/lib/typescript/src/react/instrumentation.d.ts.map +1 -0
  148. package/lib/typescript/src/react/pointerBinding.d.ts +104 -0
  149. package/lib/typescript/src/react/pointerBinding.d.ts.map +1 -0
  150. package/lib/typescript/src/react/pointerCoalescer.d.ts +106 -0
  151. package/lib/typescript/src/react/pointerCoalescer.d.ts.map +1 -0
  152. package/lib/typescript/src/react/pointerContainment.d.ts +12 -0
  153. package/lib/typescript/src/react/pointerContainment.d.ts.map +1 -0
  154. package/lib/typescript/src/react/sprites/GameSprite.d.ts +75 -0
  155. package/lib/typescript/src/react/sprites/GameSprite.d.ts.map +1 -0
  156. package/lib/typescript/src/react/sprites/GameWorld2D.d.ts +29 -0
  157. package/lib/typescript/src/react/sprites/GameWorld2D.d.ts.map +1 -0
  158. package/lib/typescript/src/react/sprites/Sprite.d.ts +43 -0
  159. package/lib/typescript/src/react/sprites/Sprite.d.ts.map +1 -0
  160. package/lib/typescript/src/react/sprites/SpriteBatch.d.ts +41 -0
  161. package/lib/typescript/src/react/sprites/SpriteBatch.d.ts.map +1 -0
  162. package/lib/typescript/src/react/sprites/spriteBatchPolicy.d.ts +10 -0
  163. package/lib/typescript/src/react/sprites/spriteBatchPolicy.d.ts.map +1 -0
  164. package/lib/typescript/src/react/sprites/spriteTransform.d.ts +86 -0
  165. package/lib/typescript/src/react/sprites/spriteTransform.d.ts.map +1 -0
  166. package/lib/typescript/src/react/viewportBinding.d.ts +42 -0
  167. package/lib/typescript/src/react/viewportBinding.d.ts.map +1 -0
  168. package/lib/typescript/src/react.d.ts +20 -0
  169. package/lib/typescript/src/react.d.ts.map +1 -0
  170. package/lib/typescript/src/scene/defineScene.d.ts +26 -0
  171. package/lib/typescript/src/scene/defineScene.d.ts.map +1 -0
  172. package/lib/typescript/src/scene/types.d.ts +71 -0
  173. package/lib/typescript/src/scene/types.d.ts.map +1 -0
  174. package/lib/typescript/src/sprites/sampleSpriteClip.d.ts +24 -0
  175. package/lib/typescript/src/sprites/sampleSpriteClip.d.ts.map +1 -0
  176. package/lib/typescript/src/sprites/spriteAnimationState.d.ts +45 -0
  177. package/lib/typescript/src/sprites/spriteAnimationState.d.ts.map +1 -0
  178. package/lib/typescript/src/testing.d.ts +28 -0
  179. package/lib/typescript/src/testing.d.ts.map +1 -0
  180. package/lib/typescript/src/viewport2d/index.d.ts +3 -0
  181. package/lib/typescript/src/viewport2d/index.d.ts.map +1 -0
  182. package/lib/typescript/src/viewport2d/math.d.ts +25 -0
  183. package/lib/typescript/src/viewport2d/math.d.ts.map +1 -0
  184. package/lib/typescript/src/viewport2d/types.d.ts +59 -0
  185. package/lib/typescript/src/viewport2d/types.d.ts.map +1 -0
  186. package/package.json +120 -0
  187. package/src/assets/defineAssets.ts +62 -0
  188. package/src/assets/errors.ts +64 -0
  189. package/src/assets/types.ts +164 -0
  190. package/src/assets/validation.ts +158 -0
  191. package/src/core/frameDriver.ts +31 -0
  192. package/src/core/input/createInputBuffer.ts +337 -0
  193. package/src/core/input/types.ts +67 -0
  194. package/src/core/session/createGameSession.ts +652 -0
  195. package/src/core/session/deepFreeze.ts +158 -0
  196. package/src/core/session/diagnostics.ts +35 -0
  197. package/src/core/session/types.ts +122 -0
  198. package/src/definition/defineGame.ts +94 -0
  199. package/src/definition/types.ts +67 -0
  200. package/src/geometry/types.ts +7 -0
  201. package/src/index.ts +84 -0
  202. package/src/react/GamePointerInput.tsx +478 -0
  203. package/src/react/GameView.tsx +317 -0
  204. package/src/react/alphaClock.ts +59 -0
  205. package/src/react/assets/createGameAssetStore.ts +459 -0
  206. package/src/react/assets/decodeSkiaImage.ts +64 -0
  207. package/src/react/assets/errors.ts +7 -0
  208. package/src/react/assets/useGameAssets.ts +171 -0
  209. package/src/react/bindAppLifecycle.ts +79 -0
  210. package/src/react/bindGameSession.ts +41 -0
  211. package/src/react/gestureLifecycle.ts +73 -0
  212. package/src/react/instrumentation.ts +54 -0
  213. package/src/react/pointerBinding.ts +226 -0
  214. package/src/react/pointerCoalescer.ts +234 -0
  215. package/src/react/pointerContainment.ts +23 -0
  216. package/src/react/sprites/GameSprite.tsx +192 -0
  217. package/src/react/sprites/GameWorld2D.tsx +46 -0
  218. package/src/react/sprites/Sprite.tsx +194 -0
  219. package/src/react/sprites/SpriteBatch.tsx +219 -0
  220. package/src/react/sprites/spriteBatchPolicy.ts +21 -0
  221. package/src/react/sprites/spriteTransform.ts +163 -0
  222. package/src/react/viewportBinding.ts +104 -0
  223. package/src/react.ts +37 -0
  224. package/src/scene/defineScene.ts +38 -0
  225. package/src/scene/types.ts +79 -0
  226. package/src/sprites/sampleSpriteClip.ts +51 -0
  227. package/src/sprites/spriteAnimationState.ts +176 -0
  228. package/src/testing.ts +61 -0
  229. package/src/viewport2d/index.ts +7 -0
  230. package/src/viewport2d/math.ts +134 -0
  231. package/src/viewport2d/types.ts +63 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to React Native GameKit will be documented in this file.
4
+
5
+ ## 0.1.0 - 2026-08-12
6
+
7
+ First public preview.
8
+
9
+ ### Added
10
+
11
+ - Fixed-step, headless game sessions with deterministic scene updates.
12
+ - Functional scene definitions, transitions, and immutable snapshots.
13
+ - Semantic button and pointer input with native gesture coalescing.
14
+ - Phone and tablet viewport resolution with `fit`, `fill`, and `extend-world` modes.
15
+ - Skia and Reanimated presentation through `GameView` and `GamePointerInput`.
16
+ - Typed local asset manifests, reference-counted loading, and React delivery.
17
+ - Sprite-sheet animation helpers, retained sprites, and Atlas-backed batching.
18
+ - A native-free root entry and deterministic testing utilities.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 React Native GameKit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # React Native GameKit
2
+
3
+ A headless-first 2D game toolkit for React Native and Expo, built for phones
4
+ and tablets.
5
+
6
+ > **0.1 preview:** React Native GameKit is usable for small 2D games and
7
+ > prototypes, but its API may change before 1.0.
8
+
9
+ ## What is included
10
+
11
+ - deterministic fixed-step game sessions;
12
+ - immutable functional scenes and scene transitions;
13
+ - semantic button and multi-touch-safe pointer input;
14
+ - phone, tablet, rotation, and split-view viewport mapping;
15
+ - React Native Skia rendering with Reanimated interpolation;
16
+ - typed local images, sprite sheets, animation clips, and asset loading;
17
+ - retained sprites and Atlas-backed sprite batching;
18
+ - a native-free root entry for headless tests.
19
+
20
+ ## Requirements
21
+
22
+ Version 0.1 targets the Expo SDK 57 compatibility set:
23
+
24
+ | Package | Supported version |
25
+ | --- | --- |
26
+ | React Native | `~0.86.2` |
27
+ | React | `^19.2.3` |
28
+ | Expo | `~57.0.10` |
29
+ | React Native Skia | `2.11.0` |
30
+ | Gesture Handler | `~3.1.0` |
31
+ | Reanimated | `4.5.3` |
32
+ | Worklets | `0.10.3` |
33
+
34
+ Expo Go is not required or supported. Use an Expo development build and
35
+ `expo prebuild`, or a bare React Native app configured with Expo Modules.
36
+
37
+ ## Installation
38
+
39
+ ```sh
40
+ npm install rn-gamekit
41
+ npx expo install expo-asset @shopify/react-native-skia react-native-gesture-handler react-native-reanimated react-native-worklets
42
+ npx expo prebuild
43
+ ```
44
+
45
+ Wrap the application with Gesture Handler's root view:
46
+
47
+ ```tsx
48
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
49
+
50
+ export default function App() {
51
+ return (
52
+ <GestureHandlerRootView style={{ flex: 1 }}>
53
+ {/* Your application */}
54
+ </GestureHandlerRootView>
55
+ );
56
+ }
57
+ ```
58
+
59
+ Native libraries are peer dependencies. The application owns them so there is
60
+ exactly one native copy, while GameKit releases declare the versions they were
61
+ validated against.
62
+
63
+ ## Define a game
64
+
65
+ ```ts
66
+ import {
67
+ createGameSession,
68
+ defineGame,
69
+ defineScene,
70
+ } from 'rn-gamekit';
71
+
72
+ const game = defineGame({
73
+ viewport: {
74
+ logicalSize: { width: 320, height: 480 },
75
+ mode: 'fit',
76
+ },
77
+ input: {
78
+ move: { type: 'pointer' },
79
+ },
80
+ scenes: {
81
+ play: defineScene({
82
+ actions: ['move'],
83
+ create: () => ({ x: 160, y: 240 }),
84
+ update: ({ state, input }) => {
85
+ const pointer = input.pointer('move');
86
+ return pointer.active && pointer.position !== undefined
87
+ ? { x: pointer.position.x, y: pointer.position.y }
88
+ : state;
89
+ },
90
+ snapshot: ({ state }) => state,
91
+ }),
92
+ },
93
+ initialScene: 'play',
94
+ });
95
+
96
+ const session = createGameSession(game);
97
+ session.start();
98
+ ```
99
+
100
+ Mount the session through the native entry point:
101
+
102
+ ```tsx
103
+ import {
104
+ GamePointerInput,
105
+ GameView,
106
+ } from 'rn-gamekit/react';
107
+
108
+ <GameView game={session} renderer={GameRenderer}>
109
+ <GamePointerInput game={session} action="move" />
110
+ </GameView>;
111
+ ```
112
+
113
+ `rn-gamekit` contains the headless definition, session, viewport,
114
+ asset-manifest, and animation APIs. `rn-gamekit/react` contains the
115
+ Skia renderer, native pointer adapter, asset loader, sprites, and sprite
116
+ batching. `rn-gamekit/testing` contains deterministic frame drivers
117
+ for Node tests.
118
+
119
+ See the [repository documentation](https://github.com/OrekuD/react-native-gamekit/tree/main/apps/docs/content/docs)
120
+ and [Expo playground](https://github.com/OrekuD/react-native-gamekit/tree/main/apps/playground)
121
+ for complete examples.
122
+
123
+ ## Current scope
124
+
125
+ The 0.1 release focuses on performant 2D foundations. Physics, tilemaps,
126
+ audio, haptics, game-level navigation, save data, and 3D rendering are not yet
127
+ part of the public package.
128
+
129
+ ## License
130
+
131
+ MIT
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Asset definition helpers (T7.2).
5
+ *
6
+ * `image(...)` and `spriteSheet(...)` build immutable descriptors;
7
+ * `defineAssets(...)` groups them into a deeply immutable typed manifest.
8
+ * Definition performs no I/O and allocates no native handle.
9
+ */
10
+ import { createDeepFreeze } from "../core/session/deepFreeze.js";
11
+ import { validateImageSource, validateManifest, validateSpriteSheet } from "./validation.js";
12
+ /** Declare a single full-image asset from a static module handle. */
13
+ export function image(source) {
14
+ validateImageSource(source);
15
+ return Object.freeze({
16
+ kind: 'image',
17
+ source
18
+ });
19
+ }
20
+
21
+ /**
22
+ * Declare a sprite-sheet asset: named source frames plus named animation
23
+ * clips. Frame and clip names are preserved as string literals; clip frame
24
+ * references are restricted to the declared frames.
25
+ */
26
+ export function spriteSheet(source, spec) {
27
+ validateSpriteSheet(source, spec);
28
+ const freezer = createDeepFreeze();
29
+ return freezer({
30
+ kind: 'sprite-sheet',
31
+ source,
32
+ frames: spec.frames,
33
+ animations: spec.animations
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Declare the game's asset manifest: a deeply immutable, fully typed group
39
+ * map. Group, asset, frame, and clip names are preserved as string literals
40
+ * and every descriptor is branded with the manifest type so lookups stay
41
+ * typed. Allocates no native resources and performs no I/O.
42
+ */
43
+ export function defineAssets(groups) {
44
+ validateManifest(groups);
45
+ const freezer = createDeepFreeze();
46
+ return freezer(groups);
47
+ }
48
+ //# sourceMappingURL=defineAssets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createDeepFreeze","validateImageSource","validateManifest","validateSpriteSheet","image","source","Object","freeze","kind","spriteSheet","spec","freezer","frames","animations","defineAssets","groups"],"sourceRoot":"../../../src","sources":["assets/defineAssets.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,gBAAgB,QAAQ,+BAA4B;AAC7D,SAASC,mBAAmB,EAAEC,gBAAgB,EAAEC,mBAAmB,QAAQ,iBAAc;AAUzF;AACA,OAAO,SAASC,KAAKA,CAACC,MAAc,EAAmB;EACrDJ,mBAAmB,CAACI,MAAM,CAAC;EAC3B,OAAOC,MAAM,CAACC,MAAM,CAAC;IAAEC,IAAI,EAAE,OAAO;IAAEH;EAAO,CAAC,CAAC;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASI,WAAWA,CAIzBJ,MAAc,EACdK,IAGC,EACuC;EACxCP,mBAAmB,CAACE,MAAM,EAAEK,IAAI,CAAC;EACjC,MAAMC,OAAO,GAAGX,gBAAgB,CAAC,CAAC;EAClC,OAAOW,OAAO,CAAC;IACbH,IAAI,EAAE,cAAc;IACpBH,MAAM;IACNO,MAAM,EAAEF,IAAI,CAACE,MAAM;IACnBC,UAAU,EAAEH,IAAI,CAACG;EACnB,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAC1BC,MAAe,EACa;EAC5Bb,gBAAgB,CAACa,MAAM,CAAC;EACxB,MAAMJ,OAAO,GAAGX,gBAAgB,CAAC,CAAC;EAClC,OAAOW,OAAO,CAACI,MAAM,CAAC;AACxB","ignoreList":[]}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Structured asset errors (T7.2).
5
+ *
6
+ * Every definition/loading failure carries a stable machine-readable code
7
+ * and the field path that caused it. Paths are documented in the public
8
+ * error reference; messages never embed machine-specific paths.
9
+ */
10
+
11
+ /** Stable error codes for asset definition and loading. */
12
+
13
+ /** A structured asset definition or loading failure. */
14
+ export class GameAssetError extends Error {
15
+ /** Stable machine-readable code. */
16
+
17
+ /** Field path within the manifest/descriptor that caused the failure. */
18
+
19
+ constructor(code, path, message) {
20
+ super(`${code}${path.length > 0 ? ` at ${path.join('.')}` : ''}: ${message}`);
21
+ this.name = 'GameAssetError';
22
+ this.code = code;
23
+ this.path = path;
24
+ }
25
+ }
26
+
27
+ /** Throw when a definition-time identifier is invalid. */
28
+ export function assertValidIdentifier(path, value) {
29
+ if (typeof value !== 'string' || value.length === 0) {
30
+ throw new GameAssetError('ASSET_INVALID_IDENTIFIER', path, 'identifiers must be non-empty strings');
31
+ }
32
+ // '/' is the diagnostic-id separator (group/key); reserving it keeps
33
+ // diagnostic ids unambiguous.
34
+ if (value.includes('/')) {
35
+ throw new GameAssetError('ASSET_INVALID_IDENTIFIER', path, `identifier ${JSON.stringify(value)} contains the reserved separator '/'`);
36
+ }
37
+ }
38
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["GameAssetError","Error","constructor","code","path","message","length","join","name","assertValidIdentifier","value","includes","JSON","stringify"],"sourceRoot":"../../../src","sources":["assets/errors.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAmBA;AACA,OAAO,MAAMA,cAAc,SAASC,KAAK,CAAC;EACxC;;EAEA;;EAGAC,WAAWA,CAACC,IAAwB,EAAEC,IAAuB,EAAEC,OAAe,EAAE;IAC9E,KAAK,CAAC,GAAGF,IAAI,GAAGC,IAAI,CAACE,MAAM,GAAG,CAAC,GAAG,OAAOF,IAAI,CAACG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAKF,OAAO,EAAE,CAAC;IAC7E,IAAI,CAACG,IAAI,GAAG,gBAAgB;IAC5B,IAAI,CAACL,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACC,IAAI,GAAGA,IAAI;EAClB;AACF;;AAEA;AACA,OAAO,SAASK,qBAAqBA,CACnCL,IAAuB,EACvBM,KAAa,EACP;EACN,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACJ,MAAM,KAAK,CAAC,EAAE;IACnD,MAAM,IAAIN,cAAc,CACtB,0BAA0B,EAC1BI,IAAI,EACJ,uCACF,CAAC;EACH;EACA;EACA;EACA,IAAIM,KAAK,CAACC,QAAQ,CAAC,GAAG,CAAC,EAAE;IACvB,MAAM,IAAIX,cAAc,CACtB,0BAA0B,EAC1BI,IAAI,EACJ,cAAcQ,IAAI,CAACC,SAAS,CAACH,KAAK,CAAC,sCACrC,CAAC;EACH;AACF","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["assets/types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Manifest validation (T7.2).
5
+ *
6
+ * Everything knowable before decoding is validated here with stable error
7
+ * codes and field paths. Rectangles are additionally validated against the
8
+ * decoded image dimensions after load (T7.4).
9
+ */
10
+ import { GameAssetError, assertValidIdentifier } from "./errors.js";
11
+ /** Validate one frame rectangle. */
12
+ export function validateFrameRect(path, name, rect) {
13
+ assertValidIdentifier(path, name);
14
+ const {
15
+ x,
16
+ y,
17
+ width,
18
+ height
19
+ } = rect;
20
+ const values = [x, y, width, height];
21
+ for (const value of values) {
22
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
23
+ throw new GameAssetError('ASSET_INVALID_FRAME_RECT', path, `frame ${JSON.stringify(name)} coordinates must be finite numbers`);
24
+ }
25
+ }
26
+ if (x < 0 || y < 0) {
27
+ throw new GameAssetError('ASSET_INVALID_FRAME_RECT', path, `frame ${JSON.stringify(name)} x/y must be non-negative`);
28
+ }
29
+ if (width <= 0 || height <= 0) {
30
+ throw new GameAssetError('ASSET_INVALID_FRAME_RECT', path, `frame ${JSON.stringify(name)} width/height must be greater than zero`);
31
+ }
32
+ }
33
+
34
+ /** Validate one animation clip against the sheet's declared frames. */
35
+ export function validateClip(path, name, clip, frames) {
36
+ assertValidIdentifier(path, name);
37
+ if (typeof clip.frames !== 'object' || clip.frames.length === 0) {
38
+ throw new GameAssetError('ASSET_EMPTY_CLIP', path, `clip ${JSON.stringify(name)} must reference at least one frame`);
39
+ }
40
+ for (const frame of clip.frames) {
41
+ if (typeof frame !== 'string' || !(frame in frames)) {
42
+ throw new GameAssetError('ASSET_UNKNOWN_FRAME', [...path, 'frames'], `clip ${JSON.stringify(name)} references unknown frame ${JSON.stringify(frame)}`);
43
+ }
44
+ }
45
+ const duration = clip.frameDurationMs;
46
+ if (typeof duration !== 'number' || !Number.isFinite(duration) || duration <= 0) {
47
+ throw new GameAssetError('ASSET_INVALID_DURATION', [...path, 'frameDurationMs'], `clip ${JSON.stringify(name)} duration must be finite and greater than zero`);
48
+ }
49
+ if (clip.mode !== 'loop' && clip.mode !== 'once') {
50
+ throw new GameAssetError('ASSET_INVALID_MODE', [...path, 'mode'], `clip ${JSON.stringify(name)} mode must be 'loop' or 'once'`);
51
+ }
52
+ }
53
+
54
+ /** Validate a full sprite-sheet descriptor. */
55
+ export function validateSpriteSheet(source, spec) {
56
+ if (typeof source !== 'number' || !Number.isInteger(source) || source < 0) {
57
+ throw new GameAssetError('ASSET_INVALID_SOURCE', [], 'sprite-sheet source must be a static module handle (number)');
58
+ }
59
+ for (const [name, rect] of Object.entries(spec.frames)) {
60
+ validateFrameRect(['frames', name], name, rect);
61
+ }
62
+ for (const [name, clip] of Object.entries(spec.animations)) {
63
+ validateClip(['animations', name], name, clip, spec.frames);
64
+ }
65
+ }
66
+
67
+ /** Validate an image descriptor's source. */
68
+ export function validateImageSource(source) {
69
+ if (typeof source !== 'number' || !Number.isInteger(source) || source < 0) {
70
+ throw new GameAssetError('ASSET_INVALID_SOURCE', [], 'image source must be a static module handle (number)');
71
+ }
72
+ }
73
+
74
+ /** Validate a full asset manifest. */
75
+ export function validateManifest(manifest) {
76
+ for (const [group, assets] of Object.entries(manifest)) {
77
+ const groupPath = [group];
78
+ assertValidIdentifier([], group);
79
+ if (typeof assets !== 'object' || assets === null) {
80
+ throw new GameAssetError('ASSET_INVALID_IDENTIFIER', groupPath, `group ${JSON.stringify(group)} must be an object of named assets`);
81
+ }
82
+ for (const [name, descriptor] of Object.entries(assets)) {
83
+ const path = [...groupPath, name];
84
+ assertValidIdentifier(groupPath, name);
85
+ if (descriptor === null || typeof descriptor !== 'object') {
86
+ throw new GameAssetError('ASSET_INVALID_IDENTIFIER', path, `asset ${JSON.stringify(name)} must be a descriptor`);
87
+ }
88
+ if (descriptor.kind === 'image') {
89
+ validateImageSource(descriptor.source);
90
+ } else if (descriptor.kind === 'sprite-sheet') {
91
+ const sheet = descriptor;
92
+ validateSpriteSheet(sheet.source, sheet);
93
+ } else {
94
+ throw new GameAssetError('ASSET_INVALID_IDENTIFIER', path, `asset ${JSON.stringify(name)} has unknown descriptor kind`);
95
+ }
96
+ }
97
+ }
98
+ }
99
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["GameAssetError","assertValidIdentifier","validateFrameRect","path","name","rect","x","y","width","height","values","value","Number","isFinite","JSON","stringify","validateClip","clip","frames","length","frame","duration","frameDurationMs","mode","validateSpriteSheet","source","spec","isInteger","Object","entries","animations","validateImageSource","validateManifest","manifest","group","assets","groupPath","descriptor","kind","sheet"],"sourceRoot":"../../../src","sources":["assets/validation.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ /** Opaque handle returned by an animation-frame driver. */
4
+
5
+ /** Minimal presentation clock used by the fixed-step runtime. */
6
+
7
+ /** Create the platform animation-frame driver used by live sessions. */
8
+ export function createAnimationFrameDriver() {
9
+ const host = globalThis;
10
+ const requestAnimationFrame = host.requestAnimationFrame;
11
+ const cancelAnimationFrame = host.cancelAnimationFrame;
12
+ if (!requestAnimationFrame || !cancelAnimationFrame) {
13
+ throw new Error('GameSession requires requestAnimationFrame on this platform');
14
+ }
15
+ return {
16
+ requestFrame: callback => requestAnimationFrame(callback),
17
+ cancelFrame: handle => cancelAnimationFrame(handle)
18
+ };
19
+ }
20
+ //# sourceMappingURL=frameDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createAnimationFrameDriver","host","globalThis","requestAnimationFrame","cancelAnimationFrame","Error","requestFrame","callback","cancelFrame","handle"],"sourceRoot":"../../../src","sources":["core/frameDriver.ts"],"mappings":";;AAAA;;AAGA;;AAaA;AACA,OAAO,SAASA,0BAA0BA,CAAA,EAAgB;EACxD,MAAMC,IAAI,GAAGC,UAAoD;EACjE,MAAMC,qBAAqB,GAAGF,IAAI,CAACE,qBAAqB;EACxD,MAAMC,oBAAoB,GAAGH,IAAI,CAACG,oBAAoB;EAEtD,IAAI,CAACD,qBAAqB,IAAI,CAACC,oBAAoB,EAAE;IACnD,MAAM,IAAIC,KAAK,CAAC,6DAA6D,CAAC;EAChF;EAEA,OAAO;IACLC,YAAY,EAAGC,QAAQ,IAAKJ,qBAAqB,CAACI,QAAQ,CAAC;IAC3DC,WAAW,EAAGC,MAAM,IAAKL,oBAAoB,CAACK,MAAM;EACtD,CAAC;AACH","ignoreList":[]}