yarn-spinner-runner-ts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +180 -0
- package/dist/compile/compiler.d.ts +9 -0
- package/dist/compile/compiler.js +172 -0
- package/dist/compile/compiler.js.map +1 -0
- package/dist/compile/ir.d.ts +47 -0
- package/dist/compile/ir.js +2 -0
- package/dist/compile/ir.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/model/ast.d.ts +72 -0
- package/dist/model/ast.js +2 -0
- package/dist/model/ast.js.map +1 -0
- package/dist/parse/lexer.d.ts +7 -0
- package/dist/parse/lexer.js +78 -0
- package/dist/parse/lexer.js.map +1 -0
- package/dist/parse/parser.d.ts +4 -0
- package/dist/parse/parser.js +433 -0
- package/dist/parse/parser.js.map +1 -0
- package/dist/runtime/commands.d.ts +31 -0
- package/dist/runtime/commands.js +157 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/evaluator.d.ts +52 -0
- package/dist/runtime/evaluator.js +309 -0
- package/dist/runtime/evaluator.js.map +1 -0
- package/dist/runtime/results.d.ts +22 -0
- package/dist/runtime/results.js +2 -0
- package/dist/runtime/results.js.map +1 -0
- package/dist/runtime/runner.d.ts +63 -0
- package/dist/runtime/runner.js +456 -0
- package/dist/runtime/runner.js.map +1 -0
- package/dist/tests/full_featured.test.d.ts +1 -0
- package/dist/tests/full_featured.test.js +130 -0
- package/dist/tests/full_featured.test.js.map +1 -0
- package/dist/tests/index.test.d.ts +1 -0
- package/dist/tests/index.test.js +30 -0
- package/dist/tests/index.test.js.map +1 -0
- package/dist/tests/jump_detour.test.d.ts +1 -0
- package/dist/tests/jump_detour.test.js +47 -0
- package/dist/tests/jump_detour.test.js.map +1 -0
- package/dist/tests/nodes_lines.test.d.ts +1 -0
- package/dist/tests/nodes_lines.test.js +23 -0
- package/dist/tests/nodes_lines.test.js.map +1 -0
- package/dist/tests/once.test.d.ts +1 -0
- package/dist/tests/once.test.js +29 -0
- package/dist/tests/once.test.js.map +1 -0
- package/dist/tests/options.test.d.ts +1 -0
- package/dist/tests/options.test.js +32 -0
- package/dist/tests/options.test.js.map +1 -0
- package/dist/tests/variables_flow_cmds.test.d.ts +1 -0
- package/dist/tests/variables_flow_cmds.test.js +30 -0
- package/dist/tests/variables_flow_cmds.test.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/commands.md +21 -0
- package/docs/compatibility-checklist.md +77 -0
- package/docs/css-attribute.md +47 -0
- package/docs/detour.md +24 -0
- package/docs/enums.md +25 -0
- package/docs/flow-control.md +25 -0
- package/docs/functions.md +20 -0
- package/docs/jumps.md +24 -0
- package/docs/line-groups.md +21 -0
- package/docs/lines-nodes-and-options.md +30 -0
- package/docs/logic-and-variables.md +25 -0
- package/docs/markup.md +19 -0
- package/docs/node-groups.md +13 -0
- package/docs/once.md +21 -0
- package/docs/options.md +45 -0
- package/docs/saliency.md +25 -0
- package/docs/scenes-actors-setup.md +195 -0
- package/docs/scenes.md +64 -0
- package/docs/shadow-lines.md +18 -0
- package/docs/smart-variables.md +19 -0
- package/docs/storylets-and-saliency-a-primer.md +14 -0
- package/docs/tags-metadata.md +18 -0
- package/eslint.config.cjs +33 -0
- package/examples/browser/README.md +40 -0
- package/examples/browser/index.html +23 -0
- package/examples/browser/main.tsx +16 -0
- package/examples/browser/vite.config.ts +22 -0
- package/examples/react/DialogueExample.tsx +2 -0
- package/examples/react/DialogueView.tsx +2 -0
- package/examples/react/useYarnRunner.tsx +2 -0
- package/examples/scenes/scenes.yaml +10 -0
- package/examples/yarn/full_featured.yarn +43 -0
- package/package.json +55 -0
- package/src/compile/compiler.ts +183 -0
- package/src/compile/ir.ts +28 -0
- package/src/index.ts +17 -0
- package/src/model/ast.ts +93 -0
- package/src/parse/lexer.ts +108 -0
- package/src/parse/parser.ts +435 -0
- package/src/react/DialogueExample.tsx +149 -0
- package/src/react/DialogueScene.tsx +107 -0
- package/src/react/DialogueView.tsx +160 -0
- package/src/react/dialogue.css +181 -0
- package/src/react/useYarnRunner.tsx +33 -0
- package/src/runtime/commands.ts +183 -0
- package/src/runtime/evaluator.ts +327 -0
- package/src/runtime/results.ts +27 -0
- package/src/runtime/runner.ts +480 -0
- package/src/scene/parser.ts +83 -0
- package/src/scene/types.ts +17 -0
- package/src/tests/full_featured.test.ts +131 -0
- package/src/tests/index.test.ts +34 -0
- package/src/tests/jump_detour.test.ts +47 -0
- package/src/tests/nodes_lines.test.ts +27 -0
- package/src/tests/once.test.ts +32 -0
- package/src/tests/options.test.ts +34 -0
- package/src/tests/variables_flow_cmds.test.ts +33 -0
- package/src/types.ts +4 -0
- package/tsconfig.json +21 -0
package/docs/options.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
## Options (Yarn Spinner)
|
|
2
|
+
|
|
3
|
+
Source: [docs.yarnspinner.dev — Options](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/options)
|
|
4
|
+
|
|
5
|
+
### What it covers
|
|
6
|
+
- **Options**: player choices written as lines prefixed with `->`.
|
|
7
|
+
- **Grouping**: options that appear consecutively (uninterrupted by non-indented lines) are delivered together.
|
|
8
|
+
- **Indented content**: lines under an option run only when that option is selected.
|
|
9
|
+
- **Nested options**: options can nest under options.
|
|
10
|
+
|
|
11
|
+
### Basic options
|
|
12
|
+
```yarn
|
|
13
|
+
title: Start
|
|
14
|
+
---
|
|
15
|
+
Navigator: We're arriving before we left.
|
|
16
|
+
-> Captain: Let's alter our trajectory and break this loop!
|
|
17
|
+
-> Captain: We must complete the cycle.
|
|
18
|
+
===
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Options with lines
|
|
22
|
+
```yarn
|
|
23
|
+
title: Start
|
|
24
|
+
---
|
|
25
|
+
-> Captain: Let's alter our trajectory and break this loop!
|
|
26
|
+
Navigator: Risky, Captain.
|
|
27
|
+
-> Captain: We must complete the cycle.
|
|
28
|
+
Navigator: Then we're doomed to repeat this moment.
|
|
29
|
+
===
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Nested options
|
|
33
|
+
```yarn
|
|
34
|
+
title: Start
|
|
35
|
+
---
|
|
36
|
+
-> Captain: Change course!
|
|
37
|
+
Navigator: Understood.
|
|
38
|
+
-> Captain: Do it now!
|
|
39
|
+
Navigator: Aye.
|
|
40
|
+
-> Captain: On second thought...
|
|
41
|
+
Navigator: Standing by.
|
|
42
|
+
===
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
|
package/docs/saliency.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## Saliency (Yarn Spinner)
|
|
2
|
+
|
|
3
|
+
Source: [docs.yarnspinner.dev — Saliency](https://docs.yarnspinner.dev/write-yarn-scripts/advanced-scripting/saliency)
|
|
4
|
+
|
|
5
|
+
### What it covers
|
|
6
|
+
- Mechanisms to score and choose among multiple narrative candidates.
|
|
7
|
+
- Authoring patterns to influence scoring with variables/tags.
|
|
8
|
+
|
|
9
|
+
### Example (conceptual)
|
|
10
|
+
```yarn
|
|
11
|
+
title: Candidate_A
|
|
12
|
+
---
|
|
13
|
+
// Conditions/tags make this salient when player is low health
|
|
14
|
+
Narrator: You look hurt. Rest a moment.
|
|
15
|
+
===
|
|
16
|
+
|
|
17
|
+
title: Candidate_B
|
|
18
|
+
---
|
|
19
|
+
Narrator: The path ahead is clear.
|
|
20
|
+
===
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Selection between candidates is driven by your saliency system configuration.
|
|
24
|
+
|
|
25
|
+
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# Scene and Actor Setup Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to configure scenes and actors for the dialogue system.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Scenes provide visual backgrounds and actor images for dialogue. Actors are characters that appear when they speak. The configuration uses YAML format with two separate sections: `scenes` and `actors`.
|
|
8
|
+
|
|
9
|
+
## Configuration Format
|
|
10
|
+
|
|
11
|
+
Create a YAML file with the following structure:
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
scenes:
|
|
15
|
+
scene1: https://example.com/background1.jpg
|
|
16
|
+
scene2: https://example.com/background2.jpg
|
|
17
|
+
|
|
18
|
+
actors:
|
|
19
|
+
user: https://example.com/user.png
|
|
20
|
+
Narrator: https://example.com/narrator.png
|
|
21
|
+
npc: https://example.com/npc.png
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Scenes
|
|
25
|
+
|
|
26
|
+
### Simple Scene (Background Only)
|
|
27
|
+
|
|
28
|
+
The simplest format is just the background image URL:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
scenes:
|
|
32
|
+
scene1: https://example.com/background1.jpg
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This creates a scene named `scene1` with the specified background. All global actors will be available in this scene.
|
|
36
|
+
|
|
37
|
+
### Scene with Custom Actors
|
|
38
|
+
|
|
39
|
+
You can override global actors per scene:
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
scenes:
|
|
43
|
+
scene1:
|
|
44
|
+
background: https://example.com/background1.jpg
|
|
45
|
+
actors:
|
|
46
|
+
special_npc:
|
|
47
|
+
image: https://example.com/special-npc.png
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This creates `scene1` with a custom background and includes a scene-specific actor `special_npc` in addition to all global actors.
|
|
51
|
+
|
|
52
|
+
### Scene Structure
|
|
53
|
+
|
|
54
|
+
- **scene name** (key): The identifier used in Yarn scripts (e.g., `scene: scene1`)
|
|
55
|
+
- **background** (string): URL or path to the background image
|
|
56
|
+
- **actors** (object, optional): Scene-specific actors that override or extend global actors
|
|
57
|
+
|
|
58
|
+
## Actors
|
|
59
|
+
|
|
60
|
+
### Global Actors
|
|
61
|
+
|
|
62
|
+
Global actors are available in all scenes:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
actors:
|
|
66
|
+
user: https://example.com/user.png
|
|
67
|
+
Narrator: https://example.com/narrator.png
|
|
68
|
+
npc: https://example.com/npc.png
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Actor Configuration
|
|
72
|
+
|
|
73
|
+
Actors can be defined in two ways:
|
|
74
|
+
|
|
75
|
+
**Shorthand** (direct URL):
|
|
76
|
+
```yaml
|
|
77
|
+
actors:
|
|
78
|
+
user: https://example.com/user.png
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Full format** (object):
|
|
82
|
+
```yaml
|
|
83
|
+
actors:
|
|
84
|
+
user:
|
|
85
|
+
image: https://example.com/user.png
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Both formats are equivalent. The object format allows for future extension with additional actor properties.
|
|
89
|
+
|
|
90
|
+
## Using Scenes in Yarn Scripts
|
|
91
|
+
|
|
92
|
+
Add a `scene:` header to any node to activate that scene:
|
|
93
|
+
|
|
94
|
+
```yarn
|
|
95
|
+
title: Start
|
|
96
|
+
scene: scene1
|
|
97
|
+
---
|
|
98
|
+
Narrator: Welcome to the adventure!
|
|
99
|
+
User: Let's begin!
|
|
100
|
+
===
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Scene Persistence
|
|
104
|
+
|
|
105
|
+
Once a scene is set, the background persists across nodes until a new scene is specified. If a node doesn't have a `scene:` header, the previous scene continues to be used.
|
|
106
|
+
|
|
107
|
+
## Actor Display
|
|
108
|
+
|
|
109
|
+
### When Actors Appear
|
|
110
|
+
|
|
111
|
+
- Actors appear only when they are speaking
|
|
112
|
+
- Actor images are matched by name (case-insensitive)
|
|
113
|
+
- The speaking actor's image appears at the top center of the scene
|
|
114
|
+
- If no matching actor is found in the scene configuration, only the text is shown
|
|
115
|
+
|
|
116
|
+
### Actor Matching
|
|
117
|
+
|
|
118
|
+
Actor names in the Yarn script are matched against actor names in the scene configuration:
|
|
119
|
+
|
|
120
|
+
```yarn
|
|
121
|
+
Narrator: This is the narrator speaking.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
This matches an actor named `Narrator`, `narrator`, or any case variation in your scene config.
|
|
125
|
+
|
|
126
|
+
## Example Configuration
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
scenes:
|
|
130
|
+
intro:
|
|
131
|
+
background: /assets/backgrounds/intro.jpg
|
|
132
|
+
forest:
|
|
133
|
+
background: /assets/backgrounds/forest.jpg
|
|
134
|
+
actors:
|
|
135
|
+
guide:
|
|
136
|
+
image: /assets/actors/guide.png
|
|
137
|
+
|
|
138
|
+
actors:
|
|
139
|
+
user: /assets/actors/user.png
|
|
140
|
+
Narrator: /assets/actors/narrator.png
|
|
141
|
+
merchant: /assets/actors/merchant.png
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
In this example:
|
|
145
|
+
- `intro` scene uses the intro background and all global actors (user, Narrator, merchant)
|
|
146
|
+
- `forest` scene uses the forest background, includes all global actors, plus a scene-specific `guide` actor
|
|
147
|
+
|
|
148
|
+
## Yarn Script Example
|
|
149
|
+
|
|
150
|
+
```yarn
|
|
151
|
+
title: Intro
|
|
152
|
+
scene: intro
|
|
153
|
+
---
|
|
154
|
+
Narrator: Welcome to the adventure!
|
|
155
|
+
User: I'm ready to begin!
|
|
156
|
+
===
|
|
157
|
+
|
|
158
|
+
title: Forest
|
|
159
|
+
scene: forest
|
|
160
|
+
---
|
|
161
|
+
Narrator: You enter the mysterious forest.
|
|
162
|
+
Guide: Let me show you the way.
|
|
163
|
+
User: Thank you, guide!
|
|
164
|
+
===
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Image Requirements
|
|
168
|
+
|
|
169
|
+
- **Background images**: Should be high resolution (recommended: 1920x1080 or higher) as they fill the entire scene
|
|
170
|
+
- **Actor images**: Should be transparent PNGs with the character visible in the frame (recommended: 800x1200 or similar portrait aspect)
|
|
171
|
+
- Images can be:
|
|
172
|
+
- Local paths: `/assets/images/character.png`
|
|
173
|
+
- Absolute URLs: `https://example.com/image.jpg`
|
|
174
|
+
- Relative URLs: `../images/background.png`
|
|
175
|
+
|
|
176
|
+
## CSS Styling
|
|
177
|
+
|
|
178
|
+
All dialogue elements use CSS classes prefixed with `yd-` for easy customization:
|
|
179
|
+
|
|
180
|
+
- `.yd-scene` - Scene background container
|
|
181
|
+
- `.yd-actor` - Actor image
|
|
182
|
+
- `.yd-dialogue-box` - Dialogue box container
|
|
183
|
+
- `.yd-text-box` - Text dialogue content
|
|
184
|
+
- `.yd-options-box` - Options container
|
|
185
|
+
|
|
186
|
+
You can override these styles in your own CSS to customize the appearance.
|
|
187
|
+
|
|
188
|
+
## Tips
|
|
189
|
+
|
|
190
|
+
1. **Reuse actors**: Define common actors globally so they're available in all scenes
|
|
191
|
+
2. **Scene-specific actors**: Use scene-specific actors for characters that only appear in certain scenes
|
|
192
|
+
3. **Background persistence**: Scenes persist until changed, so you don't need to repeat `scene:` in every node
|
|
193
|
+
4. **Case sensitivity**: Actor names are matched case-insensitively, but scene names are case-sensitive
|
|
194
|
+
5. **Image loading**: Use optimized images (WebP or compressed PNG/JPG) for better performance
|
|
195
|
+
|
package/docs/scenes.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Scene System
|
|
2
|
+
|
|
3
|
+
The scene system provides visual backgrounds and actor images for dialogue scenes.
|
|
4
|
+
|
|
5
|
+
> 📖 **Detailed Setup Guide**: See [Scenes and Actors Setup](./scenes-actors-setup.md) for complete configuration instructions.
|
|
6
|
+
|
|
7
|
+
## Quick Overview
|
|
8
|
+
|
|
9
|
+
Scenes and actors are configured separately in YAML:
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
scenes:
|
|
13
|
+
scene1: https://example.com/background1.jpg
|
|
14
|
+
|
|
15
|
+
actors:
|
|
16
|
+
user: https://example.com/user.png
|
|
17
|
+
Narrator: https://example.com/narrator.png
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
1. **Background Transitions**: When a scene changes, the background smoothly fades from the old to the new image.
|
|
23
|
+
2. **Persistent Backgrounds**: Once a scene is set, the background persists until a new scene is specified.
|
|
24
|
+
3. **Actor Images**: Only the speaking actor's image appears at the top center of the scene.
|
|
25
|
+
4. **Fallback**: If no scene is specified or an actor has no image, the system falls back to text-only display.
|
|
26
|
+
|
|
27
|
+
## Using Scenes in Yarn Scripts
|
|
28
|
+
|
|
29
|
+
Add a `scene:` header to any node:
|
|
30
|
+
|
|
31
|
+
```yarn
|
|
32
|
+
title: Start
|
|
33
|
+
scene: scene1
|
|
34
|
+
---
|
|
35
|
+
Narrator: Welcome to the adventure!
|
|
36
|
+
User: Let's begin!
|
|
37
|
+
===
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Integration
|
|
41
|
+
|
|
42
|
+
Pass scene configuration to `DialogueView`:
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { DialogueView } from "yarn-spinner-ts";
|
|
46
|
+
import { parseScenes } from "yarn-spinner-ts";
|
|
47
|
+
|
|
48
|
+
const scenes = parseScenes(sceneYamlText);
|
|
49
|
+
|
|
50
|
+
<DialogueView result={result} onAdvance={advance} scenes={scenes} />
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## CSS Classes
|
|
54
|
+
|
|
55
|
+
All dialogue elements use CSS classes prefixed with `yd-`:
|
|
56
|
+
|
|
57
|
+
- `.yd-scene` - Scene background container
|
|
58
|
+
- `.yd-actor` - Actor image (top center)
|
|
59
|
+
- `.yd-dialogue-box` - Dialogue box container
|
|
60
|
+
- `.yd-text-box` - Text dialogue content
|
|
61
|
+
- `.yd-options-box` - Options container
|
|
62
|
+
|
|
63
|
+
Customize these in your CSS to match your game's style.
|
|
64
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Shadow Lines (Yarn Spinner)
|
|
2
|
+
|
|
3
|
+
Source: [docs.yarnspinner.dev — Shadow Lines](https://docs.yarnspinner.dev/write-yarn-scripts/advanced-scripting/shadow-lines)
|
|
4
|
+
|
|
5
|
+
### What it covers
|
|
6
|
+
- Author alternative versions of lines (e.g., localized/variant lines) without changing IDs.
|
|
7
|
+
- Useful for VO/loc updates while preserving references.
|
|
8
|
+
|
|
9
|
+
### Example (conceptual)
|
|
10
|
+
```yarn
|
|
11
|
+
title: Start
|
|
12
|
+
---
|
|
13
|
+
Narrator: Primary line content.
|
|
14
|
+
// Shadow line variants are managed by tooling to swap text without new IDs.
|
|
15
|
+
===
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Smart Variables (Yarn Spinner)
|
|
2
|
+
|
|
3
|
+
Source: [docs.yarnspinner.dev — Smart Variables](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/smart-variables)
|
|
4
|
+
|
|
5
|
+
### What it covers
|
|
6
|
+
- Variables that reference game-side data or computed values.
|
|
7
|
+
- Enable referencing properties without manual syncing.
|
|
8
|
+
|
|
9
|
+
### Example (conceptual)
|
|
10
|
+
```yarn
|
|
11
|
+
title: HUD
|
|
12
|
+
---
|
|
13
|
+
Player: Health is {player.health} and gold is {player.gold}.
|
|
14
|
+
===
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Implementation details depend on the host engine (Unity/Godot/Unreal) binding.
|
|
18
|
+
|
|
19
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Storylets & Saliency — A Primer (Yarn Spinner)
|
|
2
|
+
|
|
3
|
+
Source: [docs.yarnspinner.dev — Storylets & Saliency: A Primer](https://docs.yarnspinner.dev/write-yarn-scripts/advanced-scripting/storylets-and-saliency-a-primer)
|
|
4
|
+
|
|
5
|
+
### What it covers
|
|
6
|
+
- The concept of storylets: small, modular narrative units.
|
|
7
|
+
- **Saliency**: scoring/selecting which content to present next based on context.
|
|
8
|
+
- How these ideas support dynamic narrative selection.
|
|
9
|
+
|
|
10
|
+
### Key ideas
|
|
11
|
+
- Author self-contained nodes with clear entry conditions.
|
|
12
|
+
- Use variables, tags, and conditions to influence selection.
|
|
13
|
+
|
|
14
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Tags & Metadata (Yarn Spinner)
|
|
2
|
+
|
|
3
|
+
Source: [docs.yarnspinner.dev — Tags & Metadata](https://docs.yarnspinner.dev/write-yarn-scripts/advanced-scripting/tags-metadata)
|
|
4
|
+
|
|
5
|
+
### What it covers
|
|
6
|
+
- Attach tags/metadata to lines or nodes for tooling and runtime behavior.
|
|
7
|
+
- Drive VO, animation, or analytics pipelines with tagged content.
|
|
8
|
+
|
|
9
|
+
### Example (conceptual)
|
|
10
|
+
```yarn
|
|
11
|
+
title: Start
|
|
12
|
+
---
|
|
13
|
+
// Tags may be set in headers or editor UIs; usage varies by tooling.
|
|
14
|
+
Narrator: This line might carry a "vo=Line_001" tag.
|
|
15
|
+
===
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// ESLint v9 flat config
|
|
2
|
+
const js = require("@eslint/js");
|
|
3
|
+
const tsParser = require("@typescript-eslint/parser");
|
|
4
|
+
const tsPlugin = require("@typescript-eslint/eslint-plugin");
|
|
5
|
+
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
ignores: ["dist/**", "node_modules/**", "examples/**", "src/examples/**", "src/tests/**"],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
files: ["src/**/*.ts", "src/**/*.tsx"],
|
|
12
|
+
languageOptions: {
|
|
13
|
+
parser: tsParser,
|
|
14
|
+
ecmaVersion: "latest",
|
|
15
|
+
sourceType: "module",
|
|
16
|
+
globals: {
|
|
17
|
+
console: "readonly",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
plugins: {
|
|
21
|
+
"@typescript-eslint": tsPlugin,
|
|
22
|
+
},
|
|
23
|
+
rules: {
|
|
24
|
+
...js.configs.recommended.rules,
|
|
25
|
+
...tsPlugin.configs.recommended.rules,
|
|
26
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
27
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
28
|
+
"no-console": ["warn", { allow: ["warn", "error", "assert", "log"] }],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Browser Demo
|
|
2
|
+
|
|
3
|
+
This is a browser-based demo of the Yarn Spinner dialogue system.
|
|
4
|
+
|
|
5
|
+
## Running the Demo
|
|
6
|
+
|
|
7
|
+
1. Install dependencies (if not already done):
|
|
8
|
+
```bash
|
|
9
|
+
npm install
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
2. Start the development server:
|
|
13
|
+
```bash
|
|
14
|
+
npm run demo
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This will start a Vite dev server at `http://localhost:3000` and open it in your browser.
|
|
18
|
+
|
|
19
|
+
3. Build for production:
|
|
20
|
+
```bash
|
|
21
|
+
npm run demo:build
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The built files will be in `dist-demo/`.
|
|
25
|
+
|
|
26
|
+
## Features Demonstrated
|
|
27
|
+
|
|
28
|
+
- Visual novel-style dialogue UI
|
|
29
|
+
- Click-to-continue text display
|
|
30
|
+
- Interactive option selection
|
|
31
|
+
- CSS styling support for options
|
|
32
|
+
- Speaker names
|
|
33
|
+
- Real-time Yarn script editing
|
|
34
|
+
|
|
35
|
+
## Customization
|
|
36
|
+
|
|
37
|
+
Edit `src/react/DialogueExample.tsx` to change the default Yarn script or customize the UI.
|
|
38
|
+
|
|
39
|
+
Edit `src/react/DialogueView.tsx` to change the dialogue box styling and behavior.
|
|
40
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>NarraLeaf-React Dialogue Demo</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
body {
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<div id="root"></div>
|
|
20
|
+
<script type="module" src="/main.tsx"></script>
|
|
21
|
+
</body>
|
|
22
|
+
</html>
|
|
23
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { DialogueExample } from "../../src/react/DialogueExample.js";
|
|
4
|
+
|
|
5
|
+
const rootEl = document.getElementById("root");
|
|
6
|
+
if (!rootEl) {
|
|
7
|
+
throw new Error("Root element not found");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const root = createRoot(rootEl);
|
|
11
|
+
root.render(
|
|
12
|
+
<React.StrictMode>
|
|
13
|
+
<DialogueExample />
|
|
14
|
+
</React.StrictMode>
|
|
15
|
+
);
|
|
16
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
root: "examples/browser",
|
|
8
|
+
resolve: {
|
|
9
|
+
alias: {
|
|
10
|
+
"yarn-spinner-ts": path.resolve(__dirname, "../src"),
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
build: {
|
|
14
|
+
outDir: "../../dist-demo",
|
|
15
|
+
emptyOutDir: true,
|
|
16
|
+
},
|
|
17
|
+
server: {
|
|
18
|
+
port: 3000,
|
|
19
|
+
open: true,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
title: Start
|
|
2
|
+
---
|
|
3
|
+
<<declare $score = 0>>
|
|
4
|
+
Narrator: Welcome to the comprehensive Yarn test.
|
|
5
|
+
<<set $score = 7>>
|
|
6
|
+
<<if $score > 10>>
|
|
7
|
+
Narrator: High score branch.
|
|
8
|
+
<<elseif $score > 5>>
|
|
9
|
+
Narrator: Medium score branch.
|
|
10
|
+
<<else>>
|
|
11
|
+
Narrator: Low score branch.
|
|
12
|
+
<<endif>>
|
|
13
|
+
|
|
14
|
+
<<once>>
|
|
15
|
+
Narrator: This once block should only appear the first time.
|
|
16
|
+
<<endonce>>
|
|
17
|
+
|
|
18
|
+
-> Take the main path
|
|
19
|
+
Narrator: Proceeding on the main path.
|
|
20
|
+
<<jump NextScene>>
|
|
21
|
+
-> Explore a detour
|
|
22
|
+
Narrator: Let's explore a detour first.
|
|
23
|
+
<<detour AsideInfo>>
|
|
24
|
+
Narrator: Back from detour.
|
|
25
|
+
<<jump NextScene>>
|
|
26
|
+
===
|
|
27
|
+
|
|
28
|
+
title: NextScene
|
|
29
|
+
---
|
|
30
|
+
Narrator: You have arrived in the next scene.
|
|
31
|
+
-> Ask about features
|
|
32
|
+
Player: What can this system do?
|
|
33
|
+
Narrator: It supports options, conditions, once, jump, and detour.
|
|
34
|
+
-> Finish
|
|
35
|
+
Narrator: Ending the scene.
|
|
36
|
+
===
|
|
37
|
+
|
|
38
|
+
title: AsideInfo
|
|
39
|
+
---
|
|
40
|
+
Narrator: This is detour content.
|
|
41
|
+
===
|
|
42
|
+
|
|
43
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yarn-spinner-runner-ts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "TypeScript parser, compiler, and runtime for Yarn Spinner 3.x with React adapter",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/index.cjs",
|
|
9
|
+
"module": "dist/index.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc -p tsconfig.json",
|
|
13
|
+
"clean": "rimraf dist",
|
|
14
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
15
|
+
"lint": "eslint \"src/**/*.ts\" \"src/**/*.tsx\"",
|
|
16
|
+
"pretest": "npm run build",
|
|
17
|
+
"test": "node --test --enable-source-maps \"dist/tests/**/*.test.js\" \"dist/tests/index.test.js\"",
|
|
18
|
+
"demo": "vite --config examples/browser/vite.config.ts --host 0.0.0.0",
|
|
19
|
+
"demo:build": "vite build --config examples/browser/vite.config.ts"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"require": "./dist/index.cjs"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"yarn-spinner",
|
|
30
|
+
"dialogue",
|
|
31
|
+
"parser",
|
|
32
|
+
"compiler",
|
|
33
|
+
"react"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"js-yaml": "^4.1.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^22.7.4",
|
|
40
|
+
"@types/js-yaml": "^4.0.9",
|
|
41
|
+
"@types/react": "^18.3.3",
|
|
42
|
+
"@types/react-dom": "^18.3.0",
|
|
43
|
+
"@eslint/js": "^9.12.0",
|
|
44
|
+
"@typescript-eslint/parser": "^8.8.1",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^8.8.1",
|
|
46
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
47
|
+
"eslint": "^9.12.0",
|
|
48
|
+
"react": "^18.3.1",
|
|
49
|
+
"react-dom": "^18.3.1",
|
|
50
|
+
"rimraf": "^6.0.1",
|
|
51
|
+
"typescript": "^5.6.3",
|
|
52
|
+
"vite": "^5.4.3"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|