@ankhorage/zora-game 0.3.0 → 0.4.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 (25) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +1 -1
  3. package/dist/ZORA_GAME_COMPONENT_META.d.ts +58 -0
  4. package/dist/ZORA_GAME_COMPONENT_META.d.ts.map +1 -1
  5. package/dist/ZORA_GAME_PLUGIN.d.ts +58 -0
  6. package/dist/ZORA_GAME_PLUGIN.d.ts.map +1 -1
  7. package/dist/ZORA_PLUGIN_METADATA.d.ts +58 -0
  8. package/dist/ZORA_PLUGIN_METADATA.d.ts.map +1 -1
  9. package/dist/features/game-presentation/adapters/inbound/Game.d.ts.map +1 -1
  10. package/dist/features/game-presentation/adapters/inbound/Game.js +8 -3
  11. package/dist/features/game-presentation/adapters/inbound/Game.js.map +1 -1
  12. package/dist/features/game-presentation/composition/createGameBindingContext.d.ts +4 -0
  13. package/dist/features/game-presentation/composition/createGameBindingContext.d.ts.map +1 -0
  14. package/dist/features/game-presentation/composition/createGameBindingContext.js +9 -0
  15. package/dist/features/game-presentation/composition/createGameBindingContext.js.map +1 -0
  16. package/dist/features/game-presentation/meta/gameEntityMeta.d.ts +58 -0
  17. package/dist/features/game-presentation/meta/gameEntityMeta.d.ts.map +1 -1
  18. package/dist/features/game-presentation/meta/gameEntityMeta.js +13 -0
  19. package/dist/features/game-presentation/meta/gameEntityMeta.js.map +1 -1
  20. package/package.json +3 -2
  21. package/src/ZORA_PLUGIN_METADATA.test.ts +9 -0
  22. package/src/features/game-presentation/adapters/inbound/Game.tsx +19 -11
  23. package/src/features/game-presentation/composition/createGameBindingContext.test.ts +47 -0
  24. package/src/features/game-presentation/composition/createGameBindingContext.ts +10 -0
  25. package/src/features/game-presentation/meta/gameEntityMeta.ts +13 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @ankhorage/zora-game
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - fd5e7c9: Expose each local Game session through the canonical Runtime binding context so ordinary ZORA props,
8
+ including positioned entity, text, progress, and health presentation, can bind to game session data.
9
+
3
10
  ## 0.3.0
4
11
 
5
12
  ### Minor Changes
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # @ankhorage/zora-game
5
5
 
6
- ![license: MIT](././paradox/badges/license.svg) ![npm: v0.3.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
6
+ ![license: MIT](././paradox/badges/license.svg) ![npm: v0.4.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
7
7
 
8
8
  Generic game presentation primitives for React Native and React Native Web apps built on ZORA.
9
9
 
@@ -135,6 +135,64 @@ export declare const ZORA_GAME_COMPONENT_META: {
135
135
  readonly zIndex: 0;
136
136
  };
137
137
  };
138
+ readonly bindings: {
139
+ readonly props: {
140
+ readonly x: {
141
+ readonly value: {
142
+ readonly type: "number";
143
+ };
144
+ readonly acceptsFallback: true;
145
+ };
146
+ readonly y: {
147
+ readonly value: {
148
+ readonly type: "number";
149
+ };
150
+ readonly acceptsFallback: true;
151
+ };
152
+ readonly width: {
153
+ readonly value: {
154
+ readonly type: "number";
155
+ };
156
+ readonly acceptsFallback: true;
157
+ };
158
+ readonly height: {
159
+ readonly value: {
160
+ readonly type: "number";
161
+ };
162
+ readonly acceptsFallback: true;
163
+ };
164
+ readonly opacity: {
165
+ readonly value: {
166
+ readonly type: "number";
167
+ };
168
+ readonly acceptsFallback: true;
169
+ };
170
+ readonly scale: {
171
+ readonly value: {
172
+ readonly type: "number";
173
+ };
174
+ readonly acceptsFallback: true;
175
+ };
176
+ readonly rotation: {
177
+ readonly value: {
178
+ readonly type: "number";
179
+ };
180
+ readonly acceptsFallback: true;
181
+ };
182
+ readonly zIndex: {
183
+ readonly value: {
184
+ readonly type: "number";
185
+ };
186
+ readonly acceptsFallback: true;
187
+ };
188
+ readonly hidden: {
189
+ readonly value: {
190
+ readonly type: "boolean";
191
+ };
192
+ readonly acceptsFallback: true;
193
+ };
194
+ };
195
+ };
138
196
  readonly props: {
139
197
  readonly x: {
140
198
  readonly type: "number";
@@ -1 +1 @@
1
- {"version":3,"file":"ZORA_GAME_COMPONENT_META.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_COMPONENT_META.ts"],"names":[],"mappings":"AAMA,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAM3B,CAAC"}
1
+ {"version":3,"file":"ZORA_GAME_COMPONENT_META.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_COMPONENT_META.ts"],"names":[],"mappings":"AAMA,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAM3B,CAAC"}
@@ -150,6 +150,64 @@ export declare const ZORA_GAME_PLUGIN: {
150
150
  readonly zIndex: 0;
151
151
  };
152
152
  };
