@seriousgaming/sdk-tools 0.0.0-stage → 1.0.0-alpha.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 (391) hide show
  1. package/LICENSE +93 -0
  2. package/README.md +36 -2
  3. package/dist/bundling/logic-exports.d.ts +34 -0
  4. package/dist/bundling/node-builtins.d.ts +21 -0
  5. package/dist/bundling/transpiler.d.ts +7 -0
  6. package/dist/cli.js +27368 -0
  7. package/dist/client/dev-server.d.ts +59 -0
  8. package/dist/client/index.d.ts +28 -0
  9. package/dist/client/stub-services.d.ts +32 -0
  10. package/dist/client/test-session.d.ts +195 -0
  11. package/dist/client.js +16884 -0
  12. package/dist/core/asset-reference-translator.d.ts +46 -0
  13. package/dist/core/clock.d.ts +57 -0
  14. package/dist/core/faults.d.ts +65 -0
  15. package/dist/core/game-settings.d.ts +65 -0
  16. package/dist/core/history.d.ts +89 -0
  17. package/dist/core/listen-with-fallback.d.ts +30 -0
  18. package/dist/core/mutation-queue.d.ts +61 -0
  19. package/dist/core/package-scenario.d.ts +89 -0
  20. package/dist/core/participant-registry.d.ts +109 -0
  21. package/dist/core/pending-changes.d.ts +14 -0
  22. package/dist/core/protocol.d.ts +83 -0
  23. package/dist/core/scenario-drafts.d.ts +32 -0
  24. package/dist/core/session-endpoints.d.ts +108 -0
  25. package/dist/core/session-gates.d.ts +75 -0
  26. package/dist/core/session-host.d.ts +94 -0
  27. package/dist/core/session-refusals.d.ts +56 -0
  28. package/dist/core/session-rewind.d.ts +32 -0
  29. package/dist/core/session-roster.d.ts +128 -0
  30. package/dist/core/session-surfaces.d.ts +32 -0
  31. package/dist/core/session-ticks.d.ts +18 -0
  32. package/dist/core/session-timers.d.ts +84 -0
  33. package/dist/core/session-writes.d.ts +40 -0
  34. package/dist/core/session.d.ts +385 -0
  35. package/dist/core/settings-locks.d.ts +22 -0
  36. package/dist/core/team-names.d.ts +52 -0
  37. package/dist/core/team-state-store.d.ts +209 -0
  38. package/dist/core/tick-timer.d.ts +75 -0
  39. package/dist/dev/blob-links.d.ts +10 -0
  40. package/dist/dev/console/assets/index-DgFglsnA.js +204 -0
  41. package/dist/dev/console/index.html +12 -0
  42. package/dist/dev/console-path.d.ts +19 -0
  43. package/dist/dev/lockfile.d.ts +124 -0
  44. package/dist/dev/package-watcher.d.ts +21 -0
  45. package/dist/dev/routes.d.ts +67 -0
  46. package/dist/dev/shell.d.ts +260 -0
  47. package/dist/dev/surfaces.d.ts +41 -0
  48. package/dist/dev/tools-identity.d.ts +23 -0
  49. package/dist/dev/view/batch.d.ts +172 -0
  50. package/dist/dev/view/commands.d.ts +75 -0
  51. package/dist/dev/view/route.d.ts +58 -0
  52. package/dist/dev/view/view.d.ts +78 -0
  53. package/dist/dev/view/viewer.d.ts +32 -0
  54. package/dist/discovery/config.d.ts +9 -0
  55. package/dist/discovery/manifest-paths.d.ts +21 -0
  56. package/dist/discovery/removed-fields.d.ts +90 -0
  57. package/dist/docs/api/deck.md +386 -0
  58. package/dist/docs/api/index.md +67 -0
  59. package/dist/docs/api/sdk-commands.md +286 -0
  60. package/dist/docs/api/sdk-e2e.md +433 -0
  61. package/dist/docs/api/sdk-projection.md +207 -0
  62. package/dist/docs/api/sdk-testing.md +214 -0
  63. package/dist/docs/api/sdk-tools-client.md +560 -0
  64. package/dist/docs/api/sdk-ui-testing.md +231 -0
  65. package/dist/docs/api/sdk-ui.md +1269 -0
  66. package/dist/docs/api/sdk.md +2140 -0
  67. package/dist/docs/changelog-0.x.md +1156 -0
  68. package/dist/docs/changelog.md +236 -0
  69. package/dist/docs/cli-and-dev-server.md +217 -0
  70. package/dist/docs/cli-error-codes.md +154 -0
  71. package/dist/docs/cli-reference.md +2488 -0
  72. package/dist/docs/cli-simulation-testing.md +222 -0
  73. package/dist/docs/concepts/index.md +46 -0
  74. package/dist/docs/concepts/terminology.md +322 -0
  75. package/dist/docs/environment-variables.md +102 -0
  76. package/dist/docs/getting-started.md +145 -0
  77. package/dist/docs/guides/ai-facilitation.md +220 -0
  78. package/dist/docs/guides/capabilities.md +460 -0
  79. package/dist/docs/guides/endpoints.md +335 -0
  80. package/dist/docs/guides/engine-testing.md +477 -0
  81. package/dist/docs/guides/engine.md +527 -0
  82. package/dist/docs/guides/file-handling.md +405 -0
  83. package/dist/docs/guides/games.md +176 -0
  84. package/dist/docs/guides/global-settings.md +94 -0
  85. package/dist/docs/guides/guide.md +123 -0
  86. package/dist/docs/guides/hooks.md +183 -0
  87. package/dist/docs/guides/index.md +51 -0
  88. package/dist/docs/guides/internationalization.md +288 -0
  89. package/dist/docs/guides/llm-integration.md +635 -0
  90. package/dist/docs/guides/multi-team-games.md +586 -0
  91. package/dist/docs/guides/patterns.md +391 -0
  92. package/dist/docs/guides/presentation.md +196 -0
  93. package/dist/docs/guides/production-constraints.md +130 -0
  94. package/dist/docs/guides/scenario-editor.md +143 -0
  95. package/dist/docs/guides/scenarios.md +515 -0
  96. package/dist/docs/guides/session.md +972 -0
  97. package/dist/docs/guides/settings.md +458 -0
  98. package/dist/docs/guides/setup.md +193 -0
  99. package/dist/docs/guides/speech-generation.md +233 -0
  100. package/dist/docs/guides/starter-game.md +164 -0
  101. package/dist/docs/guides/testing.md +575 -0
  102. package/dist/docs/guides/tick-controller.md +569 -0
  103. package/dist/docs/guides/type-safety.md +516 -0
  104. package/dist/docs/guides/ui.md +1389 -0
  105. package/dist/docs/guides/upgrading.md +636 -0
  106. package/dist/docs/guides/validators.md +217 -0
  107. package/dist/docs/guides/waiting-room.md +244 -0
  108. package/dist/docs/index.md +41 -0
  109. package/dist/docs/recipes/act-on-the-session-from-an-endpoint.md +95 -0
  110. package/dist/docs/recipes/adapt-a-game-for-walkthroughs.md +133 -0
  111. package/dist/docs/recipes/adapt-ui-for-observers.md +74 -0
  112. package/dist/docs/recipes/call-endpoint-from-ui.md +109 -0
  113. package/dist/docs/recipes/check-a-package-from-a-script.md +117 -0
  114. package/dist/docs/recipes/create-capability.md +66 -0
  115. package/dist/docs/recipes/create-endpoint.md +127 -0
  116. package/dist/docs/recipes/create-engine.md +111 -0
  117. package/dist/docs/recipes/create-game.md +70 -0
  118. package/dist/docs/recipes/create-guide.md +75 -0
  119. package/dist/docs/recipes/create-hook.md +80 -0
  120. package/dist/docs/recipes/create-presentation.md +142 -0
  121. package/dist/docs/recipes/create-scenario-editor.md +102 -0
  122. package/dist/docs/recipes/create-scenario.md +98 -0
  123. package/dist/docs/recipes/create-session-ui.md +116 -0
  124. package/dist/docs/recipes/create-settings.md +88 -0
  125. package/dist/docs/recipes/create-setup.md +115 -0
  126. package/dist/docs/recipes/create-tick-controller.md +65 -0
  127. package/dist/docs/recipes/create-user-interface.md +96 -0
  128. package/dist/docs/recipes/create-validator.md +67 -0
  129. package/dist/docs/recipes/create-waiting-room-ui.md +109 -0
  130. package/dist/docs/recipes/declare-api-uses.md +67 -0
  131. package/dist/docs/recipes/design-state-for-concurrent-writes.md +96 -0
  132. package/dist/docs/recipes/distribute-package.md +80 -0
  133. package/dist/docs/recipes/e2e-testing.md +116 -0
  134. package/dist/docs/recipes/end-game-on-condition.md +154 -0
  135. package/dist/docs/recipes/fix-duplicate-packages.md +101 -0
  136. package/dist/docs/recipes/index.md +86 -0
  137. package/dist/docs/recipes/make-an-endpoint-external.md +101 -0
  138. package/dist/docs/recipes/negotiate-across-teams.md +164 -0
  139. package/dist/docs/recipes/observe-other-teams-state.md +119 -0
  140. package/dist/docs/recipes/publish-a-package.md +139 -0
  141. package/dist/docs/recipes/remember-a-viewers-choice.md +55 -0
  142. package/dist/docs/recipes/review-a-past-day.md +73 -0
  143. package/dist/docs/recipes/share-assets-across-scenarios.md +120 -0
  144. package/dist/docs/recipes/share-logic-between-engine-and-ui.md +130 -0
  145. package/dist/docs/recipes/show-all-teams-participants.md +109 -0
  146. package/dist/docs/recipes/start-from-an-empty-package.md +169 -0
  147. package/dist/docs/recipes/take-a-file-in-an-endpoint.md +82 -0
  148. package/dist/docs/recipes/test-a-multi-role-game.md +51 -0
  149. package/dist/docs/recipes/test-user-interface.md +95 -0
  150. package/dist/docs/recipes/test-with-engine.md +115 -0
  151. package/dist/docs/recipes/upload-and-display-files.md +148 -0
  152. package/dist/docs/recipes/use-request-play.md +65 -0
  153. package/dist/docs/recipes/use-request-tick.md +75 -0
  154. package/dist/docs/troubleshooting.md +816 -0
  155. package/dist/execution/blob-inputs.d.ts +57 -0
  156. package/dist/execution/bundle-reload.d.ts +42 -0
  157. package/dist/execution/config-resolver.d.ts +127 -0
  158. package/dist/execution/configuration-builder.d.ts +66 -0
  159. package/dist/execution/context-composition.d.ts +161 -0
  160. package/dist/execution/endpoint-actions.d.ts +9 -0
  161. package/dist/execution/endpoint-payloads.d.ts +32 -0
  162. package/dist/execution/endpoint-runner.d.ts +129 -0
  163. package/dist/execution/engine-state.d.ts +40 -0
  164. package/dist/execution/executor-callbacks.d.ts +56 -0
  165. package/dist/execution/executor.d.ts +436 -0
  166. package/dist/execution/gates.d.ts +45 -0
  167. package/dist/execution/hook-chain.d.ts +25 -0
  168. package/dist/execution/logic-calls.d.ts +190 -0
  169. package/dist/execution/logic-failure.d.ts +84 -0
  170. package/dist/execution/logic-loader.d.ts +54 -0
  171. package/dist/execution/logic-result.d.ts +76 -0
  172. package/dist/execution/tick-controller-call.d.ts +32 -0
  173. package/dist/execution/types.d.ts +48 -0
  174. package/dist/generation/ts-type.d.ts +39 -0
  175. package/dist/guide/locale.d.ts +12 -0
  176. package/dist/guide/video-registry.d.ts +42 -0
  177. package/dist/help-examples.d.ts +125 -0
  178. package/dist/host/adapter.d.ts +67 -0
  179. package/dist/host/host-channel.d.ts +222 -0
  180. package/dist/host/index.d.ts +20 -0
  181. package/dist/host/protocol.d.ts +783 -0
  182. package/dist/host/surfaces.d.ts +42 -0
  183. package/dist/host/theme.d.ts +55 -0
  184. package/dist/host.js +583 -0
  185. package/dist/prompts/index.d.ts +7 -0
  186. package/dist/prompts/schema-builder.d.ts +29 -0
  187. package/dist/prompts/types.d.ts +108 -0
  188. package/dist/prompts/validators.d.ts +32 -0
  189. package/dist/runtime/capability-scope.d.ts +6 -0
  190. package/dist/runtime/context-merge.d.ts +29 -0
  191. package/dist/runtime/context-projection.d.ts +41 -0
  192. package/dist/runtime/guarded-callbacks.d.ts +15 -0
  193. package/dist/runtime/index.d.ts +27 -0
  194. package/dist/runtime/manifest-version.d.ts +55 -0
  195. package/dist/runtime/tick-validation.d.ts +25 -0
  196. package/dist/runtime.js +346 -0
  197. package/dist/schema.json +1546 -0
  198. package/dist/server/vite-plugin.d.ts +46 -0
  199. package/dist/services/tts/client.d.ts +51 -0
  200. package/dist/services/tts/elevenlabs.d.ts +24 -0
  201. package/dist/services/tts/types.d.ts +44 -0
  202. package/dist/storage/asset-resolver.d.ts +49 -0
  203. package/dist/storage/blob-store.d.ts +41 -0
  204. package/dist/templates/endpoint/logic.test.ts.liquid +61 -0
  205. package/dist/templates/endpoint/logic.ts.liquid +25 -0
  206. package/dist/templates/engine/init.json.liquid +7 -0
  207. package/dist/templates/engine/logic-aggregate.test.ts.liquid +90 -0
  208. package/dist/templates/engine/logic-aggregate.ts.liquid +46 -0
  209. package/dist/templates/engine/logic.test.ts.liquid +61 -0
  210. package/dist/templates/engine/logic.ts.liquid +32 -0
  211. package/dist/templates/engine/run.json.liquid +7 -0
  212. package/dist/templates/guide/01-at-a-glance.md.liquid +19 -0
  213. package/dist/templates/guide/02-preparation.md.liquid +18 -0
  214. package/dist/templates/guide/03-running-the-session.md.liquid +37 -0
  215. package/dist/templates/hook/logic.test.ts.liquid +46 -0
  216. package/dist/templates/hook/logic.ts.liquid +12 -0
  217. package/dist/templates/package/CLAUDE.md.template +338 -0
  218. package/dist/templates/package/DESIGN.md.liquid +144 -0
  219. package/dist/templates/package/README.md.liquid +143 -0
  220. package/dist/templates/package/claude/rules/workflow-create-capability.md +26 -0
  221. package/dist/templates/package/claude/rules/workflow-create-endpoint.md +35 -0
  222. package/dist/templates/package/claude/rules/workflow-create-engine.md +35 -0
  223. package/dist/templates/package/claude/rules/workflow-create-guide.md +40 -0
  224. package/dist/templates/package/claude/rules/workflow-create-presentation.md +37 -0
  225. package/dist/templates/package/claude/rules/workflow-create-user-interface.md +31 -0
  226. package/dist/templates/package/claude/rules/workflow-publish-package.md +54 -0
  227. package/dist/templates/package/claude/rules/workflow-test-engine-or-ui.md +30 -0
  228. package/dist/templates/package/claude/rules/workflow-update-sdk-version.md +43 -0
  229. package/dist/templates/package/claude/settings.json.template +16 -0
  230. package/dist/templates/package/gitignore.template +15 -0
  231. package/dist/templates/package/global-setup.ts.template +21 -0
  232. package/dist/templates/package/globals.d.ts.template +2 -0
  233. package/dist/templates/package/oxfmtrc.json.template +14 -0
  234. package/dist/templates/package/oxlintrc.json.template +238 -0
  235. package/dist/templates/package/package.json.liquid +65 -0
  236. package/dist/templates/package/playwright.config.ts.liquid +19 -0
  237. package/dist/templates/package/pnpm-workspace.yaml.template +27 -0
  238. package/dist/templates/package/test-setup.ts.liquid +7 -0
  239. package/dist/templates/package/tsconfig.json.liquid +15 -0
  240. package/dist/templates/package/vite.config.ts.liquid +19 -0
  241. package/dist/templates/package/vitest.config.ts.liquid +25 -0
  242. package/dist/templates/package/vitest.engine.config.ts.liquid +12 -0
  243. package/dist/templates/presentation/index.html.liquid +20 -0
  244. package/dist/templates/presentation/src/App.tsx.liquid +49 -0
  245. package/dist/templates/presentation/src/Slides.tsx.liquid +81 -0
  246. package/dist/templates/presentation/src/i18n.ts.liquid +54 -0
  247. package/dist/templates/presentation/src/main.tsx.liquid +14 -0
  248. package/dist/templates/scenario_editor/src/App.test.tsx.liquid +30 -0
  249. package/dist/templates/scenario_editor/src/App.tsx.liquid +95 -0
  250. package/dist/templates/scenario_editor/src/i18n.ts.liquid +44 -0
  251. package/dist/templates/session/src/App.test.tsx.liquid +60 -0
  252. package/dist/templates/session/src/App.tsx.liquid +128 -0
  253. package/dist/templates/session/src/i18n.ts.liquid +53 -0
  254. package/dist/templates/session/src/main.tsx.liquid +48 -0
  255. package/dist/templates/session/src/theme.ts.liquid +46 -0
  256. package/dist/templates/settings-editor/index.html.liquid +12 -0
  257. package/dist/templates/settings-editor/src/main.tsx.liquid +48 -0
  258. package/dist/templates/settings-editor/src/theme.ts.liquid +24 -0
  259. package/dist/templates/setup/src/App.test.tsx.liquid +39 -0
  260. package/dist/templates/setup/src/App.tsx.liquid +102 -0
  261. package/dist/templates/setup/src/i18n.ts.liquid +47 -0
  262. package/dist/templates/starter-game/capabilities/briefing/capability.sdk.json +18 -0
  263. package/dist/templates/starter-game/capabilities/plan/capability.sdk.json +17 -0
  264. package/dist/templates/starter-game/capabilities/results/capability.sdk.json +61 -0
  265. package/dist/templates/starter-game/capabilities/roles/capability.sdk.json +17 -0
  266. package/dist/templates/starter-game/capabilities/weather/capability.sdk.json +23 -0
  267. package/dist/templates/starter-game/engine/defaults.ts +81 -0
  268. package/dist/templates/starter-game/engine/engine.sdk.json +12 -0
  269. package/dist/templates/starter-game/engine/logic.test.ts +221 -0
  270. package/dist/templates/starter-game/engine/logic.ts +149 -0
  271. package/dist/templates/starter-game/engine/test-helpers.ts +74 -0
  272. package/dist/templates/starter-game/engine/types.ts +139 -0
  273. package/dist/templates/starter-game/guide/content/en/01-at-a-glance.md +51 -0
  274. package/dist/templates/starter-game/guide/content/en/02-preparation.md +35 -0
  275. package/dist/templates/starter-game/guide/content/en/03-running-the-day.md +58 -0
  276. package/dist/templates/starter-game/guide/guide.sdk.json +10 -0
  277. package/dist/templates/starter-game/guide/guide.test.ts +108 -0
  278. package/dist/templates/starter-game/hooks/assignproducts/defaults.ts +37 -0
  279. package/dist/templates/starter-game/hooks/assignproducts/hook.sdk.json +13 -0
  280. package/dist/templates/starter-game/hooks/assignproducts/logic/logic.test.ts +77 -0
  281. package/dist/templates/starter-game/hooks/assignproducts/logic/logic.ts +47 -0
  282. package/dist/templates/starter-game/hooks/assignproducts/types.ts +55 -0
  283. package/dist/templates/starter-game/package.json +68 -0
  284. package/dist/templates/starter-game/playwright.config.ts +19 -0
  285. package/dist/templates/starter-game/scenarios/heatwave/scenario.sdk.json +20 -0
  286. package/dist/templates/starter-game/scenarios/ordinary_week/scenario.sdk.json +12 -0
  287. package/dist/templates/starter-game/seriousgaming.sdk.json +23 -0
  288. package/dist/templates/starter-game/session/defaults.ts +80 -0
  289. package/dist/templates/starter-game/session/index.html +12 -0
  290. package/dist/templates/starter-game/session/session.sdk.json +11 -0
  291. package/dist/templates/starter-game/session/src/App.test.tsx +307 -0
  292. package/dist/templates/starter-game/session/src/App.tsx +309 -0
  293. package/dist/templates/starter-game/session/src/Section.tsx +37 -0
  294. package/dist/templates/starter-game/session/src/TeamDoor.tsx +96 -0
  295. package/dist/templates/starter-game/session/src/format.ts +8 -0
  296. package/dist/templates/starter-game/session/src/i18n.ts +51 -0
  297. package/dist/templates/starter-game/session/src/main.tsx +48 -0
  298. package/dist/templates/starter-game/session/src/theme.ts +45 -0
  299. package/dist/templates/starter-game/session/types.ts +135 -0
  300. package/dist/templates/starter-game/settings/engine/settings.sdk.json +50 -0
  301. package/dist/templates/starter-game/settings/menu/settings.sdk.json +78 -0
  302. package/dist/templates/starter-game/settings/session/settings.sdk.json +23 -0
  303. package/dist/templates/starter-game/settings/ui/settings.sdk.json +25 -0
  304. package/dist/templates/starter-game/test-setup.ts +7 -0
  305. package/dist/templates/starter-game/testing/e2e/game.spec.ts +139 -0
  306. package/dist/templates/starter-game/testing/e2e/global-setup.ts +21 -0
  307. package/dist/templates/starter-game/testing/engine/game.engine.test.ts +171 -0
  308. package/dist/templates/starter-game/tsconfig.json +19 -0
  309. package/dist/templates/starter-game/ui/defaults.ts +60 -0
  310. package/dist/templates/starter-game/ui/index.html +12 -0
  311. package/dist/templates/starter-game/ui/src/App.test.tsx +138 -0
  312. package/dist/templates/starter-game/ui/src/App.tsx +175 -0
  313. package/dist/templates/starter-game/ui/src/DayBar.test.tsx +78 -0
  314. package/dist/templates/starter-game/ui/src/DayBar.tsx +72 -0
  315. package/dist/templates/starter-game/ui/src/HistoryPanel.test.tsx +74 -0
  316. package/dist/templates/starter-game/ui/src/HistoryPanel.tsx +120 -0
  317. package/dist/templates/starter-game/ui/src/MakeRow.tsx +129 -0
  318. package/dist/templates/starter-game/ui/src/Section.tsx +37 -0
  319. package/dist/templates/starter-game/ui/src/ThemeToggle.tsx +49 -0
  320. package/dist/templates/starter-game/ui/src/TodayPanel.test.tsx +179 -0
  321. package/dist/templates/starter-game/ui/src/TodayPanel.tsx +92 -0
  322. package/dist/templates/starter-game/ui/src/YesterdayPanel.tsx +142 -0
  323. package/dist/templates/starter-game/ui/src/format.ts +12 -0
  324. package/dist/templates/starter-game/ui/src/i18n.ts +95 -0
  325. package/dist/templates/starter-game/ui/src/main.tsx +48 -0
  326. package/dist/templates/starter-game/ui/src/menu.ts +18 -0
  327. package/dist/templates/starter-game/ui/src/test-helpers.ts +58 -0
  328. package/dist/templates/starter-game/ui/src/theme.ts +45 -0
  329. package/dist/templates/starter-game/ui/src/writes.ts +43 -0
  330. package/dist/templates/starter-game/ui/types.ts +137 -0
  331. package/dist/templates/starter-game/ui/ui.sdk.json +11 -0
  332. package/dist/templates/starter-game/validators/capacity/defaults.ts +37 -0
  333. package/dist/templates/starter-game/validators/capacity/logic/logic.test.ts +96 -0
  334. package/dist/templates/starter-game/validators/capacity/logic/logic.ts +45 -0
  335. package/dist/templates/starter-game/validators/capacity/types.ts +55 -0
  336. package/dist/templates/starter-game/validators/capacity/validator.sdk.json +11 -0
  337. package/dist/templates/starter-game/vite.config.ts +19 -0
  338. package/dist/templates/starter-game/vitest.config.ts +15 -0
  339. package/dist/templates/starter-game/vitest.engine.config.ts +19 -0
  340. package/dist/templates/starter-game/waiting_room/defaults.ts +40 -0
  341. package/dist/templates/starter-game/waiting_room/index.html +12 -0
  342. package/dist/templates/starter-game/waiting_room/src/App.test.tsx +102 -0
  343. package/dist/templates/starter-game/waiting_room/src/App.tsx +194 -0
  344. package/dist/templates/starter-game/waiting_room/src/i18n.ts +33 -0
  345. package/dist/templates/starter-game/waiting_room/src/main.tsx +48 -0
  346. package/dist/templates/starter-game/waiting_room/src/theme.ts +45 -0
  347. package/dist/templates/starter-game/waiting_room/types.ts +59 -0
  348. package/dist/templates/starter-game/waiting_room/waiting_room.sdk.json +10 -0
  349. package/dist/templates/tick-controller/logic.ts.liquid +8 -0
  350. package/dist/templates/ui/index.html.liquid +12 -0
  351. package/dist/templates/ui/src/App.test.tsx.liquid +41 -0
  352. package/dist/templates/ui/src/App.tsx.liquid +103 -0
  353. package/dist/templates/ui/src/i18n.ts.liquid +47 -0
  354. package/dist/templates/ui/src/main.tsx.liquid +48 -0
  355. package/dist/templates/ui/src/theme.ts.liquid +46 -0
  356. package/dist/templates/validator/logic.test.ts.liquid +42 -0
  357. package/dist/templates/validator/logic.ts.liquid +21 -0
  358. package/dist/templates/waiting-room/index.html.liquid +12 -0
  359. package/dist/templates/waiting-room/src/App.test.tsx.liquid +57 -0
  360. package/dist/templates/waiting-room/src/App.tsx.liquid +118 -0
  361. package/dist/templates/waiting-room/src/i18n.ts.liquid +44 -0
  362. package/dist/templates/waiting-room/src/main.tsx.liquid +48 -0
  363. package/dist/templates/waiting-room/src/theme.ts.liquid +46 -0
  364. package/dist/templating/resource-metadata.d.ts +131 -0
  365. package/dist/types.d.ts +14 -0
  366. package/dist/utils/atomic-write.d.ts +40 -0
  367. package/dist/utils/cli-error.d.ts +64 -0
  368. package/dist/utils/document-parser-client.d.ts +20 -0
  369. package/dist/utils/env-loader.d.ts +40 -0
  370. package/dist/utils/error-codes.d.ts +335 -0
  371. package/dist/utils/errors.d.ts +19 -0
  372. package/dist/utils/global-settings.d.ts +65 -0
  373. package/dist/utils/llm-client.d.ts +34 -0
  374. package/dist/utils/logger.d.ts +36 -0
  375. package/dist/utils/output.d.ts +109 -0
  376. package/dist/utils/platform.d.ts +14 -0
  377. package/dist/utils/prompt.d.ts +36 -0
  378. package/dist/utils/real-path.d.ts +6 -0
  379. package/dist/utils/schema-properties.d.ts +35 -0
  380. package/dist/validation/ajv.d.ts +17 -0
  381. package/dist/validation/facilitator-guide-validator.d.ts +27 -0
  382. package/dist/validation/findings.d.ts +40 -0
  383. package/dist/validation/game-constraints.d.ts +10 -0
  384. package/dist/validation/game-validator.d.ts +34 -0
  385. package/dist/validation/package-validation.d.ts +41 -0
  386. package/dist/validation/package-validator.d.ts +19 -0
  387. package/dist/validation/resource-validator.d.ts +79 -0
  388. package/dist/validation/schema-defaults-validator.d.ts +29 -0
  389. package/dist/validation/schema-validation.d.ts +115 -0
  390. package/dist/validation/semver.d.ts +9 -0
  391. package/package.json +122 -3
