dreamboard 0.1.21 → 0.1.23
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/dist/{chunk-EYYWGWTO.js → chunk-2RCUHMGL.js} +343 -1911
- package/dist/chunk-2RCUHMGL.js.map +1 -0
- package/dist/{chunk-MOVHYB6E.js → chunk-GN7232BY.js} +1025 -695
- package/dist/chunk-GN7232BY.js.map +1 -0
- package/dist/{chunk-BMYC6772.js → chunk-H3O43F5P.js} +9765 -3068
- package/dist/chunk-H3O43F5P.js.map +1 -0
- package/dist/dev-host/dev-api-proxy-plugin.ts +330 -0
- package/dist/dev-host/dev-diagnostics.ts +62 -0
- package/dist/dev-host/dev-fallback-stylesheet.ts +50 -0
- package/dist/dev-host/dev-host-controller.ts +686 -0
- package/dist/dev-host/dev-host-player-query.ts +17 -0
- package/dist/dev-host/dev-host-session-transport.ts +52 -0
- package/dist/dev-host/dev-host-storage.ts +56 -0
- package/dist/dev-host/dev-log-relay-plugin.ts +469 -0
- package/dist/dev-host/dev-runtime-config.ts +14 -0
- package/dist/dev-host/dev-runtime-platform.ts +419 -0
- package/dist/dev-host/dev-virtual-modules-plugin.ts +63 -0
- package/dist/dev-host/host-main.css +182 -0
- package/dist/dev-host/host-main.tsx +754 -0
- package/dist/dev-host/index.html +56 -0
- package/dist/dev-host/plugin-main.ts +55 -0
- package/dist/dev-host/plugin.html +24 -0
- package/dist/dev-host/start-dev-server.ts +138 -0
- package/dist/dev-host/virtual-modules.d.ts +27 -0
- package/dist/dist-FEPN3BDN.js +16543 -0
- package/dist/dist-FEPN3BDN.js.map +1 -0
- package/dist/{dist-WJRJNFLI.js → dist-FRURQI7Q.js} +4 -2
- package/dist/index.js +3 -3
- package/dist/internal.js +159 -124
- package/dist/internal.js.map +1 -1
- package/dist/runtime-packages/tailwind-config/shared-styles.css +146 -0
- package/dist/runtime-packages/ui/src/components/.gitkeep +0 -0
- package/dist/runtime-packages/ui/src/components/accordion.tsx +66 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/actions.tsx +65 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/artifact.tsx +147 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/branch.tsx +215 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/canvas.tsx +22 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/chain-of-thought.tsx +228 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/code-block.tsx +179 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/confirmation.tsx +158 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/connection.tsx +28 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/context.tsx +408 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/controls.tsx +18 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/conversation.tsx +97 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/edge.tsx +140 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/image.tsx +24 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/inline-citation.tsx +287 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/loader.tsx +96 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/message.tsx +463 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/node.tsx +71 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/open-in-chat.tsx +365 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/panel.tsx +15 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/plan.tsx +142 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/prompt-input.tsx +1380 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/queue.tsx +274 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/reasoning.tsx +182 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/response.tsx +22 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/shimmer.tsx +64 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/sources.tsx +77 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/suggestion.tsx +53 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/task.tsx +87 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/tool.tsx +165 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/toolbar.tsx +16 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/web-preview.tsx +263 -0
- package/dist/runtime-packages/ui/src/components/alert-dialog.tsx +157 -0
- package/dist/runtime-packages/ui/src/components/alert.tsx +66 -0
- package/dist/runtime-packages/ui/src/components/avatar.tsx +53 -0
- package/dist/runtime-packages/ui/src/components/badge.tsx +46 -0
- package/dist/runtime-packages/ui/src/components/button-group.tsx +83 -0
- package/dist/runtime-packages/ui/src/components/button.tsx +65 -0
- package/dist/runtime-packages/ui/src/components/card.tsx +92 -0
- package/dist/runtime-packages/ui/src/components/carousel.tsx +241 -0
- package/dist/runtime-packages/ui/src/components/collapsible.tsx +33 -0
- package/dist/runtime-packages/ui/src/components/command.tsx +184 -0
- package/dist/runtime-packages/ui/src/components/context-menu.tsx +252 -0
- package/dist/runtime-packages/ui/src/components/counter.tsx +11 -0
- package/dist/runtime-packages/ui/src/components/dialog.tsx +146 -0
- package/dist/runtime-packages/ui/src/components/drawer.tsx +132 -0
- package/dist/runtime-packages/ui/src/components/dropdown-menu.tsx +257 -0
- package/dist/runtime-packages/ui/src/components/form.tsx +168 -0
- package/dist/runtime-packages/ui/src/components/header.tsx +13 -0
- package/dist/runtime-packages/ui/src/components/hover-card.tsx +44 -0
- package/dist/runtime-packages/ui/src/components/input-group.tsx +178 -0
- package/dist/runtime-packages/ui/src/components/input.tsx +21 -0
- package/dist/runtime-packages/ui/src/components/item.tsx +193 -0
- package/dist/runtime-packages/ui/src/components/label.tsx +24 -0
- package/dist/runtime-packages/ui/src/components/navigation-menu.tsx +168 -0
- package/dist/runtime-packages/ui/src/components/popover.tsx +55 -0
- package/dist/runtime-packages/ui/src/components/progress.tsx +31 -0
- package/dist/runtime-packages/ui/src/components/radio-group.tsx +45 -0
- package/dist/runtime-packages/ui/src/components/resizable.tsx +56 -0
- package/dist/runtime-packages/ui/src/components/scroll-area.tsx +58 -0
- package/dist/runtime-packages/ui/src/components/select.tsx +187 -0
- package/dist/runtime-packages/ui/src/components/separator.tsx +28 -0
- package/dist/runtime-packages/ui/src/components/skeleton.tsx +13 -0
- package/dist/runtime-packages/ui/src/components/sonner.tsx +25 -0
- package/dist/runtime-packages/ui/src/components/spinner.tsx +16 -0
- package/dist/runtime-packages/ui/src/components/switch.tsx +31 -0
- package/dist/runtime-packages/ui/src/components/table.tsx +137 -0
- package/dist/runtime-packages/ui/src/components/tabs.tsx +74 -0
- package/dist/runtime-packages/ui/src/components/textarea.tsx +23 -0
- package/dist/runtime-packages/ui/src/components/theme-provider.tsx +73 -0
- package/dist/runtime-packages/ui/src/components/tooltip.tsx +61 -0
- package/dist/runtime-packages/ui/src/components/ui/file-upload.tsx +195 -0
- package/dist/runtime-packages/ui/src/hooks/.gitkeep +0 -0
- package/dist/runtime-packages/ui/src/index.ts +68 -0
- package/dist/runtime-packages/ui/src/lib/utils.ts +6 -0
- package/dist/runtime-packages/ui-host-runtime/src/actor-principal.ts +68 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-controls.tsx +359 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback-toaster.tsx +274 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback.tsx +214 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-session-metadata.tsx +135 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/index.ts +5 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/perf-overlay.tsx +194 -0
- package/dist/runtime-packages/ui-host-runtime/src/host-controls.tsx +1 -0
- package/dist/runtime-packages/ui-host-runtime/src/host-feedback.tsx +1 -0
- package/dist/runtime-packages/ui-host-runtime/src/host-session-transport.ts +162 -0
- package/dist/runtime-packages/ui-host-runtime/src/index.ts +2 -0
- package/dist/runtime-packages/ui-host-runtime/src/logger.ts +11 -0
- package/dist/runtime-packages/ui-host-runtime/src/perf.ts +253 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-bridge.ts +195 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-health-check.ts +138 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-messages.ts +159 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-session-gateway.ts +524 -0
- package/dist/runtime-packages/ui-host-runtime/src/runtime/index.ts +12 -0
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/projection-to-snapshot.ts +122 -0
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/static-store-api.ts +26 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress-controller.ts +477 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress.ts +209 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-live-runtime.ts +112 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-model.ts +318 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-projection.ts +211 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-state-reducer.ts +814 -0
- package/dist/runtime-packages/ui-host-runtime/src/sse-manager.ts +334 -0
- package/dist/runtime-packages/ui-host-runtime/src/unified-session-store.ts +180 -0
- package/dist/scaffold/assets/static/app/tsconfig.framework.json +3 -1
- package/dist/scaffold/assets/static/ui/tsconfig.framework.json +7 -19
- package/package.json +52 -17
- package/skills/dreamboard/SKILL.md +41 -75
- package/LICENSE +0 -89
- package/NOTICE +0 -1
- package/dist/chunk-BMYC6772.js.map +0 -1
- package/dist/chunk-EYYWGWTO.js.map +0 -1
- package/dist/chunk-MOVHYB6E.js.map +0 -1
- package/dist/scaffold/assets/static/ui/App.tsx +0 -22
- package/dist/src-CUL7EGGG.js +0 -634
- package/dist/src-CUL7EGGG.js.map +0 -1
- package/skills/dreamboard/references/authoring-lifecycle.md +0 -102
- package/skills/dreamboard/references/board-surfaces.md +0 -36
- package/skills/dreamboard/references/board-topology.md +0 -443
- package/skills/dreamboard/references/boards-and-topology.md +0 -100
- package/skills/dreamboard/references/card-actions.md +0 -107
- package/skills/dreamboard/references/cli.md +0 -120
- package/skills/dreamboard/references/core-concepts.md +0 -514
- package/skills/dreamboard/references/custom-renderers.md +0 -26
- package/skills/dreamboard/references/derived-values.md +0 -55
- package/skills/dreamboard/references/effects.md +0 -111
- package/skills/dreamboard/references/game-contract.md +0 -89
- package/skills/dreamboard/references/game-definition.md +0 -89
- package/skills/dreamboard/references/game-shell.md +0 -80
- package/skills/dreamboard/references/hand-surfaces.md +0 -33
- package/skills/dreamboard/references/index.md +0 -112
- package/skills/dreamboard/references/inputs-and-targets.md +0 -160
- package/skills/dreamboard/references/interactions.md +0 -158
- package/skills/dreamboard/references/manifest-fields.md +0 -137
- package/skills/dreamboard/references/manifest.md +0 -81
- package/skills/dreamboard/references/package-surfaces.md +0 -69
- package/skills/dreamboard/references/phases.md +0 -145
- package/skills/dreamboard/references/prompts-and-choices.md +0 -55
- package/skills/dreamboard/references/quickstart.md +0 -71
- package/skills/dreamboard/references/rule-authoring.md +0 -144
- package/skills/dreamboard/references/setup-bootstrap.md +0 -78
- package/skills/dreamboard/references/stages-and-zones.md +0 -59
- package/skills/dreamboard/references/static-views.md +0 -67
- package/skills/dreamboard/references/table-queries-and-ops.md +0 -103
- package/skills/dreamboard/references/testing-bases.md +0 -147
- package/skills/dreamboard/references/testing-generated-contracts.md +0 -142
- package/skills/dreamboard/references/testing-runtime-assertions.md +0 -124
- package/skills/dreamboard/references/testing-scenarios.md +0 -148
- package/skills/dreamboard/references/testing-ui-tests.md +0 -174
- package/skills/dreamboard/references/testing.md +0 -161
- package/skills/dreamboard/references/ui-architecture.md +0 -137
- package/skills/dreamboard/references/ui-components.md +0 -34
- package/skills/dreamboard/references/views.md +0 -72
- package/skills/dreamboard/references/workspace-layout.md +0 -136
- /package/dist/{dist-WJRJNFLI.js.map → dist-FRURQI7Q.js.map} +0 -0
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Quickstart
|
|
2
|
-
|
|
3
|
-
Install Dreamboard, create a workspace, sync generated contracts, compile, and run locally.
|
|
4
|
-
|
|
5
|
-
## Requirements
|
|
6
|
-
|
|
7
|
-
- Node 20 or newer
|
|
8
|
-
|
|
9
|
-
## Install
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install -g dreamboard
|
|
13
|
-
dreamboard login
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
`dreamboard login` opens a browser for authentication.
|
|
17
|
-
|
|
18
|
-
## Create a workspace
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
dreamboard new my-deck-builder --description "An exciting deck builder for 4 players"
|
|
22
|
-
cd my-deck-builder
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The generated workspace contains generated contracts, a React UI, and reducer-native tests. Read [Workspace layout](./workspace-layout.md) before changing generated files.
|
|
26
|
-
|
|
27
|
-
## Sync generated files
|
|
28
|
-
|
|
29
|
-
Run sync after changing `manifest.ts`, reducer definitions, testing contracts, or scaffold-owned files:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
dreamboard sync
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
`sync` regenerates local contracts from authored source and upload the source files to Dreamboard server for compilation.
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
pnpm install
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Compile
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
dreamboard compile
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Compile runs local checks, builds the reducer bundle, and uploads the compiled artifact to Dreamboard server.
|
|
48
|
-
|
|
49
|
-
## Run locally
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
dreamboard dev
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Starts a local Vite server for playtesting the game. It runs the UI locally but connects to Dreamboard server for streaming game state. Open the printed URL to play the current compiled game.
|
|
56
|
-
|
|
57
|
-
## Add test coverage
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
dreamboard test generate
|
|
61
|
-
dreamboard test run
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
`test generate` writes workspace-specific testing wrappers and generated contracts. `test run` replays scenario files under `test/scenarios`.
|
|
65
|
-
|
|
66
|
-
## Next steps
|
|
67
|
-
|
|
68
|
-
- [Manifest](./manifest.md) explains the static table model.
|
|
69
|
-
- [Game contract](./game-contract.md) explains state and phase names.
|
|
70
|
-
- [Interactions](./interactions.md) explains player commands and prompts.
|
|
71
|
-
- [CLI](./cli.md) is the command reference.
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Rule authoring
|
|
2
|
-
|
|
3
|
-
Reference for authoring Dreamboard rule.md files.
|
|
4
|
-
|
|
5
|
-
`rule.md` is the game-design source of intent for a Dreamboard project. Use it
|
|
6
|
-
to describe the rules in plain language before you commit to reducer state,
|
|
7
|
-
manifest, or UI details.
|
|
8
|
-
|
|
9
|
-
## What `rule.md` is for
|
|
10
|
-
|
|
11
|
-
Use `rule.md` for:
|
|
12
|
-
|
|
13
|
-
- the game objective and match shape
|
|
14
|
-
- setup, turn flow, scoring, and victory rules
|
|
15
|
-
- player actions and their legality constraints
|
|
16
|
-
- visibility rules and information flow
|
|
17
|
-
- edge cases and deterministic tie-break rules
|
|
18
|
-
|
|
19
|
-
## Recommended structure
|
|
20
|
-
|
|
21
|
-
Use the same section order for every `rule.md`.
|
|
22
|
-
|
|
23
|
-
### `Overview`
|
|
24
|
-
|
|
25
|
-
State the core promise of the game in one short section.
|
|
26
|
-
|
|
27
|
-
- supported player count
|
|
28
|
-
- objective
|
|
29
|
-
- expected match length
|
|
30
|
-
- one-paragraph summary of how a turn feels
|
|
31
|
-
|
|
32
|
-
### `Components`
|
|
33
|
-
|
|
34
|
-
List the components the rules assume exist.
|
|
35
|
-
|
|
36
|
-
- cards, zones, boards, pieces, dice, and resources
|
|
37
|
-
- public versus hidden information
|
|
38
|
-
- per-player versus shared components
|
|
39
|
-
- hard limits such as hand size, stock limits, or caps
|
|
40
|
-
|
|
41
|
-
### `Setup`
|
|
42
|
-
|
|
43
|
-
Describe the initial state in ordered steps.
|
|
44
|
-
|
|
45
|
-
- how players are seated
|
|
46
|
-
- which player acts first
|
|
47
|
-
- which components start in which locations
|
|
48
|
-
- any setup options or setup-profile differences
|
|
49
|
-
|
|
50
|
-
### `Gameplay`
|
|
51
|
-
|
|
52
|
-
Describe the game loop in the order the reducer should implement it.
|
|
53
|
-
|
|
54
|
-
For each phase, name:
|
|
55
|
-
|
|
56
|
-
- who is allowed to act
|
|
57
|
-
- which actions are legal
|
|
58
|
-
- what input each action requires
|
|
59
|
-
- what ends the phase
|
|
60
|
-
- which phase follows next
|
|
61
|
-
|
|
62
|
-
When a game has repeated rounds, document the round loop explicitly instead of
|
|
63
|
-
implying it.
|
|
64
|
-
|
|
65
|
-
### `Scoring and progression`
|
|
66
|
-
|
|
67
|
-
Describe how players gain or lose progress.
|
|
68
|
-
|
|
69
|
-
- points, tracks, resources, or thresholds
|
|
70
|
-
- when scoring happens
|
|
71
|
-
- round-end or trick-end resolution
|
|
72
|
-
- tie-breakers for intermediate rankings
|
|
73
|
-
|
|
74
|
-
### `Winning conditions`
|
|
75
|
-
|
|
76
|
-
State the exact end trigger and winner resolution rule.
|
|
77
|
-
|
|
78
|
-
- when the game ends
|
|
79
|
-
- how the winner is chosen
|
|
80
|
-
- how ties are broken
|
|
81
|
-
- what happens if multiple end conditions become true at once
|
|
82
|
-
|
|
83
|
-
### `Special rules and edge cases`
|
|
84
|
-
|
|
85
|
-
List rules that are easy to miss during implementation.
|
|
86
|
-
|
|
87
|
-
- simultaneous actions
|
|
88
|
-
- empty-deck or empty-pool behavior
|
|
89
|
-
- no-op or invalid actions
|
|
90
|
-
- forced actions versus optional actions
|
|
91
|
-
- what happens when a player cannot act
|
|
92
|
-
|
|
93
|
-
## Example template
|
|
94
|
-
|
|
95
|
-
```markdown
|
|
96
|
-
# <Game name>
|
|
97
|
-
|
|
98
|
-
## Overview
|
|
99
|
-
|
|
100
|
-
- Players: <min-max> (optimal: <n>)
|
|
101
|
-
- Objective: <how a player wins>
|
|
102
|
-
- Duration: <target minutes>
|
|
103
|
-
|
|
104
|
-
## Components
|
|
105
|
-
|
|
106
|
-
- Shared components:
|
|
107
|
-
- Per-player components:
|
|
108
|
-
- Public information:
|
|
109
|
-
- Hidden information:
|
|
110
|
-
|
|
111
|
-
## Setup
|
|
112
|
-
|
|
113
|
-
1. ...
|
|
114
|
-
2. ...
|
|
115
|
-
3. ...
|
|
116
|
-
|
|
117
|
-
## Gameplay
|
|
118
|
-
|
|
119
|
-
### Phase 1: <name>
|
|
120
|
-
|
|
121
|
-
- Acting player(s):
|
|
122
|
-
- Allowed actions:
|
|
123
|
-
- Validation:
|
|
124
|
-
- Completion:
|
|
125
|
-
- Next phase:
|
|
126
|
-
|
|
127
|
-
### Phase 2: <name>
|
|
128
|
-
|
|
129
|
-
- ...
|
|
130
|
-
|
|
131
|
-
## Scoring and progression
|
|
132
|
-
|
|
133
|
-
- ...
|
|
134
|
-
|
|
135
|
-
## Winning conditions
|
|
136
|
-
|
|
137
|
-
- End trigger:
|
|
138
|
-
- Winner determination:
|
|
139
|
-
- Tie-breaker:
|
|
140
|
-
|
|
141
|
-
## Special rules and edge cases
|
|
142
|
-
|
|
143
|
-
- ...
|
|
144
|
-
```
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# Setup bootstrap
|
|
2
|
-
|
|
3
|
-
Seed initial table state from setup profiles with typed shuffle, deal, and move steps.
|
|
4
|
-
|
|
5
|
-
Setup bootstrap steps move components into their starting runtime locations before normal phases run. Use them for deterministic setup work that belongs to a setup profile rather than to turn logic.
|
|
6
|
-
|
|
7
|
-
Setup profiles are usually authored through the generated `setupProfiles` helper:
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
import {
|
|
11
|
-
dealToPlayerZone,
|
|
12
|
-
setupProfiles,
|
|
13
|
-
shuffle,
|
|
14
|
-
} from "../shared/manifest-contract";
|
|
15
|
-
|
|
16
|
-
export default setupProfiles({
|
|
17
|
-
"default-setup": {
|
|
18
|
-
initialPhase: "playerTurn",
|
|
19
|
-
bootstrap: [
|
|
20
|
-
shuffle({ type: "sharedZone", zoneId: "draw" }),
|
|
21
|
-
dealToPlayerZone({
|
|
22
|
-
from: { type: "sharedZone", zoneId: "draw" },
|
|
23
|
-
zoneId: "hand",
|
|
24
|
-
count: 5,
|
|
25
|
-
}),
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Step types
|
|
32
|
-
|
|
33
|
-
| Step | Use for |
|
|
34
|
-
| --- | --- |
|
|
35
|
-
| `shuffle` | Shuffle a shared zone or board container during setup. |
|
|
36
|
-
| `deal` | Deal from a shared zone/container to a per-player zone/container. |
|
|
37
|
-
| `move` | Move specific or counted components into zones, board spaces, or board containers. |
|
|
38
|
-
|
|
39
|
-
Generated helpers include:
|
|
40
|
-
|
|
41
|
-
- `shuffle`
|
|
42
|
-
- `dealToPlayerZone`
|
|
43
|
-
- `dealToPlayerBoardContainer`
|
|
44
|
-
- `seedSharedBoardContainer`
|
|
45
|
-
- `seedSharedBoardSpace`
|
|
46
|
-
|
|
47
|
-
These helpers are typed against the manifest, so invalid zone, board, space, container, card, piece, or die ids fail at author time.
|
|
48
|
-
|
|
49
|
-
## Bootstrap vs phase enter
|
|
50
|
-
|
|
51
|
-
Use bootstrap for static setup:
|
|
52
|
-
|
|
53
|
-
- shuffle starting decks
|
|
54
|
-
- deal opening hands
|
|
55
|
-
- place fixed pieces
|
|
56
|
-
- seed shared board spaces or containers
|
|
57
|
-
|
|
58
|
-
Use phase `enter` for dynamic setup:
|
|
59
|
-
|
|
60
|
-
- choose first player from runtime state
|
|
61
|
-
- branch by setup selection
|
|
62
|
-
- compute state fields from player count
|
|
63
|
-
- run setup that depends on reducer logic
|
|
64
|
-
|
|
65
|
-
It is normal to combine both: bootstrap seeds the table, then the first phase initializes active players or public state.
|
|
66
|
-
|
|
67
|
-
## Initial phase
|
|
68
|
-
|
|
69
|
-
A setup profile may override the game definition's `initialPhase`:
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
"short-game": {
|
|
73
|
-
initialPhase: "playerTurn",
|
|
74
|
-
bootstrap: [...],
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Keep `initialPhase` values aligned with `gameContract.phaseNames`.
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# Stages and zones
|
|
2
|
-
|
|
3
|
-
Use stages for phase sub-states and zones for declarative hand rendering.
|
|
4
|
-
|
|
5
|
-
Stages and zones are optional phase-level primitives. Use them when they simplify a phase without creating extra phase names.
|
|
6
|
-
|
|
7
|
-
## Stages
|
|
8
|
-
|
|
9
|
-
Stages are first-match sub-state selectors inside a phase. Declaration order is priority: the first `when` predicate that returns `true` becomes the current stage.
|
|
10
|
-
|
|
11
|
-
```ts
|
|
12
|
-
stages: {
|
|
13
|
-
discard: definePhaseStage<GameContract, typeof phaseState>()({
|
|
14
|
-
when: ({ state }) => state.phase.step === "discard",
|
|
15
|
-
allow: ["discardCards"],
|
|
16
|
-
}),
|
|
17
|
-
main: definePhaseStage<GameContract, typeof phaseState>()({
|
|
18
|
-
when: ({ state }) => state.phase.step === "main",
|
|
19
|
-
allow: ["buildPath", "tradeWithBank", "endTurn"],
|
|
20
|
-
}),
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
`allow` gates which interaction ids are available in that stage.
|
|
25
|
-
|
|
26
|
-
Stages can also use `onEnter` and `onExit` hooks:
|
|
27
|
-
|
|
28
|
-
```ts
|
|
29
|
-
onEnter({ state, accept, ops }) {
|
|
30
|
-
return accept(pipe(state, ops.patchPhaseState({ enteredMain: true })));
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Use stages when one phase has clear internal steps but the surrounding flow is still one conceptual phase.
|
|
35
|
-
|
|
36
|
-
## Zones
|
|
37
|
-
|
|
38
|
-
Zones declare which manifest player card zones are projected for generated
|
|
39
|
-
`Zone` primitives.
|
|
40
|
-
|
|
41
|
-
```ts
|
|
42
|
-
zones: [zones.actionHand],
|
|
43
|
-
cardActions: {
|
|
44
|
-
playBoost,
|
|
45
|
-
playDrawCards,
|
|
46
|
-
playBuildPath,
|
|
47
|
-
},
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Each entry is a manifest player zone id that stores cards. Import `zones` from the generated manifest contract and use handles such as `zones.actionHand` instead of raw string ids. The runtime reads cards from listed zones and derives playable actions from phase `cardActions` whose `playFrom` matches the zone id.
|
|
51
|
-
|
|
52
|
-
The runtime dry-runs each derived card action's validation to determine per-card
|
|
53
|
-
playability for UI primitives.
|
|
54
|
-
|
|
55
|
-
## Zone keys
|
|
56
|
-
|
|
57
|
-
Manifest zone ids often use kebab case, such as `action-hand`. Generated UI contracts expose JS-friendly zone keys such as `actionHand` for surface configuration while preserving the manifest zone id at runtime.
|
|
58
|
-
|
|
59
|
-
Keep the manifest zone id as the source of truth. Do not maintain a parallel UI-only zone id list.
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# Static views
|
|
2
|
-
|
|
3
|
-
Use defineStaticView for immutable session-scoped projection such as decorated board topology.
|
|
4
|
-
|
|
5
|
-
Static views project immutable data once per reducer session. They receive only the manifest and static queries, so they cannot accidentally include per-player or per-turn state.
|
|
6
|
-
|
|
7
|
-
```ts
|
|
8
|
-
export const boardStatic = defineStaticView<GameContract>()({
|
|
9
|
-
project: ({ q }) => {
|
|
10
|
-
const board = q.board.hex("island");
|
|
11
|
-
return {
|
|
12
|
-
...board,
|
|
13
|
-
portsByVertexId: computePorts(board),
|
|
14
|
-
};
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Register it in `defineGame`:
|
|
20
|
-
|
|
21
|
-
```ts
|
|
22
|
-
export default defineGame({
|
|
23
|
-
contract: gameContract,
|
|
24
|
-
phases,
|
|
25
|
-
views: { player: playerView },
|
|
26
|
-
staticView: boardStatic,
|
|
27
|
-
});
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## What belongs in static views
|
|
31
|
-
|
|
32
|
-
Good static-view data:
|
|
33
|
-
|
|
34
|
-
- board topology
|
|
35
|
-
- precomputed board decoration
|
|
36
|
-
- labels and ids derived from manifest literals
|
|
37
|
-
- fixed layout data for UI components
|
|
38
|
-
- static adjacency lookup tables
|
|
39
|
-
|
|
40
|
-
Bad static-view data:
|
|
41
|
-
|
|
42
|
-
- current pieces on spaces
|
|
43
|
-
- active player
|
|
44
|
-
- card locations
|
|
45
|
-
- resource balances
|
|
46
|
-
- prompts or available actions
|
|
47
|
-
- anything dependent on `state`, `playerId`, or `runtime`
|
|
48
|
-
|
|
49
|
-
Those belong in [Views](./views.md), interactions, or table queries.
|
|
50
|
-
|
|
51
|
-
## Static query surface
|
|
52
|
-
|
|
53
|
-
Static views use manifest-backed static queries:
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
const board = q.board.get("map");
|
|
57
|
-
const hex = q.board.hex("island");
|
|
58
|
-
const square = q.board.square("grid");
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Use this instead of rebuilding board topology manually in the workspace.
|
|
62
|
-
|
|
63
|
-
## Why static views matter
|
|
64
|
-
|
|
65
|
-
Large board topology can dominate runtime update payloads if it is projected on every action. Static views move that data into a once-per-session payload and let dynamic views focus on changing state.
|
|
66
|
-
|
|
67
|
-
Keep game-specific decoration local. If the access pattern is broadly reusable, it should become an SDK query instead of repeated workspace code.
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
# Table queries and ops
|
|
2
|
-
|
|
3
|
-
Read runtime table state with q, write with ops, and compose deterministic state transitions with pipe.
|
|
4
|
-
|
|
5
|
-
Reducer callbacks receive two canonical table helpers:
|
|
6
|
-
|
|
7
|
-
- `q` for reads
|
|
8
|
-
- `ops` for writes
|
|
9
|
-
|
|
10
|
-
Use them instead of reading or mutating `state.table` directly.
|
|
11
|
-
|
|
12
|
-
## Read with q
|
|
13
|
-
|
|
14
|
-
`q` is a typed query namespace over the runtime table:
|
|
15
|
-
|
|
16
|
-
```ts
|
|
17
|
-
const playerIds = q.player.order();
|
|
18
|
-
const hand = q.zone.playerCards(playerId, "things-hand");
|
|
19
|
-
const card = q.card.get(cardId);
|
|
20
|
-
const board = q.board.hex("island");
|
|
21
|
-
const vertices = q.board.incidentVertices("island", edgeId);
|
|
22
|
-
const resources = q.player.resources(playerId);
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Common groups:
|
|
26
|
-
|
|
27
|
-
| Namespace | Reads |
|
|
28
|
-
| --- | --- |
|
|
29
|
-
| `q.board.*` | Boards, spaces, containers, edges, vertices, adjacency, occupants. |
|
|
30
|
-
| `q.zone.*` | Shared zones, per-player zones, card collections. |
|
|
31
|
-
| `q.card.*` | Runtime card data, owner, visibility. |
|
|
32
|
-
| `q.component.*` | Component locations. |
|
|
33
|
-
| `q.slot.*` | Slot occupants and slot occupants by host. |
|
|
34
|
-
| `q.player.*` | Player order, next player, resources, affordability. |
|
|
35
|
-
|
|
36
|
-
Prefer `q.card.get(cardId)` over parsing card ids. Runtime card data already includes `cardType`, name, text, and properties.
|
|
37
|
-
|
|
38
|
-
## Write with ops
|
|
39
|
-
|
|
40
|
-
`ops` is a typed namespace of curried state writers. Compose ops with `pipe`:
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
return accept(
|
|
44
|
-
pipe(
|
|
45
|
-
state,
|
|
46
|
-
ops.spendResources({ playerId, amounts: { coin: 2 } }),
|
|
47
|
-
ops.dealCardsToPlayerZone({
|
|
48
|
-
fromZoneId: "market",
|
|
49
|
-
playerId,
|
|
50
|
-
toZoneId: "hand",
|
|
51
|
-
count: 1,
|
|
52
|
-
}),
|
|
53
|
-
ops.patchPhaseState({ step: "main" }),
|
|
54
|
-
),
|
|
55
|
-
);
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Common groups:
|
|
59
|
-
|
|
60
|
-
| Operation family | Examples |
|
|
61
|
-
| --- | --- |
|
|
62
|
-
| Flow | `setActivePlayers`, `advanceActivePlayer`. |
|
|
63
|
-
| Authored state | `patchPublicState`, `patchHiddenState`, `patchPlayerPrivateState`, `patchPhaseState`. |
|
|
64
|
-
| Zones/cards | `addCardToSharedZone`, `moveCardBetweenSharedZones`, `moveCardFromPlayerZoneToSharedZone`, `dealCardsToPlayerZone`. |
|
|
65
|
-
| Board/components | `moveComponentToSpace`, `moveComponentToContainer`, `moveComponentToEdge`, `moveComponentToVertex`. |
|
|
66
|
-
| Resources | `addResources`, `spendResources`, `transferResources`, `setResource`. |
|
|
67
|
-
|
|
68
|
-
Ops preserve the narrowed phase-state type through `pipe`.
|
|
69
|
-
|
|
70
|
-
## Author helper pattern
|
|
71
|
-
|
|
72
|
-
Game-specific helpers should accept `ops` or `q` as arguments:
|
|
73
|
-
|
|
74
|
-
```ts
|
|
75
|
-
export function incrementScore(ops: Ops, playerId: PlayerId): Op<GameState> {
|
|
76
|
-
return ops.patchPublicState((prev) => ({
|
|
77
|
-
...prev,
|
|
78
|
-
scores: {
|
|
79
|
-
...prev.scores,
|
|
80
|
-
[playerId]: (prev.scores[playerId] ?? 0) + 1,
|
|
81
|
-
},
|
|
82
|
-
}));
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
This keeps helper code testable and tied to the same injected runtime surface as reducer callbacks.
|
|
87
|
-
|
|
88
|
-
## Validation before writes
|
|
89
|
-
|
|
90
|
-
Some ops throw if the write is invalid. For example, `ops.spendResources` requires the player to afford the full cost.
|
|
91
|
-
|
|
92
|
-
Check business rules in `validate`:
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
validate({ input, q }) {
|
|
96
|
-
if (!q.player.canAfford(input.playerId, COST)) {
|
|
97
|
-
return { errorCode: "INSUFFICIENT_RESOURCES" };
|
|
98
|
-
}
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Then apply the write in `reduce`.
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# Bases
|
|
2
|
-
|
|
3
|
-
Define reusable starting states for scenario tests.
|
|
4
|
-
|
|
5
|
-
A base is a deterministic starting state for scenarios. It chooses the seed,
|
|
6
|
-
player count, optional setup profile, and setup actions that produce a reusable
|
|
7
|
-
checkpoint.
|
|
8
|
-
|
|
9
|
-
Bases live under `test/bases/*.base.ts` and are generated into
|
|
10
|
-
`test/generated/base-states.generated.ts` by `dreamboard test generate`.
|
|
11
|
-
|
|
12
|
-
## Basic base
|
|
13
|
-
|
|
14
|
-
```ts
|
|
15
|
-
import { defineBase } from "../testing-types";
|
|
16
|
-
|
|
17
|
-
export default defineBase({
|
|
18
|
-
id: "initial-turn",
|
|
19
|
-
seed: 1337,
|
|
20
|
-
players: 4,
|
|
21
|
-
setup: async () => undefined,
|
|
22
|
-
});
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Fields:
|
|
26
|
-
|
|
27
|
-
| Field | Required | Meaning |
|
|
28
|
-
| --- | --- | --- |
|
|
29
|
-
| `id` | Yes | Stable base id used by scenarios. |
|
|
30
|
-
| `seed` | Yes unless inherited | Reducer seed for deterministic randomness. |
|
|
31
|
-
| `players` | Yes unless inherited | Number of seats in the generated base. |
|
|
32
|
-
| `setupProfileId` | No | Manifest setup profile to use before setup actions. |
|
|
33
|
-
| `extends` | No | Parent base id to hydrate before this setup runs. |
|
|
34
|
-
| `setup` | Yes | Async function that prepares the checkpoint. |
|
|
35
|
-
|
|
36
|
-
A base without `extends` must declare both `seed` and `players`.
|
|
37
|
-
|
|
38
|
-
## Setup actions
|
|
39
|
-
|
|
40
|
-
Use `game.submit` with generated interaction ids and typed params:
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
export default defineBase({
|
|
44
|
-
id: "after-first-placement",
|
|
45
|
-
extends: "initial-turn",
|
|
46
|
-
setup: async ({ game, seat }) => {
|
|
47
|
-
await game.submit(seat(1), "placeThingCard", {
|
|
48
|
-
cardId: "a-diamond",
|
|
49
|
-
ringId: "ring-1",
|
|
50
|
-
});
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
`game.submit` runs the same validation and reducer dispatch path as a scenario
|
|
56
|
-
action. If setup fails, generation fails.
|
|
57
|
-
|
|
58
|
-
## Seat helpers
|
|
59
|
-
|
|
60
|
-
Use `seat(index)` for stable player references:
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
const firstPlayer = seat(0);
|
|
64
|
-
const secondPlayer = seat(1);
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
`seat(index)` throws if the base has fewer players than requested. Prefer it to
|
|
68
|
-
literal ids because player id literals are generated from the workspace
|
|
69
|
-
manifest and player count.
|
|
70
|
-
|
|
71
|
-
## Setup profiles
|
|
72
|
-
|
|
73
|
-
Use `setupProfileId` when the manifest has named setup profiles:
|
|
74
|
-
|
|
75
|
-
```ts
|
|
76
|
-
export default defineBase({
|
|
77
|
-
id: "standard-opening",
|
|
78
|
-
seed: 2026,
|
|
79
|
-
players: 4,
|
|
80
|
-
setupProfileId: "standard",
|
|
81
|
-
setup: async () => undefined,
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
When a base extends another base, the setup profile is inherited unless the
|
|
86
|
-
child declares one. A child base cannot change the effective seed, player count,
|
|
87
|
-
or setup profile from its generated parent artifact. If it does, the fingerprint
|
|
88
|
-
check fails and you should model that as a separate root base.
|
|
89
|
-
|
|
90
|
-
## Inherited bases
|
|
91
|
-
|
|
92
|
-
Use `extends` to avoid rebuilding expensive checkpoints in every scenario:
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
export default defineBase({
|
|
96
|
-
id: "after-setup",
|
|
97
|
-
seed: 1337,
|
|
98
|
-
players: 4,
|
|
99
|
-
setup: async ({ game, seat }) => {
|
|
100
|
-
for (const step of SETUP_ORDER) {
|
|
101
|
-
await game.submit(seat(step.seat), "placeSetupMarker", {
|
|
102
|
-
vertexId: step.vertex,
|
|
103
|
-
});
|
|
104
|
-
await game.submit(seat(step.seat), "placeSetupPath", {
|
|
105
|
-
edgeId: step.edge,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
```ts
|
|
113
|
-
export default defineBase({
|
|
114
|
-
id: "pending-trade",
|
|
115
|
-
extends: "after-setup",
|
|
116
|
-
setup: async ({ game, seat }) => {
|
|
117
|
-
await game.submit(seat(0), "rollDice");
|
|
118
|
-
await game.submit(seat(0), "offerTrade", {
|
|
119
|
-
targetPlayerId: seat(1),
|
|
120
|
-
give: { brick: 1 },
|
|
121
|
-
receive: { wool: 1 },
|
|
122
|
-
});
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Generation hydrates the parent snapshot, runs the child setup, and fingerprints
|
|
128
|
-
the parent. If the parent changes, children become stale and must be
|
|
129
|
-
regenerated.
|
|
130
|
-
|
|
131
|
-
## What belongs in a base
|
|
132
|
-
|
|
133
|
-
Good base setup:
|
|
134
|
-
|
|
135
|
-
- opening state
|
|
136
|
-
- post-setup state
|
|
137
|
-
- pending prompt state shared by several scenarios
|
|
138
|
-
- late-game state that would be noisy to replay inline
|
|
139
|
-
|
|
140
|
-
Poor base setup:
|
|
141
|
-
|
|
142
|
-
- a one-off action used by only one scenario
|
|
143
|
-
- assertions
|
|
144
|
-
- full playthroughs that hide the rule being tested
|
|
145
|
-
- local mutation of generated state files
|
|
146
|
-
|
|
147
|
-
Assertions belong in scenarios. Bases create state; scenarios prove behavior.
|