153
+ readonly bindings: {
154
+ readonly props: {
155
+ readonly x: {
156
+ readonly value: {
157
+ readonly type: "number";
158
+ };
159
+ readonly acceptsFallback: true;
160
+ };
161
+ readonly y: {
162
+ readonly value: {
163
+ readonly type: "number";
164
+ };
165
+ readonly acceptsFallback: true;
166
+ };
167
+ readonly width: {
168
+ readonly value: {
169
+ readonly type: "number";
170
+ };
171
+ readonly acceptsFallback: true;
172
+ };
173
+ readonly height: {
174
+ readonly value: {
175
+ readonly type: "number";
176
+ };
177
+ readonly acceptsFallback: true;
178
+ };
179
+ readonly opacity: {
180
+ readonly value: {
181
+ readonly type: "number";
182
+ };
183
+ readonly acceptsFallback: true;
184
+ };
185
+ readonly scale: {
186
+ readonly value: {
187
+ readonly type: "number";
188
+ };
189
+ readonly acceptsFallback: true;
190
+ };
191
+ readonly rotation: {
192
+ readonly value: {
193
+ readonly type: "number";
194
+ };
195
+ readonly acceptsFallback: true;
196
+ };
197
+ readonly zIndex: {
198
+ readonly value: {
199
+ readonly type: "number";
200
+ };
201
+ readonly acceptsFallback: true;
202
+ };
203
+ readonly hidden: {
204
+ readonly value: {
205
+ readonly type: "boolean";
206
+ };
207
+ readonly acceptsFallback: true;
208
+ };
209
+ };
210
+ };
153
211
  readonly props: {
154
212
  readonly x: {
155
213
  readonly type: "number";
@@ -1 +1 @@
1
- {"version":3,"file":"ZORA_GAME_PLUGIN.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_PLUGIN.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oDAAoD,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,0DAA0D,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,yDAAyD,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,6DAA6D,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,2DAA2D,CAAC;AAGxF,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASnB,CAAC"}
1
+ {"version":3,"file":"ZORA_GAME_PLUGIN.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_PLUGIN.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oDAAoD,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,0DAA0D,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,yDAAyD,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,6DAA6D,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,2DAA2D,CAAC;AAGxF,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASnB,CAAC"}
@@ -138,6 +138,64 @@ export declare const ZORA_PLUGIN_METADATA: {
138
138
  readonly zIndex: 0;
139
139
  };
140
140
  };
141
+ readonly bindings: {
142
+ readonly props: {
143
+ readonly x: {
144
+ readonly value: {
145
+ readonly type: "number";
146
+ };
147
+ readonly acceptsFallback: true;
148
+ };
149
+ readonly y: {
150
+ readonly value: {
151
+ readonly type: "number";
152
+ };
153
+ readonly acceptsFallback: true;
154
+ };
155
+ readonly width: {
156
+ readonly value: {
157
+ readonly type: "number";
158
+ };
159
+ readonly acceptsFallback: true;
160
+ };
161
+ readonly height: {
162
+ readonly value: {
163
+ readonly type: "number";
164
+ };
165
+ readonly acceptsFallback: true;
166
+ };
167
+ readonly opacity: {
168
+ readonly value: {
169
+ readonly type: "number";
170
+ };
171
+ readonly acceptsFallback: true;
172
+ };
173
+ readonly scale: {
174
+ readonly value: {
175
+ readonly type: "number";
176
+ };
177
+ readonly acceptsFallback: true;
178
+ };
179
+ readonly rotation: {
180
+ readonly value: {
181
+ readonly type: "number";
182
+ };
183
+ readonly acceptsFallback: true;
184
+ };
185
+ readonly zIndex: {
186
+ readonly value: {
187
+ readonly type: "number";
188
+ };
189
+ readonly acceptsFallback: true;
190
+ };
191
+ readonly hidden: {
192
+ readonly value: {
193
+ readonly type: "boolean";
194
+ };
195
+ readonly acceptsFallback: true;
196
+ };
197
+ };
198
+ };
141
199
  readonly props: {
142
200
  readonly x: {
143
201
  readonly type: "number";
@@ -1 +1 @@
1
- {"version":3,"file":"ZORA_PLUGIN_METADATA.d.ts","sourceRoot":"","sources":["../src/ZORA_PLUGIN_METADATA.ts"],"names":[],"mappings":"AAIA,sFAAsF;AACtF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BM,CAAC"}
1
+ {"version":3,"file":"ZORA_PLUGIN_METADATA.d.ts","sourceRoot":"","sources":["../src/ZORA_PLUGIN_METADATA.ts"],"names":[],"mappings":"AAIA,sFAAsF;AACtF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Game.d.ts","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/Game.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAKpE,kGAAkG;AAClG,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,qBAkBpC"}
1
+ {"version":3,"file":"Game.d.ts","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/Game.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAMpE,kGAAkG;AAClG,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,qBAwBpC"}
@@ -1,16 +1,21 @@
1
+ import { RuntimeRendererConfigProvider } from '@ankhorage/runtime';
1
2
  import React from 'react';
3
+ import { createGameBindingContext } from '../../composition/createGameBindingContext';
2
4
  import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
3
5
  import { useGameRuntime } from '../../composition/useGameRuntime';
4
6
  import { GameField } from './GameField';
5
7
  /*** Bind one serializable game definition to a local transient session and presentation field. */
6
8
  export function Game(props) {
7
9
  const runtime = useGameRuntime(props);
10
+ const runtimeBindingConfig = React.useMemo(() => ({ bindingContext: createGameBindingContext(runtime.session) }), [runtime.session]);
8
11
  return (<GameRuntimeContext.Provider value={runtime}>
9
- <GameField {...(props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio })} {...(props.minHeight === undefined ? {} : { minHeight: props.minHeight })} {...(props.clip === undefined ? {} : { clip: props.clip })} {...(props.accessibilityLabel === undefined
12
+ <RuntimeRendererConfigProvider value={runtimeBindingConfig}>
13
+ <GameField {...(props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio })} {...(props.minHeight === undefined ? {} : { minHeight: props.minHeight })} {...(props.clip === undefined ? {} : { clip: props.clip })} {...(props.accessibilityLabel === undefined
10
14
  ? {}
11
15
  : { accessibilityLabel: props.accessibilityLabel })} {...(props.testID === undefined ? {} : { testID: props.testID })}>
12
- {props.children}
13
- </GameField>
16
+ {props.children}
17
+ </GameField>
18
+ </RuntimeRendererConfigProvider>
14
19
  </GameRuntimeContext.Provider>);
15
20
  }
16
21
  //# sourceMappingURL=Game.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Game.js","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/Game.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,kGAAkG;AAClG,MAAM,UAAU,IAAI,CAAC,KAAgB;IACnC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAEtC,OAAO,CACL,CAAC,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAC1C;MAAA,CAAC,SAAS,CACR,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAChF,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAC1E,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAC3D,IAAI,CAAC,KAAK,CAAC,kBAAkB,KAAK,SAAS;QACzC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,CACtD,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAEjE;QAAA,CAAC,KAAK,CAAC,QAAQ,CACjB;MAAA,EAAE,SAAS,CACb;IAAA,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAC/B,CAAC;AACJ,CAAC","sourcesContent":["import React from 'react';\n\nimport type { GameProps } from '../../../../types/gamePresentation';\nimport { GameRuntimeContext } from '../../composition/GameRuntimeContext';\nimport { useGameRuntime } from '../../composition/useGameRuntime';\nimport { GameField } from './GameField';\n\n/*** Bind one serializable game definition to a local transient session and presentation field. */\nexport function Game(props: GameProps) {\n const runtime = useGameRuntime(props);\n\n return (\n <GameRuntimeContext.Provider value={runtime}>\n <GameField\n {...(props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio })}\n {...(props.minHeight === undefined ? {} : { minHeight: props.minHeight })}\n {...(props.clip === undefined ? {} : { clip: props.clip })}\n {...(props.accessibilityLabel === undefined\n ? {}\n : { accessibilityLabel: props.accessibilityLabel })}\n {...(props.testID === undefined ? {} : { testID: props.testID })}\n >\n {props.children}\n </GameField>\n </GameRuntimeContext.Provider>\n );\n}\n"]}
1
+ {"version":3,"file":"Game.js","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/Game.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,kGAAkG;AAClG,MAAM,UAAU,IAAI,CAAC,KAAgB;IACnC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,oBAAoB,GAAG,KAAK,CAAC,OAAO,CACxC,GAAG,EAAE,CAAC,CAAC,EAAE,cAAc,EAAE,wBAAwB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EACrE,CAAC,OAAO,CAAC,OAAO,CAAC,CAClB,CAAC;IAEF,OAAO,CACL,CAAC,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAC1C;MAAA,CAAC,6BAA6B,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAAC,CACzD;QAAA,CAAC,SAAS,CACR,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAChF,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAC1E,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAC3D,IAAI,CAAC,KAAK,CAAC,kBAAkB,KAAK,SAAS;QACzC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,CACtD,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAEjE;UAAA,CAAC,KAAK,CAAC,QAAQ,CACjB;QAAA,EAAE,SAAS,CACb;MAAA,EAAE,6BAA6B,CACjC;IAAA,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAC/B,CAAC;AACJ,CAAC","sourcesContent":["import { RuntimeRendererConfigProvider } from '@ankhorage/runtime';\nimport React from 'react';\n\nimport type { GameProps } from '../../../../types/gamePresentation';\nimport { createGameBindingContext } from '../../composition/createGameBindingContext';\nimport { GameRuntimeContext } from '../../composition/GameRuntimeContext';\nimport { useGameRuntime } from '../../composition/useGameRuntime';\nimport { GameField } from './GameField';\n\n/*** Bind one serializable game definition to a local transient session and presentation field. */\nexport function Game(props: GameProps) {\n const runtime = useGameRuntime(props);\n const runtimeBindingConfig = React.useMemo(\n () => ({ bindingContext: createGameBindingContext(runtime.session) }),\n [runtime.session],\n );\n\n return (\n <GameRuntimeContext.Provider value={runtime}>\n <RuntimeRendererConfigProvider value={runtimeBindingConfig}>\n <GameField\n {...(props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio })}\n {...(props.minHeight === undefined ? {} : { minHeight: props.minHeight })}\n {...(props.clip === undefined ? {} : { clip: props.clip })}\n {...(props.accessibilityLabel === undefined\n ? {}\n : { accessibilityLabel: props.accessibilityLabel })}\n {...(props.testID === undefined ? {} : { testID: props.testID })}\n >\n {props.children}\n </GameField>\n </RuntimeRendererConfigProvider>\n </GameRuntimeContext.Provider>\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { GameSession } from '@ankhorage/game';
2
+ /*** Create the canonical Runtime context namespace for one local game session. */
3
+ export declare function createGameBindingContext(session: GameSession): Record<string, unknown>;
4
+ //# sourceMappingURL=createGameBindingContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createGameBindingContext.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/createGameBindingContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMtF"}
@@ -0,0 +1,9 @@
1
+ /*** Create the canonical Runtime context namespace for one local game session. */
2
+ export function createGameBindingContext(session) {
3
+ return {
4
+ game: {
5
+ session,
6
+ },
7
+ };
8
+ }
9
+ //# sourceMappingURL=createGameBindingContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createGameBindingContext.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/createGameBindingContext.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,OAAO;QACL,IAAI,EAAE;YACJ,OAAO;SACR;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { GameSession } from '@ankhorage/game';\n\n/*** Create the canonical Runtime context namespace for one local game session. */\nexport function createGameBindingContext(session: GameSession): Record<string, unknown> {\n return {\n game: {\n session,\n },\n };\n}\n"]}
@@ -16,6 +16,64 @@ export declare const gameEntityMeta: {
16
16
  readonly zIndex: 0;
17
17
  };
18
18
  };
19
+ readonly bindings: {
20
+ readonly props: {
21
+ readonly x: {
22
+ readonly value: {
23
+ readonly type: "number";
24
+ };
25
+ readonly acceptsFallback: true;
26
+ };
27
+ readonly y: {
28
+ readonly value: {
29
+ readonly type: "number";
30
+ };
31
+ readonly acceptsFallback: true;
32
+ };
33
+ readonly width: {
34
+ readonly value: {
35
+ readonly type: "number";
36
+ };
37
+ readonly acceptsFallback: true;
38
+ };
39
+ readonly height: {
40
+ readonly value: {
41
+ readonly type: "number";
42
+ };
43
+ readonly acceptsFallback: true;
44
+ };
45
+ readonly opacity: {
46
+ readonly value: {
47
+ readonly type: "number";
48
+ };
49
+ readonly acceptsFallback: true;
50
+ };
51
+ readonly scale: {
52
+ readonly value: {
53
+ readonly type: "number";
54
+ };
55
+ readonly acceptsFallback: true;
56
+ };
57
+ readonly rotation: {
58
+ readonly value: {
59
+ readonly type: "number";
60
+ };
61
+ readonly acceptsFallback: true;
62
+ };
63
+ readonly zIndex: {
64
+ readonly value: {
65
+ readonly type: "number";
66
+ };
67
+ readonly acceptsFallback: true;
68
+ };
69
+ readonly hidden: {
70
+ readonly value: {
71
+ readonly type: "boolean";
72
+ };
73
+ readonly acceptsFallback: true;
74
+ };
75
+ };
76
+ };
19
77
  readonly props: {
20
78
  readonly x: {
21
79
  readonly type: "number";
@@ -1 +1 @@
1
- {"version":3,"file":"gameEntityMeta.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameEntityMeta.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuFW,CAAC"}
1
+ {"version":3,"file":"gameEntityMeta.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameEntityMeta.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoGW,CAAC"}
@@ -9,6 +9,19 @@ export const gameEntityMeta = {
9
9
  label: 'Game entity',
10
10
  defaultProps: { x: 0, y: 0, opacity: 1, scale: 1, rotation: 0, zIndex: 0 },
11
11
  },
12
+ bindings: {
13
+ props: {
14
+ x: { value: { type: 'number' }, acceptsFallback: true },
15
+ y: { value: { type: 'number' }, acceptsFallback: true },
16
+ width: { value: { type: 'number' }, acceptsFallback: true },
17
+ height: { value: { type: 'number' }, acceptsFallback: true },
18
+ opacity: { value: { type: 'number' }, acceptsFallback: true },
19
+ scale: { value: { type: 'number' }, acceptsFallback: true },
20
+ rotation: { value: { type: 'number' }, acceptsFallback: true },
21
+ zIndex: { value: { type: 'number' }, acceptsFallback: true },
22
+ hidden: { value: { type: 'boolean' }, acceptsFallback: true },
23
+ },
24
+ },
12
25
  props: {
13
26
  x: {
14
27
  type: 'number',
@@ -1 +1 @@
1
- {"version":3,"file":"gameEntityMeta.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameEntityMeta.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,YAAY;IAClB,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,kFAAkF;IAC/F,kBAAkB,EAAE,IAAI;IACxB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;IAC3D,SAAS,EAAE;QACT,KAAK,EAAE,aAAa;QACpB,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;KAC3E;IACD,KAAK,EAAE;QACL,CAAC,EAAE;YACD,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,CAAC,EAAE;YACD,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,OAAO;YACd,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,QAAQ;YACf,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,YAAY;YACtB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,aAAa,EAAE;YACb,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,gBAAgB;YACvB,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC;YAC9C,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,kBAAkB,EAAE;YAClB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,eAAe;YACzB,KAAK,EAAE,qBAAqB;YAC5B,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;KACF;CACmC,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '@ankhorage/zora/metadata';\n\n/*** Describe one positioned generic game entity for ZORA authoring tools. */\nexport const gameEntityMeta = {\n name: 'GameEntity',\n category: 'component',\n description: 'Positions arbitrary visual content inside a GameField without owning game rules.',\n directManifestNode: true,\n allowedChildren: ['Badge', 'Icon', 'Image', 'Text', 'View'],\n blueprint: {\n label: 'Game entity',\n defaultProps: { x: 0, y: 0, opacity: 1, scale: 1, rotation: 0, zIndex: 0 },\n },\n props: {\n x: {\n type: 'number',\n category: 'Position',\n label: 'X (%)',\n default: 0,\n authoring: { authority: 'instance' },\n },\n y: {\n type: 'number',\n category: 'Position',\n label: 'Y (%)',\n default: 0,\n authoring: { authority: 'instance' },\n },\n width: {\n type: 'number',\n category: 'Size',\n label: 'Width',\n authoring: { authority: 'instance' },\n },\n height: {\n type: 'number',\n category: 'Size',\n label: 'Height',\n authoring: { authority: 'instance' },\n },\n opacity: {\n type: 'number',\n category: 'Appearance',\n label: 'Opacity',\n default: 1,\n authoring: { authority: 'instance' },\n },\n scale: {\n type: 'number',\n category: 'Transform',\n label: 'Scale',\n default: 1,\n authoring: { authority: 'instance' },\n },\n rotation: {\n type: 'number',\n category: 'Transform',\n label: 'Rotation',\n default: 0,\n authoring: { authority: 'instance' },\n },\n zIndex: {\n type: 'number',\n category: 'Position',\n label: 'Z index',\n default: 0,\n authoring: { authority: 'instance' },\n },\n hidden: {\n type: 'boolean',\n category: 'State',\n label: 'Hidden',\n default: false,\n authoring: { authority: 'instance' },\n },\n pointerEvents: {\n type: 'enum',\n category: 'Interaction',\n label: 'Pointer events',\n enum: ['auto', 'box-none', 'box-only', 'none'],\n default: 'auto',\n authoring: { authority: 'instance' },\n },\n accessibilityLabel: {\n type: 'string',\n category: 'Accessibility',\n label: 'Accessibility label',\n authoring: { authority: 'instance' },\n },\n },\n} as const satisfies ZoraComponentMeta;\n"]}
1
+ {"version":3,"file":"gameEntityMeta.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameEntityMeta.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ZoraComponentMeta } from '@ankhorage/zora/metadata';\n\n/*** Describe one positioned generic game entity for ZORA authoring tools. */\nexport const gameEntityMeta = {\n name: 'GameEntity',\n category: 'component',\n description: 'Positions arbitrary visual content inside a GameField without owning game rules.',\n directManifestNode: true,\n allowedChildren: ['Badge', 'Icon', 'Image', 'Text', 'View'],\n blueprint: {\n label: 'Game entity',\n defaultProps: { x: 0, y: 0, opacity: 1, scale: 1, rotation: 0, zIndex: 0 },\n },\n bindings: {\n props: {\n x: { value: { type: 'number' }, acceptsFallback: true },\n y: { value: { type: 'number' }, acceptsFallback: true },\n width: { value: { type: 'number' }, acceptsFallback: true },\n height: { value: { type: 'number' }, acceptsFallback: true },\n opacity: { value: { type: 'number' }, acceptsFallback: true },\n scale: { value: { type: 'number' }, acceptsFallback: true },\n rotation: { value: { type: 'number' }, acceptsFallback: true },\n zIndex: { value: { type: 'number' }, acceptsFallback: true },\n hidden: { value: { type: 'boolean' }, acceptsFallback: true },\n },\n },\n props: {\n x: {\n type: 'number',\n category: 'Position',\n label: 'X (%)',\n default: 0,\n authoring: { authority: 'instance' },\n },\n y: {\n type: 'number',\n category: 'Position',\n label: 'Y (%)',\n default: 0,\n authoring: { authority: 'instance' },\n },\n width: {\n type: 'number',\n category: 'Size',\n label: 'Width',\n authoring: { authority: 'instance' },\n },\n height: {\n type: 'number',\n category: 'Size',\n label: 'Height',\n authoring: { authority: 'instance' },\n },\n opacity: {\n type: 'number',\n category: 'Appearance',\n label: 'Opacity',\n default: 1,\n authoring: { authority: 'instance' },\n },\n scale: {\n type: 'number',\n category: 'Transform',\n label: 'Scale',\n default: 1,\n authoring: { authority: 'instance' },\n },\n rotation: {\n type: 'number',\n category: 'Transform',\n label: 'Rotation',\n default: 0,\n authoring: { authority: 'instance' },\n },\n zIndex: {\n type: 'number',\n category: 'Position',\n label: 'Z index',\n default: 0,\n authoring: { authority: 'instance' },\n },\n hidden: {\n type: 'boolean',\n category: 'State',\n label: 'Hidden',\n default: false,\n authoring: { authority: 'instance' },\n },\n pointerEvents: {\n type: 'enum',\n category: 'Interaction',\n label: 'Pointer events',\n enum: ['auto', 'box-none', 'box-only', 'none'],\n default: 'auto',\n authoring: { authority: 'instance' },\n },\n accessibilityLabel: {\n type: 'string',\n category: 'Accessibility',\n label: 'Accessibility label',\n authoring: { authority: 'instance' },\n },\n },\n} as const satisfies ZoraComponentMeta;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ankhorage/zora-game",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Generic game presentation primitives for React Native and React Native Web apps built on ZORA.",
6
6
  "homepage": "https://github.com/ankhorage/zora-game#readme",
@@ -93,6 +93,7 @@
93
93
  },
94
94
  "packageManager": "bun@1.4.2",
95
95
  "dependencies": {
96
- "@ankhorage/game": "^0.1.0"
96
+ "@ankhorage/game": "^0.1.0",
97
+ "@ankhorage/runtime": "^2.3.1"
97
98
  }
98
99
  }
@@ -41,6 +41,15 @@ describe('ZORA game plugin metadata', () => {
41
41
  expect(game.events?.output?.eventType).toBe('game.output');
42
42
  });
43
43
 
44
+ test('exposes GameEntity presentation props to canonical ZORA bindings', () => {
45
+ const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
46
+ const gameEntity = readComponentMeta(catalog.componentMeta.GameEntity, 'GameEntity');
47
+
48
+ expect(gameEntity.bindings?.props?.x?.value.type).toBe('number');
49
+ expect(gameEntity.bindings?.props?.y?.value.type).toBe('number');
50
+ expect(gameEntity.bindings?.props?.hidden?.value.type).toBe('boolean');
51
+ });
52
+
44
53
  test('keeps the generic presentation vocabulary free of product-specific concepts', () => {
45
54
  const serialized = JSON.stringify(ZORA_PLUGIN_METADATA).toLowerCase();
46
55
 
@@ -1,6 +1,8 @@
1
+ import { RuntimeRendererConfigProvider } from '@ankhorage/runtime';
1
2
  import React from 'react';
2
3
 
3
4
  import type { GameProps } from '../../../../types/gamePresentation';
5
+ import { createGameBindingContext } from '../../composition/createGameBindingContext';
4
6
  import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
5
7
  import { useGameRuntime } from '../../composition/useGameRuntime';
6
8
  import { GameField } from './GameField';
@@ -8,20 +10,26 @@ import { GameField } from './GameField';
8
10
  /*** Bind one serializable game definition to a local transient session and presentation field. */
9
11
  export function Game(props: GameProps) {
10
12
  const runtime = useGameRuntime(props);
13
+ const runtimeBindingConfig = React.useMemo(
14
+ () => ({ bindingContext: createGameBindingContext(runtime.session) }),
15
+ [runtime.session],
16
+ );
11
17
 
12
18
  return (
13
19
  <GameRuntimeContext.Provider value={runtime}>
14
- <GameField
15
- {...(props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio })}
16
- {...(props.minHeight === undefined ? {} : { minHeight: props.minHeight })}
17
- {...(props.clip === undefined ? {} : { clip: props.clip })}
18
- {...(props.accessibilityLabel === undefined
19
- ? {}
20
- : { accessibilityLabel: props.accessibilityLabel })}
21
- {...(props.testID === undefined ? {} : { testID: props.testID })}
22
- >
23
- {props.children}
24
- </GameField>
20
+ <RuntimeRendererConfigProvider value={runtimeBindingConfig}>
21
+ <GameField
22
+ {...(props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio })}
23
+ {...(props.minHeight === undefined ? {} : { minHeight: props.minHeight })}
24
+ {...(props.clip === undefined ? {} : { clip: props.clip })}
25
+ {...(props.accessibilityLabel === undefined
26
+ ? {}
27
+ : { accessibilityLabel: props.accessibilityLabel })}
28
+ {...(props.testID === undefined ? {} : { testID: props.testID })}
29
+ >
30
+ {props.children}
31
+ </GameField>
32
+ </RuntimeRendererConfigProvider>
25
33
  </GameRuntimeContext.Provider>
26
34
  );
27
35
  }
@@ -0,0 +1,47 @@
1
+ import type { GameSession } from '@ankhorage/game';
2
+ import { resolveRuntimeBindingValueSync } from '@ankhorage/runtime/bindings';
3
+ import { describe, expect, test } from 'bun:test';
4
+
5
+ import { createGameBindingContext } from './createGameBindingContext';
6
+
7
+ const session: GameSession = {
8
+ definitionId: 'binding-demo',
9
+ stageId: 'main',
10
+ phase: 'playing',
11
+ state: { health: 80, progress: 0.5 },
12
+ entities: {
13
+ player: {
14
+ id: 'player',
15
+ templateId: 'actor',
16
+ state: { x: 42, y: 73, label: 'Player' },
17
+ },
18
+ },
19
+ scheduled: [],
20
+ elapsedMs: 120,
21
+ sequence: 4,
22
+ };
23
+
24
+ describe('createGameBindingContext', () => {
25
+ test('resolves ordinary Runtime context bindings from the local Game session', () => {
26
+ const context = createGameBindingContext(session);
27
+
28
+ expect(
29
+ resolveRuntimeBindingValueSync(
30
+ { source: { kind: 'context', path: 'game.session.entities.player.state.x' } },
31
+ { context },
32
+ ),
33
+ ).toBe(42);
34
+ expect(
35
+ resolveRuntimeBindingValueSync(
36
+ { source: { kind: 'context', path: 'game.session.state.health' } },
37
+ { context },
38
+ ),
39
+ ).toBe(80);
40
+ });
41
+
42
+ test('owns only the local game namespace', () => {
43
+ expect(createGameBindingContext(session)).toEqual({
44
+ game: { session },
45
+ });
46
+ });
47
+ });
@@ -0,0 +1,10 @@
1
+ import type { GameSession } from '@ankhorage/game';
2
+
3
+ /*** Create the canonical Runtime context namespace for one local game session. */
4
+ export function createGameBindingContext(session: GameSession): Record<string, unknown> {
5
+ return {
6
+ game: {
7
+ session,
8
+ },
9
+ };
10
+ }
@@ -11,6 +11,19 @@ export const gameEntityMeta = {
11
11
  label: 'Game entity',
12
12
  defaultProps: { x: 0, y: 0, opacity: 1, scale: 1, rotation: 0, zIndex: 0 },
13
13
  },
14
+ bindings: {
15
+ props: {
16
+ x: { value: { type: 'number' }, acceptsFallback: true },
17
+ y: { value: { type: 'number' }, acceptsFallback: true },
18
+ width: { value: { type: 'number' }, acceptsFallback: true },
19
+ height: { value: { type: 'number' }, acceptsFallback: true },
20
+ opacity: { value: { type: 'number' }, acceptsFallback: true },
21
+ scale: { value: { type: 'number' }, acceptsFallback: true },
22
+ rotation: { value: { type: 'number' }, acceptsFallback: true },
23
+ zIndex: { value: { type: 'number' }, acceptsFallback: true },
24
+ hidden: { value: { type: 'boolean' }, acceptsFallback: true },
25
+ },
26
+ },
14
27
  props: {
15
28
  x: {
16
29
  type: 'number',