@@ -0,0 +1,816 @@
1
+ # Troubleshooting
2
+
3
+ Find the symptom you are seeing, then read its cause and fix. Entries are grouped by where the problem shows up.
4
+
5
+ - [Dev server and sessions](#dev-server-and-sessions)
6
+ - [Engine logic and endpoints](#engine-logic-and-endpoints)
7
+ - [Build and validation](#build-and-validation)
8
+ - [User interfaces](#user-interfaces)
9
+ - [Tests](#tests)
10
+ - [Other error messages](#other-error-messages)
11
+
12
+ ## Dev server and sessions
13
+
14
+ ### The dev server does not start
15
+
16
+ **Symptom:** `pnpm run sdk dev` fails, or does not open http://localhost:3000.
17
+
18
+ **Fix:** work through these in order.
19
+
20
+ 1. Check the Node.js version. The SDK requires Node 24 or later:
21
+
22
+ ```bash
23
+ node --version
24
+ ```
25
+
26
+ 2. Check you are in a package directory:
27
+
28
+ ```bash
29
+ ls seriousgaming.sdk.json
30
+ ```
31
+
32
+ 3. Install dependencies:
33
+
34
+ ```bash
35
+ pnpm install
36
+ ```
37
+
38
+ 4. Clean and rebuild:
39
+
40
+ ```bash
41
+ rm -rf node_modules dist
42
+ pnpm install
43
+ pnpm run build
44
+ pnpm run sdk dev
45
+ ```
46
+
47
+ 5. Try a different port:
48
+
49
+ ```bash
50
+ pnpm run sdk dev --port 3001
51
+ ```
52
+
53
+ ### A command fails with SESSION_STALE
54
+
55
+ **Symptom:** `sdk tick` or another session command fails with `SESSION_STALE` (exit 5), saying the dev server was started by different tools.
56
+
57
+ **Cause:** the dev server you started with `sdk dev` is running an older build of the SDK tools than your CLI: you upgraded, rebuilt a linked checkout, or switched branch while it ran. Its answers may not match what is on disk, and a server you started yourself is never stopped for you. A server a command started in the background is replaced automatically instead.
58
+
59
+ **Fix:** stop it and start it again:
60
+
61
+ ```bash
62
+ pnpm run sdk dev stop
63
+ pnpm run sdk dev
64
+ ```
65
+
66
+ ### sdk dev says a server is running when none is
67
+
68
+ A lock whose process is gone, whose pid is the process reading it, that was written on another machine, or whose port does not answer as that server is removed, and `sdk dev` starts. If your project directory is restored from a snapshot, set `SERIOUSGAMING_DEV_STATE_DIR` to a directory outside it so the lock is not restored at all (see [Environment variables](./environment-variables.md#dev-server)).
69
+
70
+ ### A command fails with DEV_SERVER_UNRESPONSIVE, or hangs after a tick
71
+
72
+ **Symptom:** a tick never finishes, and every command after it fails with `DEV_SERVER_UNRESPONSIVE`, saying the server accepts connections but did not answer.
73
+
74
+ **Cause:** logic is stuck in synchronous code that never returns, such as a `while (true)` whose exit condition is never met. The dev server runs logic on its own thread, so a loop like this blocks the whole server, and the time limit on the call cannot fire until the loop ends (see [Time limits](./guides/engine.md#time-limits)).
75
+
76
+ **Fix:** stop the server, which kills it if it does not exit on its own, then fix the loop and start again:
77
+
78
+ ```bash
79
+ pnpm run sdk dev stop
80
+ ```
81
+
82
+ A `tick --no-server` stuck the same way runs in your terminal: stop it with Ctrl+C.
83
+
84
+ ### The console says 'Nothing is answering', or the CLI and the browser disagree
85
+
86
+ **Symptom:** the console sits on 'Nothing is answering', or `sdk tick` advances a session the browser does not show.
87
+
88
+ **Cause:** the browser is on a different dev server from the one your commands reach, usually an older one still holding the port, so the server you just started moved to the next free port. The CLI and a browser on the same server cannot disagree: they are one session.
89
+
90
+ **Fix:** ask where this package's server actually is, and open that address, or stop the old one:
91
+
92
+ ```bash
93
+ pnpm run sdk dev status
94
+ pnpm run sdk dev stop
95
+ ```
96
+
97
+ ### Game surfaces cannot be served
98
+
99
+ **Symptom:** `sdk dev` starts, but a surface fails to load and the server prints 'Game surfaces cannot be served'.
100
+
101
+ **Cause:** the package's dependencies are not installed, so Vite cannot load its configuration. The session still runs, so the CLI and the console's state work as usual.
102
+
103
+ **Fix:** install the dependencies and start the server again:
104
+
105
+ ```bash
106
+ pnpm install
107
+ pnpm run sdk dev stop
108
+ pnpm run sdk dev
109
+ ```
110
+
111
+ ### Engine code does not appear, or is stale
112
+
113
+ **Symptom:** the dev server does not pick up the engine, or runs old code.
114
+
115
+ **Cause:** a logic edit changes the next run, not the ticks already played. If the engine still looks wrong after a new tick, the files themselves may be missing or incomplete. See [What reloads](./cli-reference.md#what-reloads).
116
+
117
+ **Fix:**
118
+
119
+ 1. Rebuild after making changes:
120
+
121
+ ```bash
122
+ pnpm run build
123
+ pnpm run sdk dev
124
+ ```
125
+
126
+ 2. Check the engine file exists:
127
+
128
+ ```bash
129
+ ls engine/logic.ts
130
+ ```
131
+
132
+ 3. Check the engine exports the right functions:
133
+
134
+ ```bash
135
+ grep "export const Run" engine/logic.ts
136
+ ```
137
+
138
+ 4. Check the engine bundle:
139
+
140
+ ```bash
141
+ cat engine/engine.sdk.json
142
+ ```
143
+
144
+ ### UIs crash after a capability schema change
145
+
146
+ **Symptom:** after changing a capability's `variablesSchema` while a game is running under `sdk dev`, UIs crash reading fields that do not exist yet, and team contexts keep the old shape.
147
+
148
+ **Cause:** a bundle edit is adopted and a logic edit reaches the next run, but neither resets the session. Contexts that `Init` has already built keep the shape they had, so a new field has no value until something writes it.
149
+
150
+ **Fix:**
151
+
152
+ 1. Reset the session so `Init` runs again against the new schema:
153
+
154
+ ```bash
155
+ pnpm run sdk reset
156
+ ```
157
+
158
+ 2. Or undo and tick again to replay a tick from the same starting point with the new code. See [What reloads](./cli-reference.md#what-reloads)
159
+
160
+ ### A tick is refused with 'Tick limit reached'
161
+
162
+ **Symptom:** a tick request is refused instead of advancing the game. From a UI, `requestTick` rejects with a `MutationError` whose `outcome.kind` is `'tick-failed'`; from the CLI, `sdk tick` exits non-zero. The message is `Tick limit reached`, or `The game is complete` once the session has finished.
163
+
164
+ **Cause:** the game has reached its declared `maxTicks` limit, and the runtime refuses to execute a tick beyond it.
165
+
166
+ **Fix:**
167
+
168
+ 1. This is the expected end of the game. Use undo or reset to keep playing, or raise `maxTicks` in `seriousgaming.sdk.json` if the game should run longer
169
+ 2. Your UI does not need to gate its advance control on `latestTick < maxTicks` for correctness, because the runtime enforces the limit. Disabling the control remains good UX
170
+
171
+ ### A tick is refused with 'Team is already complete'
172
+
173
+ **Symptom:** `sdk tick --team N` is refused with `Team is already complete`.
174
+
175
+ **Cause:** in an independent game, that team has finished.
176
+
177
+ **Fix:** tick another team, tick with no `--team` to advance every team that can move, or reset the session with `pnpm run sdk reset`.
178
+
179
+ ### The dev server is slow
180
+
181
+ **Symptom:** the game runs slowly and the dev server is sluggish.
182
+
183
+ **Fix:**
184
+
185
+ 1. Reduce the tick count while testing:
186
+
187
+ ```bash
188
+ pnpm run sdk update package --patch '[{"op":"replace","path":"/maxTicks","value":5}]'
189
+ ```
190
+
191
+ 2. Profile the engine. Logic runs with only the ECMAScript intrinsics and the SDK's `console` shim (`log`, `info`, `warn`, `error`, and `debug`; there is no `console.time`), so time a section with `Date.now()`:
192
+
193
+ ```typescript
194
+ const started = Date.now();
195
+ // engine logic
196
+ console.log(`engine-run: ${Date.now() - started}ms`);
197
+ ```
198
+
199
+ 3. Make expensive calculations cheaper:
200
+ - Avoid loops in `Run` functions
201
+ - Cache computed values
202
+ - Use efficient algorithms
203
+
204
+ 4. Check system resources:
205
+
206
+ ```bash
207
+ top # macOS/Linux
208
+ tasklist # Windows
209
+ ```
210
+
211
+ ## Engine logic and endpoints
212
+
213
+ ### Context changes do not appear in the next tick
214
+
215
+ **Symptom:** changes the engine makes to the context are gone on the next tick.
216
+
217
+ **Cause:** one of three mistakes in `Run`.
218
+
219
+ **Fix:**
220
+
221
+ 1. **Return a new object instead of mutating the context:**
222
+
223
+ ```typescript
224
+ // ❌ Wrong - mutates context
225
+ context.inventory.variable = value;
226
+
227
+ // ✅ Correct - immutable update
228
+ return {
229
+ capabilities: {
230
+ ...context,
231
+ inventory: {
232
+ ...context.inventory,
233
+ variable: value,
234
+ },
235
+ },
236
+ };
237
+ ```
238
+
239
+ 2. **Return the result from `Run`:**
240
+
241
+ ```typescript
242
+ // ❌ Wrong - doesn't return
243
+ export const Run = async ({ context, settings, callbacks }) => {
244
+ // modify context
245
+ };
246
+
247
+ // ✅ Correct
248
+ export const Run = async ({ context, settings, callbacks }) => {
249
+ return { capabilities: { ...context, ... } };
250
+ };
251
+ ```
252
+
253
+ 3. **Key the result by the capability identifier:**
254
+
255
+ ```typescript
256
+ // ❌ Wrong - wrong identifier
257
+ return {
258
+ capabilities: {
259
+ ...context,
260
+ "com.wrong.identifier": { ... }
261
+ },
262
+ };
263
+
264
+ // ✅ Correct
265
+ return {
266
+ capabilities: {
267
+ ...context,
268
+ "inventory": { ... }
269
+ },
270
+ };
271
+ ```
272
+
273
+ ### A tick fails with 'returned unknown top-level key'
274
+
275
+ **Symptom:** a tick, init, hook or endpoint call fails with an error such as `Engine "engine" Run returned unknown top-level key "inventory"`.
276
+
277
+ **Cause:** the logic returns its capabilities flat, the shape SDK 0.6 and earlier used (or `{ response, context }` from a writing endpoint). Logic now returns what it writes under `capabilities`, and the runtime refuses any top-level key it does not know rather than silently discarding the writes.
278
+
279
+ **Fix:** wrap the return:
280
+
281
+ ```typescript
282
+ // ❌ Wrong - flat
283
+ return { ...context, inventory: { ...context.inventory, Stock } };
284
+
285
+ // ✅ Correct
286
+ return { capabilities: { ...context, inventory: { ...context.inventory, Stock } } };
287
+ ```
288
+
289
+ An aggregate engine returns `{ shared: { capabilities }, teams: [{ capabilities }] }`, and a writing endpoint `{ response, capabilities }`. See the [upgrading guide](./guides/upgrading.md).
290
+
291
+ ### Variables have unexpected values
292
+
293
+ **Symptom:** variables show values you did not expect.
294
+
295
+ **Fix:**
296
+
297
+ 1. Check the variable schema defaults:
298
+
299
+ ```bash
300
+ cat capabilities/inventory/capability.sdk.json
301
+ ```
302
+
303
+ 2. Trace engine initialisation:
304
+
305
+ ```typescript
306
+ // Add logging in Init function
307
+ export const Init = async ({ context, settings, callbacks }) => {
308
+ console.log('Initial context:', context);
309
+ console.log('Settings:', settings);
310
+ return { ... };
311
+ };
312
+ ```
313
+
314
+ 3. Inspect the actual values in the dev server's context inspector
315
+
316
+ ### A field the engine cleared comes back on a hosted session
317
+
318
+ **Symptom:** the engine clears an object variable by returning `{}`, for example `PendingJunction: {}`. Locally the field is empty after the tick, in the dev server and in tests alike. On a hosted session the old value is still there.
319
+
320
+ **Cause:** a returned variable replaces its old value whole, so `{}` empties it (see [how a result folds into the context](./guides/engine.md#how-a-result-folds-into-the-context)). A runtime that instead merges the returned object into the old one treats `{}` as a change to nothing. No runtime should do that, but a hosted runtime has done it.
321
+
322
+ **Fix:** return a value that comes out the same either way. Set each field inside the variable explicitly, or return `null` for the variable if its schema allows `null`. Both clear the field on every runtime.
323
+
324
+ ### Shared values from an aggregate engine stay at their defaults
325
+
326
+ **Symptom:** values an aggregate engine returns in the `shared` slice of its `InitAggregate` or `RunAggregate` result stay at their schema defaults on every tick, with no error.
327
+
328
+ **Cause:** SDK versions before 0.0.104 discard the `shared` slice, so a shared value persists only if the engine also writes it into each `teams` context.
329
+
330
+ **Fix:**
331
+
332
+ 1. Update the SDK. The runtime writes `shared` to the shared store after applying `teams`, so returning the value in `shared` alone is enough. Remove any copy the workaround wrote into each `teams` context: a shared capability in a `teams` entry now fails the init or tick (see the next entry)
333
+ 2. Check that every key in `shared.capabilities` is a `scope: 'shared'` capability. Anything else fails the init or tick with an error naming the engine and the capability
334
+
335
+ ### An aggregate engine fails with 'returned shared capability in teams'
336
+
337
+ **Symptom:** an init or tick fails with an error such as `Engine "engine" returned shared capability "market" in teams[0] of RunAggregate. Return shared capabilities once, under "shared": { capabilities: { market: ... } }.`
338
+
339
+ **Cause:** a `teams` entry of the result carries a `scope: 'shared'` capability. A `teams` entry is a per-team patch, and a capability with one value per session has no per-team value, so the runtime refuses it even when every team carries the same value. Earlier SDK versions adopted a value every team carried identically; that channel is removed.
340
+
341
+ **Fix:**
342
+
343
+ 1. Return the shared value once, under `shared: { capabilities }`
344
+ 2. Read the previous value from the `shared` argument (`shared.context.market`), not off a team. Each `teams[i].context` now carries team scope only, so spreading `...t.context` into a `teams` entry no longer copies shared capabilities back
345
+ 3. Type the function with the generated `TeamContext` and `SharedContext`: `RunAggregateFunction<TeamContext, SharedContext, Settings>`. A shared capability in a `teams` entry is then a compile error as well. See [step 5 of the upgrading guide](./guides/upgrading.md#step-5-read-shared-state-from-its-own-channel)
346
+
347
+ ### A writing endpoint is refused with 'the game moved on'
348
+
349
+ **Symptom:** an endpoint that declares `writes` returns _'The game moved on while the endpoint was running'_ and changes nothing.
350
+
351
+ **Cause:** a tick committed while the handler was still running, so its patch was computed against a board that has since been replaced. Applying it would silently undo part of the tick that just closed.
352
+
353
+ **Fix:**
354
+
355
+ 1. Make the handler faster. A handler that calls a model can easily outlive the tick it was called in, and a facilitator operation taking that long is a poor experience regardless
356
+ 2. Move the slow part into the engine, which runs as part of the tick rather than beside it
357
+ 3. Where the work genuinely has to be slow and the result genuinely has to land, have the handler write a request into the context and let the next tick act on it
358
+
359
+ ## Build and validation
360
+
361
+ ### TypeScript reports errors about `Context` or `Settings` types
362
+
363
+ **Symptom:** compilation fails with errors about the generated `Context` or `Settings` types.
364
+
365
+ **Fix:**
366
+
367
+ 1. Regenerate types:
368
+
369
+ ```bash
370
+ pnpm run generate
371
+ pnpm run build
372
+ ```
373
+
374
+ 2. Check the resource definitions are valid:
375
+
376
+ ```bash
377
+ pnpm run sdk build --validate-only
378
+ ```
379
+
380
+ 3. Check the generated types file:
381
+
382
+ ```bash
383
+ cat engine/types.ts
384
+ ```
385
+
386
+ 4. Restart your editor's TypeScript server (in VS Code: Cmd+Shift+P, then 'TypeScript: Restart TS server')
387
+
388
+ ### The build fails with a missing capability
389
+
390
+ **Symptom:** `Engine "engine" reads capability "foo" which is not found in configuration`, or the same for another resource, or for `writes`.
391
+
392
+ **Fix:**
393
+
394
+ 1. Check the capability exists:
395
+
396
+ ```bash
397
+ ls capabilities/foo/capability.sdk.json
398
+ ```
399
+
400
+ 2. Check the spelling in the engine definition:
401
+
402
+ ```bash
403
+ grep -r "foo" engine/
404
+ ```
405
+
406
+ 3. Create the missing capability:
407
+
408
+ ```bash
409
+ pnpm run sdk new capability '{
410
+ "definition": {
411
+ "identifier": "foo",
412
+ "variablesSchema": {
413
+ "type": "object",
414
+ "properties": {},
415
+ "required": [],
416
+ "additionalProperties": false
417
+ }
418
+ }
419
+ }'
420
+ ```
421
+
422
+ ### The build rejects `aggregate` in engine.sdk.json
423
+
424
+ **Symptom:** `pnpm run sdk build` fails with ``\`aggregate\` has been removed`` on an engine bundle that carries the flag.
425
+
426
+ **Cause:** an engine is aggregate because its logic exports `InitAggregate` and `RunAggregate`, and the build reads that from the code. An authored flag could only agree with the exports or contradict them, so the bundle may not carry one.
427
+
428
+ **Fix:**
429
+
430
+ 1. Delete the field. Nothing replaces it:
431
+
432
+ ```bash
433
+ pnpm run sdk update engine --patch '[
434
+ { "op": "remove", "path": "/definition/aggregate" }
435
+ ]'
436
+ ```
437
+
438
+ 2. If the engine is meant to be aggregate, make sure its logic exports `InitAggregate` and `RunAggregate` (and `Init`, if it needs one). Exporting one of the aggregate pair without the other fails the build, naming the missing one
439
+ 3. If it is meant to be per team, remove the aggregate exports and keep `Run` (and `Init`, if it has one)
440
+
441
+ ### The build rejects `configurationSchema` or the game's `configuration` block
442
+
443
+ **Symptom:** loading or building the package fails with one of these:
444
+
445
+ ```
446
+ `configurationSchema` has been removed. Move these properties into a settings resource (`pnpm run sdk new settings`), and list it in this resource's `settings`.
447
+ ```
448
+
449
+ ```
450
+ The game-level `configuration` block has been removed: edit the settings resource's defaults instead, or override them in a scenario's `settings`. Delete the block.
451
+ ```
452
+
453
+ **Cause:** settings are no longer declared per resource. It lives in settings resources, `settings/<name>/settings.sdk.json`, which any resource reads by listing them in its `settings`. A game's own values are those resources' defaults, so there is no game-level override layer left for the manifest's `configuration` block to fill.
454
+
455
+ **Fix:**
456
+
457
+ 1. Create a settings resource holding the old `configurationSchema` properties, with `pnpm run sdk new settings` (interactive) or `pnpm run sdk new settings '<JSON>'` (see [Create settings](./recipes/create-settings.md)). Every property needs a `default`
458
+ 2. Delete the `configurationSchema` from the bundle and add `"settings": ["<name>"]` in its place
459
+ 3. Read `settings.<name>.X` in logic and surfaces where they read `config.X`, then run `pnpm run sdk generate`
460
+ 4. Copy any values from the manifest's `configuration` block into the settings defaults, then delete the block
461
+
462
+ [Step 2 of the upgrading guide](./guides/upgrading.md#step-2-move-configuration-into-settings-resources) walks through the whole move.
463
+
464
+ ### The build rejects `demo` or a user interface's `uses`
465
+
466
+ **Symptom:** loading or building the package fails with one of these:
467
+
468
+ ```
469
+ Demo mode has been removed, so `demo` is read by nothing. To show a game to a room, start a walkthrough run, which plays it without touching the session. Delete the block.
470
+ ```
471
+
472
+ ```
473
+ `uses` has been removed from user interfaces: a user interface reaches a service through an endpoint. Declare the API in the endpoint's `uses`, list the endpoint in this interface's `endpoints`, and delete the field.
474
+ ```
475
+
476
+ **Cause:** both fields were removed in 1.0. Nothing defined how a session entered demo mode, and a walkthrough run is where a game is demonstrated. A user interface could never call a service directly, so every value its `uses` accepted was either refused or did nothing.
477
+
478
+ **Fix:**
479
+
480
+ 1. Delete the `demo` block from `seriousgaming.sdk.json` and from any scenario. To rehearse or show the game, use a walkthrough run (see [Adapt a game for walkthroughs](./recipes/adapt-a-game-for-walkthroughs.md))
481
+ 2. Delete `uses` from the user interface. If it needs a service, put the call in an endpoint that declares it, and list that endpoint in the interface's `endpoints` (see [Call an endpoint from a UI](./recipes/call-endpoint-from-ui.md))
482
+
483
+ ### A settings override fails with 'Unknown settings'
484
+
485
+ **Symptom:** `sdk configure`, `sdk init`, `sdk build`, or a scenario switch fails with `Unknown settings "engine": expected one of ...` (or `this package declares no settings`).
486
+
487
+ **Cause:** a scenario's `settings`, `sdk configure` input, and `.seriousgaming-sdk/configuration.json` are keyed by settings identifier, the directory name under `settings/`. They were keyed by slot before, so an override written for the old shape names a slot (`engine`, `ui`, `tick_controller`) that the package holds no settings resource for. The override is refused rather than ignored, because an override that reaches nothing reads as applied.
488
+
489
+ **Fix:** re-key the override by the settings resource that declares the property, or create one with that name. A value in `.seriousgaming-sdk/configuration.json` can be corrected in place, or the file deleted to start again from the defaults. See [Overriding settings](./guides/settings.md#overriding-settings).
490
+
491
+ ### An aggregate engine fails the build with 'must export Init and Run'
492
+
493
+ **Symptom:** an engine you intended as aggregate fails `pnpm run sdk build` with errors saying it must export `Init` and `Run`.
494
+
495
+ **Cause:** its logic exports neither `InitAggregate` nor `RunAggregate`, so the build reads it as a per-team engine and applies the per-team export contract. Merging several files into one engine makes this easy to do: the aggregate functions end up in a file nothing re-exports.
496
+
497
+ **Fix:**
498
+
499
+ 1. Check what the entrypoint actually exports:
500
+
501
+ ```bash
502
+ grep -n 'export const \(Init\|Run\)' engine/logic.ts
503
+ ```
504
+
505
+ 2. Export the aggregate pair from the entrypoint. A re-export counts:
506
+
507
+ ```typescript
508
+ export { InitAggregate, RunAggregate } from './market';
509
+ ```
510
+
511
+ 3. `sdk new engine --aggregate` scaffolds all three exports for a fresh engine
512
+
513
+ ### The build rejects a teamless surface calling a team-scoped endpoint
514
+
515
+ **Symptom:** `pnpm run sdk build` fails with _'calls endpoint X, which is team-scoped, but this surface has no team of its own'_ on a session UI, setup screen, or scenario editor.
516
+
517
+ **Cause:** an endpoint declares whether it acts on one team or on the session, and `scope` is `'team'` when absent. A session UI, a setup screen, and a scenario editor have no team of their own, so there is nothing for a team-scoped call to act against.
518
+
519
+ **Fix:**
520
+
521
+ 1. If the endpoint acts on the session, declare it session-scoped:
522
+
523
+ ```json
524
+ { "definition": { "scope": "session" } }
525
+ ```
526
+
527
+ 2. If the endpoint genuinely acts on one team, stop listing it on the teamless surface and call it from the game UI instead
528
+ 3. Check what each endpoint declares:
529
+
530
+ ```bash
531
+ pnpm run sdk endpoint list
532
+ ```
533
+
534
+ ### The build is slow
535
+
536
+ **Symptom:** `pnpm run build` takes a long time.
537
+
538
+ **Fix:**
539
+
540
+ 1. Check for large files:
541
+
542
+ ```bash
543
+ find . -size +10M
544
+ ```
545
+
546
+ 2. Clear the build cache:
547
+
548
+ ```bash
549
+ rm -rf dist build node_modules
550
+ pnpm install
551
+ pnpm run build
552
+ ```
553
+
554
+ 3. Use the dev server while you work: it watches sources for you rather than needing a full rebuild each time (start it yourself; agents should not):
555
+
556
+ ```bash
557
+ pnpm run sdk dev
558
+ ```
559
+
560
+ ### A package built on Windows serves the wrong asset paths
561
+
562
+ **Symptom:** a package builds and runs on your machine, but once published a user interface fails to load its files, or `pnpm run sdk build` in a project that depends on the package fails to find a resource directory. `dist/seriousgaming.json` shows a backslash in the path:
563
+
564
+ ```json
565
+ "rootDirectory": "user-interfaces\\com.example.dashboard"
566
+ ```
567
+
568
+ **Cause:** the package was built on Windows with SDK 0.0.119 or earlier, which composed each `rootDirectory` with the host's path separator. A POSIX host and an object store cannot follow a backslash. A browser normalises one in a URL path, which is why the dev server and a direct page load look fine.
569
+
570
+ **Fix:**
571
+
572
+ 1. Upgrade the SDK and rebuild:
573
+
574
+ ```bash
575
+ pnpm run sdk build
576
+ grep rootDirectory dist/seriousgaming.json
577
+ ```
578
+
579
+ Every value should read `<resource-kind>/<identifier>` with forward slashes.
580
+
581
+ 2. Republish the package, since the bad paths are baked into the published artefact:
582
+
583
+ ```bash
584
+ pnpm run sdk package bundle
585
+ pnpm run sdk package publish
586
+ ```
587
+
588
+ 3. If you consume a package published this way and cannot get it rebuilt, upgrade your own SDK instead. It normalises the separator as a dependency's manifest is read, so the package works without being rebuilt
589
+
590
+ ## User interfaces
591
+
592
+ ### A UI is blank or does not appear
593
+
594
+ **Symptom:** a user interface shows nothing in the dev server.
595
+
596
+ **Fix:**
597
+
598
+ 1. Check the UI bundle:
599
+
600
+ ```bash
601
+ cat ui/ui.sdk.json
602
+ ```
603
+
604
+ 2. Check the React component exports:
605
+
606
+ ```bash
607
+ grep "export default" ui/src/App.tsx
608
+ ```
609
+
610
+ 3. Check the build output:
611
+
612
+ ```bash
613
+ ls dist/ui/
614
+ ```
615
+
616
+ 4. Look in the browser console for errors (F12 in the dev server)
617
+
618
+ 5. Open the dev drawer (press the backtick key). If the **State** tab shows what you expect, the problem is in the surface rather than the session, and the **Errors** tab lists anything the session reported
619
+
620
+ ### 'Invalid hook call' or 'Cannot read properties of null'
621
+
622
+ **Symptom:** the UI crashes with:
623
+
624
+ > Error: Invalid hook call. Hooks can only be called inside of the function body of a function component.
625
+
626
+ or:
627
+
628
+ > Cannot read properties of null (reading 'useState')
629
+
630
+ **Cause:** a third-party library (such as `@react-three/fiber` or MUI) has React as a peer dependency but also `require()`s React internally. Vite's pre-bundler produces a second copy of React, so two React instances are active at runtime. Hooks fail because the renderer's dispatcher is registered on one while components read from the other.
631
+
632
+ **Fix:** add a `vite.config.ts` to your project root with `resolve.dedupe`, as `sdk new package` writes it:
633
+
634
+ ```typescript
635
+ import { defineConfig } from 'vite';
636
+
637
+ export default defineConfig({
638
+ resolve: {
639
+ dedupe: [
640
+ 'react',
641
+ 'react-dom',
642
+ '@emotion/react',
643
+ '@emotion/styled',
644
+ '@seriousgaming/sdk',
645
+ '@seriousgaming/deck',
646
+ ],
647
+ },
648
+ });
649
+ ```
650
+
651
+ The SDK packages are there for the same reason as React: a second copy of the SDK, such as one a shared package of yours resolves, brings its own React contexts, so its hooks read empty data rather than throwing.
652
+
653
+ Restart the dev server. The SDK merges this config automatically for both `sdk dev` and `sdk build`. See [Fix duplicate package errors in a UI](./recipes/fix-duplicate-packages.md) for more.
654
+
655
+ ### `useUserInterfaceData()` throws, or its data is undefined
656
+
657
+ **Symptom:** `useUserInterfaceData()` throws an error, or the data it returns is undefined.
658
+
659
+ **Fix:**
660
+
661
+ 1. Make sure the UI reads the capabilities it needs:
662
+
663
+ ```bash
664
+ cat ui/ui.sdk.json | grep "reads"
665
+ ```
666
+
667
+ 2. Use the hook the SDK provides:
668
+
669
+ ```typescript
670
+ // ✅ Correct
671
+ const { data, settings, setData } = useUserInterfaceData<Context, Settings>();
672
+ const { Stock } = data.inventory;
673
+
674
+ // ❌ Wrong - trying to use non-existent hooks
675
+ const context = useUserInterfaceContext<Context>();
676
+ const settings = useUserInterfaceSettings<Settings>();
677
+ ```
678
+
679
+ 3. Check the type imports:
680
+
681
+ ```typescript
682
+ import type { Context, Settings } from '../types';
683
+ import { useUserInterfaceData } from '@seriousgaming/sdk/ui';
684
+ ```
685
+
686
+ 4. Call the hook inside `UserInterfaceWrapper`:
687
+
688
+ ```typescript
689
+ // ❌ Wrong - hook used outside wrapper
690
+ const { data } = useUserInterfaceData<Context, Settings>();
691
+
692
+ export default () => <App />;
693
+
694
+ // ✅ Correct - hook inside wrapper
695
+ export default () => <UserInterfaceWrapper><App /></UserInterfaceWrapper>;
696
+ ```
697
+
698
+ ### A UI is blocked by the content security policy
699
+
700
+ **Symptom:** the browser console shows errors such as:
701
+
702
+ ```
703
+ Content-Security-Policy: The page's settings blocked a worker script (worker-src)
704
+ at blob:... because it violates the following directive: "script-src 'self' 'unsafe-inline'"
705
+ ```
706
+
707
+ or fonts, scripts, or stylesheets fail to load from an external origin (for example `fonts.googleapis.com`).
708
+
709
+ **Cause:** your UI runs under a strict content security policy on the isolated asset host, and the dev server applies the same policy as production. Everything must be first-party to your bundle, outbound network calls are limited to the asset host, and blob-URL workers are blocked.
710
+
711
+ **Fix:**
712
+
713
+ 1. Bundle external assets into your build. Replace CDN font links with a self-hosted package (for example `@fontsource-variable/work-sans`) imported in your UI source
714
+ 2. Remove blob-URL web workers. Configure libraries that spawn workers (PDF.js, transformers.js, ONNX runtime) to load a bundled worker file, or avoid them
715
+ 3. Move outbound network calls out of the UI: fetch through an engine, an endpoint, or a host capability rather than calling a third-party origin directly
716
+ 4. Drop any reliance on `eval` or `new Function`: `unsafe-eval` is not granted
717
+
718
+ See [Production security constraints](./guides/production-constraints.md) for the full policy.
719
+
720
+ ### An asset is refused because its content type was not sniffed
721
+
722
+ **Symptom:** a script, stylesheet, or other asset is blocked with a console error such as:
723
+
724
+ ```
725
+ Refused to execute script from '...' because its MIME type ('text/plain') is not
726
+ executable, and strict MIME type checking is enabled.
727
+ ```
728
+
729
+ **Cause:** both production and the dev server send `X-Content-Type-Options: nosniff`, so the browser will not guess an asset's type from its bytes. An asset served with a missing or wrong `Content-Type` (a script delivered as `text/plain`, a stylesheet with the wrong type) is refused rather than sniffed into the right type.
730
+
731
+ **Fix:**
732
+
733
+ 1. Bundle the asset into your build so it is served with the correct type, rather than referencing a loosely typed file
734
+ 2. If you serve the asset through an endpoint or capability, set an accurate `Content-Type` on the response
735
+
736
+ See [Production security constraints](./guides/production-constraints.md) for the full asset-host response contract.
737
+
738
+ ### Content is hidden behind the iOS URL bar
739
+
740
+ **Symptom:** on iOS Safari or Chrome, the bottom of a UI is cut off behind the browser's URL bar, and the page will not scroll to reveal it.
741
+
742
+ **Cause:** on iOS WebKit, `height: 100vh` (and `min-height: 100vh`) resolves to the tall viewport you get once the URL bar collapses, even while the bar is still showing. A full-height element is therefore taller than the visible area on load.
743
+
744
+ **Fix:**
745
+
746
+ 1. Size your UI to its container (`height: 100%` through `html`, `body`, and the root element) rather than the viewport. The host already sizes the iframe to the visible area
747
+ 2. If you use viewport units, add a `dvh` value after the `vh` fallback: `min-height: 100vh; min-height: 100dvh;` (in MUI `sx`, `{ minHeight: '100vh', '@supports (height: 100dvh)': { minHeight: '100dvh' } }`)
748
+
749
+ See the [user interfaces guide](./guides/ui.md) for sizing to the viewport on mobile.
750
+
751
+ ## Tests
752
+
753
+ ### Tests will not run
754
+
755
+ **Symptom:** `pnpm run test` fails before any test runs.
756
+
757
+ **Fix:**
758
+
759
+ 1. Install the test runner:
760
+
761
+ ```bash
762
+ pnpm add -D vitest
763
+ ```
764
+
765
+ 2. Check the test file:
766
+
767
+ ```bash
768
+ cat engine/logic.test.ts
769
+ ```
770
+
771
+ 3. Run with verbose output:
772
+
773
+ ```bash
774
+ pnpm run test -- --reporter=verbose
775
+ ```
776
+
777
+ ### Tests pass locally but fail in CI
778
+
779
+ **Fix:**
780
+
781
+ 1. Run tests with the same Node version as CI:
782
+
783
+ ```bash
784
+ node --version
785
+ ```
786
+
787
+ 2. Clear `node_modules` and reinstall:
788
+
789
+ ```bash
790
+ rm -rf node_modules pnpm-lock.yaml
791
+ pnpm install
792
+ pnpm run test
793
+ ```
794
+
795
+ 3. Look for timing and async issues in the tests
796
+
797
+ ## Other error messages
798
+
799
+ | Error | Fix |
800
+ | ---------------------------------------- | ------------------------------------------ |
801
+ | `ENOENT: no such file or directory` | Check file paths, and create missing files |
802
+ | `JSON.parse error` | Check the JSON syntax in CLI commands |
803
+ | `Cannot find engine` | Run `pnpm install`, and check imports |
804
+ | `Type 'X' is not assignable to type 'Y'` | Check generated types, and regenerate them |
805
+
806
+ ## Getting help
807
+
808
+ Collect a detailed report and share it when you ask for help:
809
+
810
+ ```bash
811
+ pnpm run sdk build --validate-only
812
+ pnpm run lint
813
+ pnpm run build --verbose 2>&1 | tee build.log
814
+ ```
815
+
816
+ For more, see the [guides](./guides/index.md), the [concepts](./concepts/index.md), and the [CLI reference](./cli-reference.md). [Drive a game from the CLI](./cli-simulation-testing.md#troubleshooting) covers errors from session commands.