@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.
- package/LICENSE +93 -0
- package/README.md +36 -2
- package/dist/bundling/logic-exports.d.ts +34 -0
- package/dist/bundling/node-builtins.d.ts +21 -0
- package/dist/bundling/transpiler.d.ts +7 -0
- package/dist/cli.js +27368 -0
- package/dist/client/dev-server.d.ts +59 -0
- package/dist/client/index.d.ts +28 -0
- package/dist/client/stub-services.d.ts +32 -0
- package/dist/client/test-session.d.ts +195 -0
- package/dist/client.js +16884 -0
- package/dist/core/asset-reference-translator.d.ts +46 -0
- package/dist/core/clock.d.ts +57 -0
- package/dist/core/faults.d.ts +65 -0
- package/dist/core/game-settings.d.ts +65 -0
- package/dist/core/history.d.ts +89 -0
- package/dist/core/listen-with-fallback.d.ts +30 -0
- package/dist/core/mutation-queue.d.ts +61 -0
- package/dist/core/package-scenario.d.ts +89 -0
- package/dist/core/participant-registry.d.ts +109 -0
- package/dist/core/pending-changes.d.ts +14 -0
- package/dist/core/protocol.d.ts +83 -0
- package/dist/core/scenario-drafts.d.ts +32 -0
- package/dist/core/session-endpoints.d.ts +108 -0
- package/dist/core/session-gates.d.ts +75 -0
- package/dist/core/session-host.d.ts +94 -0
- package/dist/core/session-refusals.d.ts +56 -0
- package/dist/core/session-rewind.d.ts +32 -0
- package/dist/core/session-roster.d.ts +128 -0
- package/dist/core/session-surfaces.d.ts +32 -0
- package/dist/core/session-ticks.d.ts +18 -0
- package/dist/core/session-timers.d.ts +84 -0
- package/dist/core/session-writes.d.ts +40 -0
- package/dist/core/session.d.ts +385 -0
- package/dist/core/settings-locks.d.ts +22 -0
- package/dist/core/team-names.d.ts +52 -0
- package/dist/core/team-state-store.d.ts +209 -0
- package/dist/core/tick-timer.d.ts +75 -0
- package/dist/dev/blob-links.d.ts +10 -0
- package/dist/dev/console/assets/index-DgFglsnA.js +204 -0
- package/dist/dev/console/index.html +12 -0
- package/dist/dev/console-path.d.ts +19 -0
- package/dist/dev/lockfile.d.ts +124 -0
- package/dist/dev/package-watcher.d.ts +21 -0
- package/dist/dev/routes.d.ts +67 -0
- package/dist/dev/shell.d.ts +260 -0
- package/dist/dev/surfaces.d.ts +41 -0
- package/dist/dev/tools-identity.d.ts +23 -0
- package/dist/dev/view/batch.d.ts +172 -0
- package/dist/dev/view/commands.d.ts +75 -0
- package/dist/dev/view/route.d.ts +58 -0
- package/dist/dev/view/view.d.ts +78 -0
- package/dist/dev/view/viewer.d.ts +32 -0
- package/dist/discovery/config.d.ts +9 -0
- package/dist/discovery/manifest-paths.d.ts +21 -0
- package/dist/discovery/removed-fields.d.ts +90 -0
- package/dist/docs/api/deck.md +386 -0
- package/dist/docs/api/index.md +67 -0
- package/dist/docs/api/sdk-commands.md +286 -0
- package/dist/docs/api/sdk-e2e.md +433 -0
- package/dist/docs/api/sdk-projection.md +207 -0
- package/dist/docs/api/sdk-testing.md +214 -0
- package/dist/docs/api/sdk-tools-client.md +560 -0
- package/dist/docs/api/sdk-ui-testing.md +231 -0
- package/dist/docs/api/sdk-ui.md +1269 -0
- package/dist/docs/api/sdk.md +2140 -0
- package/dist/docs/changelog-0.x.md +1156 -0
- package/dist/docs/changelog.md +236 -0
- package/dist/docs/cli-and-dev-server.md +217 -0
- package/dist/docs/cli-error-codes.md +154 -0
- package/dist/docs/cli-reference.md +2488 -0
- package/dist/docs/cli-simulation-testing.md +222 -0
- package/dist/docs/concepts/index.md +46 -0
- package/dist/docs/concepts/terminology.md +322 -0
- package/dist/docs/environment-variables.md +102 -0
- package/dist/docs/getting-started.md +145 -0
- package/dist/docs/guides/ai-facilitation.md +220 -0
- package/dist/docs/guides/capabilities.md +460 -0
- package/dist/docs/guides/endpoints.md +335 -0
- package/dist/docs/guides/engine-testing.md +477 -0
- package/dist/docs/guides/engine.md +527 -0
- package/dist/docs/guides/file-handling.md +405 -0
- package/dist/docs/guides/games.md +176 -0
- package/dist/docs/guides/global-settings.md +94 -0
- package/dist/docs/guides/guide.md +123 -0
- package/dist/docs/guides/hooks.md +183 -0
- package/dist/docs/guides/index.md +51 -0
- package/dist/docs/guides/internationalization.md +288 -0
- package/dist/docs/guides/llm-integration.md +635 -0
- package/dist/docs/guides/multi-team-games.md +586 -0
- package/dist/docs/guides/patterns.md +391 -0
- package/dist/docs/guides/presentation.md +196 -0
- package/dist/docs/guides/production-constraints.md +130 -0
- package/dist/docs/guides/scenario-editor.md +143 -0
- package/dist/docs/guides/scenarios.md +515 -0
- package/dist/docs/guides/session.md +972 -0
- package/dist/docs/guides/settings.md +458 -0
- package/dist/docs/guides/setup.md +193 -0
- package/dist/docs/guides/speech-generation.md +233 -0
- package/dist/docs/guides/starter-game.md +164 -0
- package/dist/docs/guides/testing.md +575 -0
- package/dist/docs/guides/tick-controller.md +569 -0
- package/dist/docs/guides/type-safety.md +516 -0
- package/dist/docs/guides/ui.md +1389 -0
- package/dist/docs/guides/upgrading.md +636 -0
- package/dist/docs/guides/validators.md +217 -0
- package/dist/docs/guides/waiting-room.md +244 -0
- package/dist/docs/index.md +41 -0
- package/dist/docs/recipes/act-on-the-session-from-an-endpoint.md +95 -0
- package/dist/docs/recipes/adapt-a-game-for-walkthroughs.md +133 -0
- package/dist/docs/recipes/adapt-ui-for-observers.md +74 -0
- package/dist/docs/recipes/call-endpoint-from-ui.md +109 -0
- package/dist/docs/recipes/check-a-package-from-a-script.md +117 -0
- package/dist/docs/recipes/create-capability.md +66 -0
- package/dist/docs/recipes/create-endpoint.md +127 -0
- package/dist/docs/recipes/create-engine.md +111 -0
- package/dist/docs/recipes/create-game.md +70 -0
- package/dist/docs/recipes/create-guide.md +75 -0
- package/dist/docs/recipes/create-hook.md +80 -0
- package/dist/docs/recipes/create-presentation.md +142 -0
- package/dist/docs/recipes/create-scenario-editor.md +102 -0
- package/dist/docs/recipes/create-scenario.md +98 -0
- package/dist/docs/recipes/create-session-ui.md +116 -0
- package/dist/docs/recipes/create-settings.md +88 -0
- package/dist/docs/recipes/create-setup.md +115 -0
- package/dist/docs/recipes/create-tick-controller.md +65 -0
- package/dist/docs/recipes/create-user-interface.md +96 -0
- package/dist/docs/recipes/create-validator.md +67 -0
- package/dist/docs/recipes/create-waiting-room-ui.md +109 -0
- package/dist/docs/recipes/declare-api-uses.md +67 -0
- package/dist/docs/recipes/design-state-for-concurrent-writes.md +96 -0
- package/dist/docs/recipes/distribute-package.md +80 -0
- package/dist/docs/recipes/e2e-testing.md +116 -0
- package/dist/docs/recipes/end-game-on-condition.md +154 -0
- package/dist/docs/recipes/fix-duplicate-packages.md +101 -0
- package/dist/docs/recipes/index.md +86 -0
- package/dist/docs/recipes/make-an-endpoint-external.md +101 -0
- package/dist/docs/recipes/negotiate-across-teams.md +164 -0
- package/dist/docs/recipes/observe-other-teams-state.md +119 -0
- package/dist/docs/recipes/publish-a-package.md +139 -0
- package/dist/docs/recipes/remember-a-viewers-choice.md +55 -0
- package/dist/docs/recipes/review-a-past-day.md +73 -0
- package/dist/docs/recipes/share-assets-across-scenarios.md +120 -0
- package/dist/docs/recipes/share-logic-between-engine-and-ui.md +130 -0
- package/dist/docs/recipes/show-all-teams-participants.md +109 -0
- package/dist/docs/recipes/start-from-an-empty-package.md +169 -0
- package/dist/docs/recipes/take-a-file-in-an-endpoint.md +82 -0
- package/dist/docs/recipes/test-a-multi-role-game.md +51 -0
- package/dist/docs/recipes/test-user-interface.md +95 -0
- package/dist/docs/recipes/test-with-engine.md +115 -0
- package/dist/docs/recipes/upload-and-display-files.md +148 -0
- package/dist/docs/recipes/use-request-play.md +65 -0
- package/dist/docs/recipes/use-request-tick.md +75 -0
- package/dist/docs/troubleshooting.md +816 -0
- package/dist/execution/blob-inputs.d.ts +57 -0
- package/dist/execution/bundle-reload.d.ts +42 -0
- package/dist/execution/config-resolver.d.ts +127 -0
- package/dist/execution/configuration-builder.d.ts +66 -0
- package/dist/execution/context-composition.d.ts +161 -0
- package/dist/execution/endpoint-actions.d.ts +9 -0
- package/dist/execution/endpoint-payloads.d.ts +32 -0
- package/dist/execution/endpoint-runner.d.ts +129 -0
- package/dist/execution/engine-state.d.ts +40 -0
- package/dist/execution/executor-callbacks.d.ts +56 -0
- package/dist/execution/executor.d.ts +436 -0
- package/dist/execution/gates.d.ts +45 -0
- package/dist/execution/hook-chain.d.ts +25 -0
- package/dist/execution/logic-calls.d.ts +190 -0
- package/dist/execution/logic-failure.d.ts +84 -0
- package/dist/execution/logic-loader.d.ts +54 -0
- package/dist/execution/logic-result.d.ts +76 -0
- package/dist/execution/tick-controller-call.d.ts +32 -0
- package/dist/execution/types.d.ts +48 -0
- package/dist/generation/ts-type.d.ts +39 -0
- package/dist/guide/locale.d.ts +12 -0
- package/dist/guide/video-registry.d.ts +42 -0
- package/dist/help-examples.d.ts +125 -0
- package/dist/host/adapter.d.ts +67 -0
- package/dist/host/host-channel.d.ts +222 -0
- package/dist/host/index.d.ts +20 -0
- package/dist/host/protocol.d.ts +783 -0
- package/dist/host/surfaces.d.ts +42 -0
- package/dist/host/theme.d.ts +55 -0
- package/dist/host.js +583 -0
- package/dist/prompts/index.d.ts +7 -0
- package/dist/prompts/schema-builder.d.ts +29 -0
- package/dist/prompts/types.d.ts +108 -0
- package/dist/prompts/validators.d.ts +32 -0
- package/dist/runtime/capability-scope.d.ts +6 -0
- package/dist/runtime/context-merge.d.ts +29 -0
- package/dist/runtime/context-projection.d.ts +41 -0
- package/dist/runtime/guarded-callbacks.d.ts +15 -0
- package/dist/runtime/index.d.ts +27 -0
- package/dist/runtime/manifest-version.d.ts +55 -0
- package/dist/runtime/tick-validation.d.ts +25 -0
- package/dist/runtime.js +346 -0
- package/dist/schema.json +1546 -0
- package/dist/server/vite-plugin.d.ts +46 -0
- package/dist/services/tts/client.d.ts +51 -0
- package/dist/services/tts/elevenlabs.d.ts +24 -0
- package/dist/services/tts/types.d.ts +44 -0
- package/dist/storage/asset-resolver.d.ts +49 -0
- package/dist/storage/blob-store.d.ts +41 -0
- package/dist/templates/endpoint/logic.test.ts.liquid +61 -0
- package/dist/templates/endpoint/logic.ts.liquid +25 -0
- package/dist/templates/engine/init.json.liquid +7 -0
- package/dist/templates/engine/logic-aggregate.test.ts.liquid +90 -0
- package/dist/templates/engine/logic-aggregate.ts.liquid +46 -0
- package/dist/templates/engine/logic.test.ts.liquid +61 -0
- package/dist/templates/engine/logic.ts.liquid +32 -0
- package/dist/templates/engine/run.json.liquid +7 -0
- package/dist/templates/guide/01-at-a-glance.md.liquid +19 -0
- package/dist/templates/guide/02-preparation.md.liquid +18 -0
- package/dist/templates/guide/03-running-the-session.md.liquid +37 -0
- package/dist/templates/hook/logic.test.ts.liquid +46 -0
- package/dist/templates/hook/logic.ts.liquid +12 -0
- package/dist/templates/package/CLAUDE.md.template +338 -0
- package/dist/templates/package/DESIGN.md.liquid +144 -0
- package/dist/templates/package/README.md.liquid +143 -0
- package/dist/templates/package/claude/rules/workflow-create-capability.md +26 -0
- package/dist/templates/package/claude/rules/workflow-create-endpoint.md +35 -0
- package/dist/templates/package/claude/rules/workflow-create-engine.md +35 -0
- package/dist/templates/package/claude/rules/workflow-create-guide.md +40 -0
- package/dist/templates/package/claude/rules/workflow-create-presentation.md +37 -0
- package/dist/templates/package/claude/rules/workflow-create-user-interface.md +31 -0
- package/dist/templates/package/claude/rules/workflow-publish-package.md +54 -0
- package/dist/templates/package/claude/rules/workflow-test-engine-or-ui.md +30 -0
- package/dist/templates/package/claude/rules/workflow-update-sdk-version.md +43 -0
- package/dist/templates/package/claude/settings.json.template +16 -0
- package/dist/templates/package/gitignore.template +15 -0
- package/dist/templates/package/global-setup.ts.template +21 -0
- package/dist/templates/package/globals.d.ts.template +2 -0
- package/dist/templates/package/oxfmtrc.json.template +14 -0
- package/dist/templates/package/oxlintrc.json.template +238 -0
- package/dist/templates/package/package.json.liquid +65 -0
- package/dist/templates/package/playwright.config.ts.liquid +19 -0
- package/dist/templates/package/pnpm-workspace.yaml.template +27 -0
- package/dist/templates/package/test-setup.ts.liquid +7 -0
- package/dist/templates/package/tsconfig.json.liquid +15 -0
- package/dist/templates/package/vite.config.ts.liquid +19 -0
- package/dist/templates/package/vitest.config.ts.liquid +25 -0
- package/dist/templates/package/vitest.engine.config.ts.liquid +12 -0
- package/dist/templates/presentation/index.html.liquid +20 -0
- package/dist/templates/presentation/src/App.tsx.liquid +49 -0
- package/dist/templates/presentation/src/Slides.tsx.liquid +81 -0
- package/dist/templates/presentation/src/i18n.ts.liquid +54 -0
- package/dist/templates/presentation/src/main.tsx.liquid +14 -0
- package/dist/templates/scenario_editor/src/App.test.tsx.liquid +30 -0
- package/dist/templates/scenario_editor/src/App.tsx.liquid +95 -0
- package/dist/templates/scenario_editor/src/i18n.ts.liquid +44 -0
- package/dist/templates/session/src/App.test.tsx.liquid +60 -0
- package/dist/templates/session/src/App.tsx.liquid +128 -0
- package/dist/templates/session/src/i18n.ts.liquid +53 -0
- package/dist/templates/session/src/main.tsx.liquid +48 -0
- package/dist/templates/session/src/theme.ts.liquid +46 -0
- package/dist/templates/settings-editor/index.html.liquid +12 -0
- package/dist/templates/settings-editor/src/main.tsx.liquid +48 -0
- package/dist/templates/settings-editor/src/theme.ts.liquid +24 -0
- package/dist/templates/setup/src/App.test.tsx.liquid +39 -0
- package/dist/templates/setup/src/App.tsx.liquid +102 -0
- package/dist/templates/setup/src/i18n.ts.liquid +47 -0
- package/dist/templates/starter-game/capabilities/briefing/capability.sdk.json +18 -0
- package/dist/templates/starter-game/capabilities/plan/capability.sdk.json +17 -0
- package/dist/templates/starter-game/capabilities/results/capability.sdk.json +61 -0
- package/dist/templates/starter-game/capabilities/roles/capability.sdk.json +17 -0
- package/dist/templates/starter-game/capabilities/weather/capability.sdk.json +23 -0
- package/dist/templates/starter-game/engine/defaults.ts +81 -0
- package/dist/templates/starter-game/engine/engine.sdk.json +12 -0
- package/dist/templates/starter-game/engine/logic.test.ts +221 -0
- package/dist/templates/starter-game/engine/logic.ts +149 -0
- package/dist/templates/starter-game/engine/test-helpers.ts +74 -0
- package/dist/templates/starter-game/engine/types.ts +139 -0
- package/dist/templates/starter-game/guide/content/en/01-at-a-glance.md +51 -0
- package/dist/templates/starter-game/guide/content/en/02-preparation.md +35 -0
- package/dist/templates/starter-game/guide/content/en/03-running-the-day.md +58 -0
- package/dist/templates/starter-game/guide/guide.sdk.json +10 -0
- package/dist/templates/starter-game/guide/guide.test.ts +108 -0
- package/dist/templates/starter-game/hooks/assignproducts/defaults.ts +37 -0
- package/dist/templates/starter-game/hooks/assignproducts/hook.sdk.json +13 -0
- package/dist/templates/starter-game/hooks/assignproducts/logic/logic.test.ts +77 -0
- package/dist/templates/starter-game/hooks/assignproducts/logic/logic.ts +47 -0
- package/dist/templates/starter-game/hooks/assignproducts/types.ts +55 -0
- package/dist/templates/starter-game/package.json +68 -0
- package/dist/templates/starter-game/playwright.config.ts +19 -0
- package/dist/templates/starter-game/scenarios/heatwave/scenario.sdk.json +20 -0
- package/dist/templates/starter-game/scenarios/ordinary_week/scenario.sdk.json +12 -0
- package/dist/templates/starter-game/seriousgaming.sdk.json +23 -0
- package/dist/templates/starter-game/session/defaults.ts +80 -0
- package/dist/templates/starter-game/session/index.html +12 -0
- package/dist/templates/starter-game/session/session.sdk.json +11 -0
- package/dist/templates/starter-game/session/src/App.test.tsx +307 -0
- package/dist/templates/starter-game/session/src/App.tsx +309 -0
- package/dist/templates/starter-game/session/src/Section.tsx +37 -0
- package/dist/templates/starter-game/session/src/TeamDoor.tsx +96 -0
- package/dist/templates/starter-game/session/src/format.ts +8 -0
- package/dist/templates/starter-game/session/src/i18n.ts +51 -0
- package/dist/templates/starter-game/session/src/main.tsx +48 -0
- package/dist/templates/starter-game/session/src/theme.ts +45 -0
- package/dist/templates/starter-game/session/types.ts +135 -0
- package/dist/templates/starter-game/settings/engine/settings.sdk.json +50 -0
- package/dist/templates/starter-game/settings/menu/settings.sdk.json +78 -0
- package/dist/templates/starter-game/settings/session/settings.sdk.json +23 -0
- package/dist/templates/starter-game/settings/ui/settings.sdk.json +25 -0
- package/dist/templates/starter-game/test-setup.ts +7 -0
- package/dist/templates/starter-game/testing/e2e/game.spec.ts +139 -0
- package/dist/templates/starter-game/testing/e2e/global-setup.ts +21 -0
- package/dist/templates/starter-game/testing/engine/game.engine.test.ts +171 -0
- package/dist/templates/starter-game/tsconfig.json +19 -0
- package/dist/templates/starter-game/ui/defaults.ts +60 -0
- package/dist/templates/starter-game/ui/index.html +12 -0
- package/dist/templates/starter-game/ui/src/App.test.tsx +138 -0
- package/dist/templates/starter-game/ui/src/App.tsx +175 -0
- package/dist/templates/starter-game/ui/src/DayBar.test.tsx +78 -0
- package/dist/templates/starter-game/ui/src/DayBar.tsx +72 -0
- package/dist/templates/starter-game/ui/src/HistoryPanel.test.tsx +74 -0
- package/dist/templates/starter-game/ui/src/HistoryPanel.tsx +120 -0
- package/dist/templates/starter-game/ui/src/MakeRow.tsx +129 -0
- package/dist/templates/starter-game/ui/src/Section.tsx +37 -0
- package/dist/templates/starter-game/ui/src/ThemeToggle.tsx +49 -0
- package/dist/templates/starter-game/ui/src/TodayPanel.test.tsx +179 -0
- package/dist/templates/starter-game/ui/src/TodayPanel.tsx +92 -0
- package/dist/templates/starter-game/ui/src/YesterdayPanel.tsx +142 -0
- package/dist/templates/starter-game/ui/src/format.ts +12 -0
- package/dist/templates/starter-game/ui/src/i18n.ts +95 -0
- package/dist/templates/starter-game/ui/src/main.tsx +48 -0
- package/dist/templates/starter-game/ui/src/menu.ts +18 -0
- package/dist/templates/starter-game/ui/src/test-helpers.ts +58 -0
- package/dist/templates/starter-game/ui/src/theme.ts +45 -0
- package/dist/templates/starter-game/ui/src/writes.ts +43 -0
- package/dist/templates/starter-game/ui/types.ts +137 -0
- package/dist/templates/starter-game/ui/ui.sdk.json +11 -0
- package/dist/templates/starter-game/validators/capacity/defaults.ts +37 -0
- package/dist/templates/starter-game/validators/capacity/logic/logic.test.ts +96 -0
- package/dist/templates/starter-game/validators/capacity/logic/logic.ts +45 -0
- package/dist/templates/starter-game/validators/capacity/types.ts +55 -0
- package/dist/templates/starter-game/validators/capacity/validator.sdk.json +11 -0
- package/dist/templates/starter-game/vite.config.ts +19 -0
- package/dist/templates/starter-game/vitest.config.ts +15 -0
- package/dist/templates/starter-game/vitest.engine.config.ts +19 -0
- package/dist/templates/starter-game/waiting_room/defaults.ts +40 -0
- package/dist/templates/starter-game/waiting_room/index.html +12 -0
- package/dist/templates/starter-game/waiting_room/src/App.test.tsx +102 -0
- package/dist/templates/starter-game/waiting_room/src/App.tsx +194 -0
- package/dist/templates/starter-game/waiting_room/src/i18n.ts +33 -0
- package/dist/templates/starter-game/waiting_room/src/main.tsx +48 -0
- package/dist/templates/starter-game/waiting_room/src/theme.ts +45 -0
- package/dist/templates/starter-game/waiting_room/types.ts +59 -0
- package/dist/templates/starter-game/waiting_room/waiting_room.sdk.json +10 -0
- package/dist/templates/tick-controller/logic.ts.liquid +8 -0
- package/dist/templates/ui/index.html.liquid +12 -0
- package/dist/templates/ui/src/App.test.tsx.liquid +41 -0
- package/dist/templates/ui/src/App.tsx.liquid +103 -0
- package/dist/templates/ui/src/i18n.ts.liquid +47 -0
- package/dist/templates/ui/src/main.tsx.liquid +48 -0
- package/dist/templates/ui/src/theme.ts.liquid +46 -0
- package/dist/templates/validator/logic.test.ts.liquid +42 -0
- package/dist/templates/validator/logic.ts.liquid +21 -0
- package/dist/templates/waiting-room/index.html.liquid +12 -0
- package/dist/templates/waiting-room/src/App.test.tsx.liquid +57 -0
- package/dist/templates/waiting-room/src/App.tsx.liquid +118 -0
- package/dist/templates/waiting-room/src/i18n.ts.liquid +44 -0
- package/dist/templates/waiting-room/src/main.tsx.liquid +48 -0
- package/dist/templates/waiting-room/src/theme.ts.liquid +46 -0
- package/dist/templating/resource-metadata.d.ts +131 -0
- package/dist/types.d.ts +14 -0
- package/dist/utils/atomic-write.d.ts +40 -0
- package/dist/utils/cli-error.d.ts +64 -0
- package/dist/utils/document-parser-client.d.ts +20 -0
- package/dist/utils/env-loader.d.ts +40 -0
- package/dist/utils/error-codes.d.ts +335 -0
- package/dist/utils/errors.d.ts +19 -0
- package/dist/utils/global-settings.d.ts +65 -0
- package/dist/utils/llm-client.d.ts +34 -0
- package/dist/utils/logger.d.ts +36 -0
- package/dist/utils/output.d.ts +109 -0
- package/dist/utils/platform.d.ts +14 -0
- package/dist/utils/prompt.d.ts +36 -0
- package/dist/utils/real-path.d.ts +6 -0
- package/dist/utils/schema-properties.d.ts +35 -0
- package/dist/validation/ajv.d.ts +17 -0
- package/dist/validation/facilitator-guide-validator.d.ts +27 -0
- package/dist/validation/findings.d.ts +40 -0
- package/dist/validation/game-constraints.d.ts +10 -0
- package/dist/validation/game-validator.d.ts +34 -0
- package/dist/validation/package-validation.d.ts +41 -0
- package/dist/validation/package-validator.d.ts +19 -0
- package/dist/validation/resource-validator.d.ts +79 -0
- package/dist/validation/schema-defaults-validator.d.ts +29 -0
- package/dist/validation/schema-validation.d.ts +115 -0
- package/dist/validation/semver.d.ts +9 -0
- package/package.json +122 -3
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Create an engine
|
|
2
|
+
|
|
3
|
+
Write the engine that moves the game on each tick: here, one that reads a price and writes the day's revenue.
|
|
4
|
+
|
|
5
|
+
**Keywords:** create engine, new engine, engine example, add engine, simple engine, update engine, Init, Run
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- A capability to read (here `pricing`, with `BasePrice`) and one to write (here `sales`, with `Revenue` and `DailySales`); see [Create a capability](create-capability.md)
|
|
10
|
+
- A settings resource for the engine's parameters (here `demand`, with `DailyUnitsSold`); see [Create settings](create-settings.md)
|
|
11
|
+
- `seriousgaming.sdk.json` in your working directory
|
|
12
|
+
|
|
13
|
+
## Steps
|
|
14
|
+
|
|
15
|
+
1. Declare what the engine reads, writes, and takes as settings. A game holds one engine, in the `engine/` slot, and the starter game already has it, so in a package made with `new package` update it:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm run sdk update engine --patch '[
|
|
19
|
+
{ "op": "replace", "path": "/definition/reads", "value": ["pricing"] },
|
|
20
|
+
{ "op": "replace", "path": "/definition/writes", "value": ["sales"] },
|
|
21
|
+
{ "op": "replace", "path": "/definition/settings", "value": ["demand"] }
|
|
22
|
+
]'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
In a package made with `new package --empty`, create it:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm run sdk new engine '{
|
|
29
|
+
"definition": {
|
|
30
|
+
"reads": ["pricing"],
|
|
31
|
+
"writes": ["sales"],
|
|
32
|
+
"settings": ["demand"]
|
|
33
|
+
},
|
|
34
|
+
"logic": { "directory": ".", "entrypoint": "logic.ts" },
|
|
35
|
+
"rootDirectory": "."
|
|
36
|
+
}'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Either command regenerates `engine/types.ts`. `update engine` leaves `engine/logic.ts` alone.
|
|
40
|
+
|
|
41
|
+
2. Write `Init` and `Run` in `engine/logic.ts`. Each returns what it writes under `capabilities`, spreading rather than mutating:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { InitializationFunction, RunFunction } from '@seriousgaming/sdk';
|
|
45
|
+
|
|
46
|
+
import type { Callbacks, Context, Settings } from './types';
|
|
47
|
+
|
|
48
|
+
export const Init: InitializationFunction<Context, Settings, Callbacks> = async ({
|
|
49
|
+
context,
|
|
50
|
+
settings,
|
|
51
|
+
}) => ({
|
|
52
|
+
capabilities: {
|
|
53
|
+
...context,
|
|
54
|
+
sales: { ...context.sales, Revenue: 0, DailySales: settings.demand.DailyUnitsSold },
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const Run: RunFunction<Context, Settings, Callbacks> = async ({
|
|
59
|
+
context,
|
|
60
|
+
settings,
|
|
61
|
+
}) => ({
|
|
62
|
+
capabilities: {
|
|
63
|
+
...context,
|
|
64
|
+
sales: {
|
|
65
|
+
...context.sales,
|
|
66
|
+
Revenue: context.pricing.BasePrice * context.sales.DailySales,
|
|
67
|
+
DailySales: settings.demand.DailyUnitsSold,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
3. If you replaced the starter game's engine, replace or delete `engine/logic.test.ts` and the starter's other engine files, which test the old logic.
|
|
74
|
+
|
|
75
|
+
4. In a package made with `--empty`, set how long the game runs (the starter already sets `maxTicks`):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm run sdk update package --patch '[{ "op": "add", "path": "/maxTicks", "value": 10 }]'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
5. Build:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm run build
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Verify
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm run sdk init
|
|
91
|
+
pnpm run sdk tick
|
|
92
|
+
pnpm run sdk view
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`sales.Revenue` is `BasePrice` times the previous day's `DailySales`, and `sales.DailySales` is the `demand` setting.
|
|
96
|
+
|
|
97
|
+
## Troubleshooting
|
|
98
|
+
|
|
99
|
+
| Problem | Solution |
|
|
100
|
+
| --------------------------------------- | --------------------------------------------------------------- |
|
|
101
|
+
| `new engine` refuses: the game has one | Use `update engine` (step 1) |
|
|
102
|
+
| `context.pricing` is a type error | Add `pricing` to `reads`; the command regenerates `types.ts` |
|
|
103
|
+
| `settings.demand` is undefined | List `demand` in the engine's `settings` |
|
|
104
|
+
| The tick fails with a flat-result error | Return the new state under `capabilities`, not at the top level |
|
|
105
|
+
| The engine's write is refused | The engine returned a capability outside its `writes` |
|
|
106
|
+
|
|
107
|
+
## Related
|
|
108
|
+
|
|
109
|
+
- [Engine guide](../guides/engine.md): the model, results, memory between ticks, aggregate engines, and the language environment
|
|
110
|
+
- [Test a whole game in-process](test-with-engine.md)
|
|
111
|
+
- [Create a user interface](create-user-interface.md)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Shape your game
|
|
2
|
+
|
|
3
|
+
Set what your package's game is: its name in each locale, how long it runs, and its teams.
|
|
4
|
+
|
|
5
|
+
**Keywords:** create game, new game, game definition, game setup, game manifest, seriousgaming.sdk.json, ticks, teams, locales, update package
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- A package (see [Getting started](../getting-started.md)). A package is a game: there is no `new game`, and the game runs whatever resources sit beside its manifest
|
|
10
|
+
- `seriousgaming.sdk.json` in your working directory
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
1. Name the game in each locale it supports. Patch the field rather than replacing the manifest, so the fields you do not name stay as they are:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm run sdk update package --patch '[
|
|
18
|
+
{ "op": "replace", "path": "/locales/en/name", "value": "Retail Simulation" }
|
|
19
|
+
]'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. Set how many ticks the game runs, one per meaningful period or phase:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm run sdk update package --patch '[{ "op": "add", "path": "/maxTicks", "value": 12 }]'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For a game that ends on a goal rather than a count, see [End a game when a condition is met](end-game-on-condition.md). Do not set a large `maxTicks` 'just in case', and do not keep a tick number, a status, or a phase in context: the SDK tracks them.
|
|
29
|
+
|
|
30
|
+
3. Set the teams: the interaction mode and how many teams a session may have:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm run sdk update package --patch '[
|
|
34
|
+
{ "op": "add", "path": "/teams", "value": { "mode": "independent", "min": 1, "max": 8 } }
|
|
35
|
+
]'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
See [Play modes](../guides/multi-team-games.md#play-modes) for `independent` and `shared-state`.
|
|
39
|
+
|
|
40
|
+
4. Build:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pnpm run build
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Verify
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm run sdk init
|
|
50
|
+
pnpm run sdk tick
|
|
51
|
+
pnpm run sdk view
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`init` runs the engine's `Init`, and `view` shows `completedTicks: 1` after one tick. To play with different settings without changing their defaults, see [Overriding settings from the CLI](../guides/settings.md#from-the-cli).
|
|
55
|
+
|
|
56
|
+
## Troubleshooting
|
|
57
|
+
|
|
58
|
+
| Problem | Solution |
|
|
59
|
+
| ----------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
60
|
+
| The build reports no engine | Check `engine/engine.sdk.json` exists |
|
|
61
|
+
| The build warns that only the engine can end the game | There is no `maxTicks`; expected for a goal-based game |
|
|
62
|
+
| A patch fails on a missing path | Use `add` for a field the manifest does not have yet, `replace` for one it has |
|
|
63
|
+
| Detailed errors | Run `pnpm run sdk build --validate-only --json` |
|
|
64
|
+
|
|
65
|
+
## Related
|
|
66
|
+
|
|
67
|
+
- [Games guide](../guides/games.md): the manifest, host controls, and goal-based games
|
|
68
|
+
- [Create settings](create-settings.md)
|
|
69
|
+
- [Create a setup screen](create-setup.md)
|
|
70
|
+
- [Drive a game from the CLI](../cli-simulation-testing.md)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Create a facilitator guide
|
|
2
|
+
|
|
3
|
+
Bundle a facilitator guide with your game: markdown chapters shown on the facilitator's page.
|
|
4
|
+
|
|
5
|
+
**Keywords:** create facilitator guide, new facilitator guide, cheat sheet, run sheet, facilitation notes, session script, markdown guide, say do timing
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- A package with `seriousgaming.sdk.json` in your working directory
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Declare the guide's locales and titles. A game holds at most one guide, in the `guide/` slot, and the starter game already fills it, so in a package made with `new package` update it:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm run sdk update guide --patch '[
|
|
17
|
+
{ "op": "add", "path": "/definition/locales/de", "value": { "name": "Moderationsleitfaden" } }
|
|
18
|
+
]'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
In a package without one, create it, which scaffolds a chapter skeleton for every locale:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm run sdk new guide '{
|
|
25
|
+
"definition": {
|
|
26
|
+
"locales": {
|
|
27
|
+
"en": { "name": "Facilitator guide" },
|
|
28
|
+
"de": { "name": "Moderationsleitfaden" }
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"rootDirectory": "."
|
|
32
|
+
}'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
2. Write the chapters as markdown files in `guide/content/<locale>/`, ordered by file name, with the same file names in every locale (`01-at-a-glance.md`, `02-preparation.md`, and so on).
|
|
36
|
+
|
|
37
|
+
3. Mark the live script with admonitions:
|
|
38
|
+
|
|
39
|
+
```markdown
|
|
40
|
+
:::say
|
|
41
|
+
Welcome everyone. Today you are running a company for three simulated years.
|
|
42
|
+
:::
|
|
43
|
+
|
|
44
|
+
:::do
|
|
45
|
+
Form the teams and hand each team its device.
|
|
46
|
+
:::
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`timing`, `note`, `warning`, and `tip` work the same way. See [Content rules](../guides/guide.md#content-rules) for headings, images, and video blocks.
|
|
50
|
+
|
|
51
|
+
4. Put images in `guide/assets/` and reference them relatively from a chapter: ``.
|
|
52
|
+
|
|
53
|
+
## Verify
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pnpm run sdk build --validate-only
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Validation warns when a locale is missing a chapter the reference locale has, and fails on a malformed video block or an image that does not resolve. Then open `/guide` in the dev server: the page has its own locale picker and a print button.
|
|
60
|
+
|
|
61
|
+
## Troubleshooting
|
|
62
|
+
|
|
63
|
+
| Problem | Solution |
|
|
64
|
+
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
65
|
+
| `new guide` fails with `RESOURCE_EXISTS` | The slot is filled: use `update guide` and edit the chapters, or `pnpm run sdk delete guide --yes` first |
|
|
66
|
+
| A chapter shows a 'not yet translated' note | That file is missing from the selected locale's directory; content falls back per file to the reference locale |
|
|
67
|
+
| A video renders an error block | The provider must be `youtube` and the id an 11-character YouTube id |
|
|
68
|
+
| An image does not display | The path must resolve inside `guide/`, for example `../../assets/diagram.png` from a chapter |
|
|
69
|
+
| Raw HTML appears as text | By design: the renderer escapes HTML. Use markdown, admonitions, and video blocks |
|
|
70
|
+
|
|
71
|
+
## Related
|
|
72
|
+
|
|
73
|
+
- [Facilitator guides](../guides/guide.md): writing guidance and the full content format
|
|
74
|
+
- [Create a presentation](create-presentation.md)
|
|
75
|
+
- [Internationalisation](../guides/internationalization.md)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Create a hook
|
|
2
|
+
|
|
3
|
+
React to a lifecycle signal, such as a participant joining a team, outside the tick loop.
|
|
4
|
+
|
|
5
|
+
**Keywords:** create hook, new hook, lifecycle hook, participant join, participant move, out-of-tick
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- A capability for the hook to write (here `roles`, with an `Assignments` map keyed by participant id); see [Create a capability](create-capability.md)
|
|
10
|
+
- `seriousgaming.sdk.json` in your working directory
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
1. Create the hook, naming its signal and what it reads and writes:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm run sdk new hook '{
|
|
18
|
+
"definition": {
|
|
19
|
+
"identifier": "assignroles",
|
|
20
|
+
"signal": "participantJoin",
|
|
21
|
+
"reads": ["roles"],
|
|
22
|
+
"writes": ["roles"]
|
|
23
|
+
},
|
|
24
|
+
"logic": { "directory": "logic", "entrypoint": "logic.ts" },
|
|
25
|
+
"rootDirectory": "."
|
|
26
|
+
}'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This writes `hooks/assignroles/` with `hook.sdk.json`, `logic/logic.ts`, and a generated `types.ts` that pins the signal and its payload. The directory is the whole of the wiring.
|
|
30
|
+
|
|
31
|
+
2. Write `Run` in `hooks/assignroles/logic/logic.ts`, returning what it writes under `capabilities`:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import type { HookFunction } from '../types';
|
|
35
|
+
|
|
36
|
+
export const Run: HookFunction = async ({ context, participant }) => ({
|
|
37
|
+
capabilities: {
|
|
38
|
+
...context,
|
|
39
|
+
roles: {
|
|
40
|
+
...context.roles,
|
|
41
|
+
Assignments: {
|
|
42
|
+
...context.roles.Assignments,
|
|
43
|
+
[participant.id]: context.roles.Assignments[participant.id] ?? 'observer',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
3. If several hooks subscribe to the same signal and order matters, number their directories: they run in directory-name order.
|
|
51
|
+
|
|
52
|
+
4. Build:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm run build
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Verify
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pnpm run sdk participant add Alice --team 1
|
|
62
|
+
pnpm run sdk view
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Adding a participant fires `participantJoin`, and the team's `roles.Assignments` holds an entry for the new participant.
|
|
66
|
+
|
|
67
|
+
## Troubleshooting
|
|
68
|
+
|
|
69
|
+
| Problem | Solution |
|
|
70
|
+
| ------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
71
|
+
| The hook never fires | Check `hooks/<identifier>/hook.sdk.json` exists and `signal` is spelled as a signal name |
|
|
72
|
+
| `context.roles` is a type error | Add `roles` to the hook's `reads`; a hook is handed only what it declares |
|
|
73
|
+
| The write is refused | The hook returned a capability outside its `writes` |
|
|
74
|
+
| `participant` is undefined | The hook is bound to a signal whose payload has no `participant`; check `signal` |
|
|
75
|
+
|
|
76
|
+
## Related
|
|
77
|
+
|
|
78
|
+
- [Hooks guide](../guides/hooks.md): signals and payloads, ordering, settings, and testing
|
|
79
|
+
- [Create a validator](create-validator.md)
|
|
80
|
+
- [Test a whole game in-process](test-with-engine.md)
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Create a presentation
|
|
2
|
+
|
|
3
|
+
Ship the facilitator's slide deck with the game, so the briefing, the round dividers, the debriefs and the results travel with the package rather than in an email after train the trainer.
|
|
4
|
+
|
|
5
|
+
**Keywords:** presentation, slides, slide deck, deck, briefing, debrief, results slide, PowerPoint, PDF export, facilitator slides, usePresentation, @seriousgaming/deck
|
|
6
|
+
|
|
7
|
+
## What you'll build
|
|
8
|
+
|
|
9
|
+
A presentation in the `presentation/` slot that:
|
|
10
|
+
|
|
11
|
+
- Opens with a title slide, an agenda revealed one point per click, and a results slide
|
|
12
|
+
- Renders with no session at all, showing labelled sample figures in place of results
|
|
13
|
+
- Shows every team's results once a session is running
|
|
14
|
+
- Exports to PDF, editable PowerPoint and PNG from its own controls
|
|
15
|
+
|
|
16
|
+
A game holds at most one presentation. It is read-only: it reads every team's state, but writes nothing and calls no endpoint. Only the facilitator sees it, and the room sees it because the facilitator shares or projects their screen. See the [presentation guide](../guides/presentation.md) for the full picture.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- A game to attach the deck to; see [Shape your game](create-game.md)
|
|
21
|
+
- `@seriousgaming/deck` in your `package.json`, at the same version as the SDK. A newly scaffolded package already has it; an older one adds it:
|
|
22
|
+
```bash
|
|
23
|
+
pnpm add @seriousgaming/deck@<your SDK version>
|
|
24
|
+
```
|
|
25
|
+
- `seriousgaming.sdk.json` in your working directory
|
|
26
|
+
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
### 1. Create the presentation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pnpm run sdk new presentation '{
|
|
33
|
+
"definition": {
|
|
34
|
+
"reads": ["results"],
|
|
35
|
+
"settings": ["engine"]
|
|
36
|
+
},
|
|
37
|
+
"rootDirectory": ".",
|
|
38
|
+
"ui": {
|
|
39
|
+
"entrypoint": "index.html"
|
|
40
|
+
}
|
|
41
|
+
}'
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`reads` names the capabilities the deck shows, from every team. `settings` names the settings resources it varies on. Neither `writes`, `uses` nor `endpoints` is accepted. This creates:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
presentation/
|
|
48
|
+
├── presentation.sdk.json
|
|
49
|
+
├── index.html
|
|
50
|
+
├── types.ts
|
|
51
|
+
└── src/
|
|
52
|
+
├── main.tsx
|
|
53
|
+
├── App.tsx
|
|
54
|
+
├── Slides.tsx
|
|
55
|
+
└── i18n.ts
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Write the slides
|
|
59
|
+
|
|
60
|
+
`presentation/src/Slides.tsx` returns an array, and every element of it is one slide. Use the deck's building blocks for anything a facilitator might want to edit after exporting (see [Habits that keep an export faithful](../guides/presentation.md#habits-that-keep-an-export-faithful)):
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { Bullets, Heading, Slide, Table, Text } from '@seriousgaming/deck';
|
|
64
|
+
|
|
65
|
+
import type { PresentationSession } from '../types';
|
|
66
|
+
|
|
67
|
+
export function slides({ session }: { session: PresentationSession | null }) {
|
|
68
|
+
return [
|
|
69
|
+
<Slide key="agenda" transition="slide" notes="Reveal each point in turn.">
|
|
70
|
+
<div style={{ padding: '120px 140px' }}>
|
|
71
|
+
<Heading>Today</Heading>
|
|
72
|
+
<Bullets stepped items={['Meet your team', 'Play the rounds', 'Review together']} />
|
|
73
|
+
</div>
|
|
74
|
+
</Slide>,
|
|
75
|
+
|
|
76
|
+
<Slide key="results" transition="rise">
|
|
77
|
+
<div style={{ padding: '120px 140px' }}>
|
|
78
|
+
<Heading>Results</Heading>
|
|
79
|
+
{session ? (
|
|
80
|
+
<Table
|
|
81
|
+
columns={['Team', 'Round']}
|
|
82
|
+
align={['start', 'end']}
|
|
83
|
+
rows={session.teams.map((team) => [
|
|
84
|
+
team.name,
|
|
85
|
+
session.data.teams[team.teamId]?.completedTicks ?? 0,
|
|
86
|
+
])}
|
|
87
|
+
/>
|
|
88
|
+
) : (
|
|
89
|
+
<Text>Sample data: results appear here once the session has started</Text>
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
</Slide>,
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- Give every slide a `key`. The deck remembers the slide a facilitator was on by that name, so a slide that comes and goes with a setting does not shift them onto the wrong one
|
|
98
|
+
- `stepped` on `Bullets` reveals one item per click. Wrap anything else in `<Step at={n}>` to do the same
|
|
99
|
+
- `notes` go to nobody on screen and into PowerPoint's notes pane on export
|
|
100
|
+
|
|
101
|
+
### 3. Make it work with no session
|
|
102
|
+
|
|
103
|
+
`session` is `null` whenever the deck is shown outside a session: in a game's library, while a facilitator rehearses, or to export it before the day. Every slide must still make sense then. Where a slide would show results, show sample or placeholder figures and say so on the slide.
|
|
104
|
+
|
|
105
|
+
### 4. Route every word through i18n
|
|
106
|
+
|
|
107
|
+
The scaffold keeps every word in `src/i18n.ts`, in English, Italian and Arabic, and sets the deck's language and direction from `usePresentation().locale`. Add a key there for each new word, and a translation for each locale the game supports, rather than writing words into a slide.
|
|
108
|
+
|
|
109
|
+
### 5. Build
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pnpm run build
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Verify
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pnpm run sdk dev
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Open http://localhost:3000/presentation for the deck during the session, or http://localhost:3000/presentation?preview for the deck as it looks with no session. Then:
|
|
122
|
+
|
|
123
|
+
- Press the right arrow, space or page down to advance, O for the overview, and F for fullscreen
|
|
124
|
+
- Move the pointer to show the controls, and use **Export** to download a PDF, a PowerPoint file and a PNG of the current slide
|
|
125
|
+
- Open the PowerPoint file and check that headings, bullets and tables are editable text
|
|
126
|
+
|
|
127
|
+
## Troubleshooting
|
|
128
|
+
|
|
129
|
+
| Problem | Solution |
|
|
130
|
+
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
131
|
+
| `Cannot find module '@seriousgaming/deck'` | Add the deck package at the SDK's version (see prerequisites), then `pnpm install` |
|
|
132
|
+
| The whole deck is one slide | The slides are wrapped in a component of your own. Return them as an array, or make each component render one `Slide` |
|
|
133
|
+
| The deck shows blank or broken with `?preview` | A slide reads `session` without checking for `null` |
|
|
134
|
+
| `data` is empty for a team | Add the capability to the presentation's `reads`, then run `pnpm run sdk generate` |
|
|
135
|
+
| An export differs from the screen | See [Habits that keep an export faithful](../guides/presentation.md#habits-that-keep-an-export-faithful) |
|
|
136
|
+
| The deck shows the wrong slides for a scenario | Branch on settings and scenario assets, never on `game.scenarioName` |
|
|
137
|
+
|
|
138
|
+
## Related
|
|
139
|
+
|
|
140
|
+
- [Presentation guide](../guides/presentation.md): the slot, the deck library, resume and export
|
|
141
|
+
- [Create a facilitator guide](create-guide.md): the run sheet beside the deck
|
|
142
|
+
- [Create a scenario](create-scenario.md): vary the deck through settings and assets
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Create a scenario editor
|
|
2
|
+
|
|
3
|
+
Give people a screen for building new scenarios for your released game, without rebuilding it.
|
|
4
|
+
|
|
5
|
+
**Keywords:** scenario editor, scenario builder, custom scenarios, author scenario, save as scenario, customScenarios, settings editor, configures
|
|
6
|
+
|
|
7
|
+
## What you'll build
|
|
8
|
+
|
|
9
|
+
A scenario editor at `scenario_editor/` that edits the `engine` and `ui` settings. The host offers save-as-scenario from it, never from setup. See the [scenario editor guide](../guides/scenario-editor.md) for when a game needs one.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
- Settings resources for the editor to edit; see [Create a settings resource](create-settings.md)
|
|
14
|
+
- `seriousgaming.sdk.json` in your working directory
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
|
|
18
|
+
### 1. Switch custom scenarios on
|
|
19
|
+
|
|
20
|
+
The editor is optional; this declaration is what lets a hosted runtime save scenarios for the game:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm run sdk update package --patch '[
|
|
24
|
+
{ "op": "add", "path": "/customScenarios", "value": { "supported": true } }
|
|
25
|
+
]'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. Create the slot
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm run sdk new scenario_editor '{
|
|
32
|
+
"definition": {
|
|
33
|
+
"configures": ["engine", "ui"]
|
|
34
|
+
},
|
|
35
|
+
"rootDirectory": ".",
|
|
36
|
+
"ui": { "entrypoint": "index.html" }
|
|
37
|
+
}'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This creates `scenario_editor/` with `scenario_editor.sdk.json`, `index.html`, `src/{main,App,i18n,theme}`, and the generated `types.ts` and `defaults.ts`.
|
|
41
|
+
|
|
42
|
+
### 3. Build the editor
|
|
43
|
+
|
|
44
|
+
Open `scenario_editor/src/App.tsx`. It uses the same hooks as setup:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { useSettingsEditor } from '@seriousgaming/sdk/ui';
|
|
48
|
+
import { Stack, TextField } from '@mui/material';
|
|
49
|
+
import type { Settings } from '../types';
|
|
50
|
+
|
|
51
|
+
function App() {
|
|
52
|
+
const { settings, updateSettings } = useSettingsEditor<Settings>();
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Stack spacing={2}>
|
|
56
|
+
<TextField
|
|
57
|
+
label="Maximum price"
|
|
58
|
+
type="number"
|
|
59
|
+
value={settings.ui.MaxPrice}
|
|
60
|
+
onChange={(e) =>
|
|
61
|
+
void updateSettings({
|
|
62
|
+
ui: { ...settings.ui, MaxPrice: Number(e.target.value) },
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
/>
|
|
66
|
+
</Stack>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default App;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Do not add a save button or call `requestPlay`: the host owns saving, and ignores `requestPlay` from the editor.
|
|
74
|
+
|
|
75
|
+
### 4. Edit a scenario in the dev server
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm run sdk dev
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Open the dev drawer, then **Scenario**, then **Edit** on a scenario (or **Add scenario**). The editor opens on `/scenario-editor`. Change a value and click **Save**.
|
|
82
|
+
|
|
83
|
+
## Verify
|
|
84
|
+
|
|
85
|
+
- [ ] `scenarios/<identifier>/scenario.sdk.json` holds the value you changed, under its settings identifier
|
|
86
|
+
- [ ] Selecting that scenario starts a session with the value
|
|
87
|
+
|
|
88
|
+
## Troubleshooting
|
|
89
|
+
|
|
90
|
+
**Edit opens nothing to edit**
|
|
91
|
+
|
|
92
|
+
The package has no `scenario_editor/scenario_editor.sdk.json`. Without an editor, set values with `pnpm run sdk configure` and add a scenario from the current settings.
|
|
93
|
+
|
|
94
|
+
**An agent cannot tell what a setting means**
|
|
95
|
+
|
|
96
|
+
Describe every property in the settings schema: `title`, `description` with units, `minimum` and `maximum`, and `enum` where the choices are closed. An agent edits a game with no editor UI from those alone.
|
|
97
|
+
|
|
98
|
+
## Related
|
|
99
|
+
|
|
100
|
+
- [Create a setup screen](create-setup.md)
|
|
101
|
+
- [Create a scenario](create-scenario.md)
|
|
102
|
+
- [Scenarios guide](../guides/scenarios.md)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Create a scenario
|
|
2
|
+
|
|
3
|
+
Bundle a game flavour with settings overrides and static assets.
|
|
4
|
+
|
|
5
|
+
**Keywords:** create scenario, new scenario, game variant, game flavour, difficulty preset, storyline, scenario assets
|
|
6
|
+
|
|
7
|
+
## What you'll build
|
|
8
|
+
|
|
9
|
+
A scenario called `hard_mode` that overrides the engine's `demand` settings and includes a briefing PDF.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
- A package with a `demand` settings resource that declares `BaseDemand` and `InflationRate` (see [Create a settings resource](create-settings.md))
|
|
14
|
+
- `seriousgaming.sdk.json` in your working directory
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
|
|
18
|
+
### 1. Create the scenario
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm run sdk new scenario '{
|
|
22
|
+
"definition": {
|
|
23
|
+
"identifier": "hard_mode",
|
|
24
|
+
"locales": {
|
|
25
|
+
"en": {
|
|
26
|
+
"name": "Hard Mode",
|
|
27
|
+
"description": "Higher costs, lower demand"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"settings": {
|
|
31
|
+
"demand": { "BaseDemand": 30, "InflationRate": 0.15 }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"rootDirectory": "."
|
|
35
|
+
}'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Overrides are keyed by settings identifier and are partial: a key you leave out falls through to its default. Every resource that lists `demand` in its `settings` receives the overridden values.
|
|
39
|
+
|
|
40
|
+
### 2. Add assets
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cp briefing.pdf scenarios/hard_mode/assets/shared/
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. Mark it as the default
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm run sdk update scenario hard_mode --patch '[
|
|
50
|
+
{ "op": "add", "path": "/definition/default", "value": true }
|
|
51
|
+
]'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 4. Load assets in a UI
|
|
55
|
+
|
|
56
|
+
Scenario assets are referenced under the `asset:` URI scheme (see [Asset references](../guides/file-handling.md#asset-references)):
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
const { getAssetUrl } = useUserInterfaceCallbacks();
|
|
60
|
+
return <a href={getAssetUrl('asset:shared/briefing.pdf')}>Download briefing</a>;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Verify
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Check the overrides against each settings resource's settingsSchema
|
|
67
|
+
pnpm run sdk build --validate-only
|
|
68
|
+
|
|
69
|
+
# CLI
|
|
70
|
+
pnpm run sdk init --scenario hard_mode
|
|
71
|
+
pnpm run sdk tick
|
|
72
|
+
|
|
73
|
+
# Dev server
|
|
74
|
+
pnpm run sdk dev --scenario hard_mode
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The game should initialise with `BaseDemand: 30` and `InflationRate: 0.15`. A facilitator can still override these values through the game's setup screen: the scenario is a starting point, not a lock.
|
|
78
|
+
|
|
79
|
+
You should now have:
|
|
80
|
+
|
|
81
|
+
- `scenarios/hard_mode/scenario.sdk.json`, the scenario definition
|
|
82
|
+
- `scenarios/hard_mode/assets/shared/briefing.pdf`, the static asset
|
|
83
|
+
|
|
84
|
+
## Troubleshooting
|
|
85
|
+
|
|
86
|
+
| Problem | Solution |
|
|
87
|
+
| ---------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
88
|
+
| Build rejects an override key | The settings resource's `settingsSchema` does not declare it, usually a misspelling |
|
|
89
|
+
| Build rejects a settings identifier | The package holds no settings resource by that name |
|
|
90
|
+
| Override has no effect in the UI | The UI does not list those settings in its `settings` array |
|
|
91
|
+
| Build refuses a default scenario | A restricted scenario cannot also be the default |
|
|
92
|
+
| Facilitator value wins over the scenario | By design: the session overrides a facilitator sets win over scenario values |
|
|
93
|
+
|
|
94
|
+
## Related
|
|
95
|
+
|
|
96
|
+
- [Scenarios guide](../guides/scenarios.md): the model, validation, resolution order, team names and restricted scenarios
|
|
97
|
+
- [Share assets across scenarios](./share-assets-across-scenarios.md)
|
|
98
|
+
- [Create a settings resource](create-settings.md)
|