@thijshakkenberg/valkyrie-mom-mcp 2.2.0 → 2.3.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/.claude-plugin/plugin.json +1 -1
- package/README.md +24 -4
- package/agents/scenario-designer.md +2 -1
- package/dist/catalogs/extract-catalogs.js +4 -1
- package/dist/catalogs/extract-catalogs.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +28 -0
- package/dist/server.js.map +1 -1
- package/dist/story/story-graph.d.ts +55 -0
- package/dist/story/story-graph.d.ts.map +1 -0
- package/dist/story/story-graph.js +391 -0
- package/dist/story/story-graph.js.map +1 -0
- package/package.json +3 -2
- package/skills/scenario/SKILL.md +1 -0
- package/src/catalogs/extract-catalogs.ts +4 -4
- package/src/server.ts +30 -0
- package/src/story/story-graph.ts +392 -0
package/README.md
CHANGED
|
@@ -53,6 +53,16 @@ Add to your MCP client config (e.g., `~/.claude/mcp.json` or Claude Desktop sett
|
|
|
53
53
|
|
|
54
54
|
This gives you the MCP tools and resources, but not the skills or agent (those require Claude Code).
|
|
55
55
|
|
|
56
|
+
### As a Hermes Agent plugin
|
|
57
|
+
|
|
58
|
+
[Hermes Agent](https://hermes-agent.nousresearch.com/docs/user-guide/features/plugins) installs the repository as a plugin with every tool and all skills:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
hermes plugins install thijs-hakkenberg/ValkyrieMCP --enable
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If Hermes offers to install the plugin's Node dependencies, answer N: they are only needed to develop the plugin. The plugin registers the MCP tools as native Hermes tools (toolset `valkyrie-mom`) and the skills as `valkyrie-mom:<skill>` (e.g. `skill_view("valkyrie-mom:artwork")`). On the first tool call it starts the matching `@thijshakkenberg/valkyrie-mom-mcp` version with `npx` (Node.js 20+ required) and keeps it running for the session, since the scenario being edited lives there. Pictures that tools return, such as `render_map`, are saved under `~/.hermes/cache/valkyrie-mom/` and their paths are given in the result. For a local checkout, set `VALKYRIE_MCP_COMMAND="npx tsx /path/to/ValkyrieMCP/src/index.ts"`.
|
|
65
|
+
|
|
56
66
|
### From source
|
|
57
67
|
|
|
58
68
|
```bash
|
|
@@ -113,6 +123,11 @@ npx tsx src/index.ts # Run MCP server via stdio
|
|
|
113
123
|
| `suggest_tile_layout` | Suggest coordinates for large (7x7) tiles in linear, L-shape, or hub-spoke layouts |
|
|
114
124
|
| `place_tile_relative` | Position and rotation for a new tile against an existing one, with a door lined up |
|
|
115
125
|
|
|
126
|
+
### Story
|
|
127
|
+
| Tool | Description |
|
|
128
|
+
|------|-------------|
|
|
129
|
+
| `story_graph` | Project the storyline as a graph: a condensed text outline (buttons, conditions, effects, placed tokens, puzzles, monster events, endings, never-reached events), Mermaid, or an HTML page with the rendered flowchart |
|
|
130
|
+
|
|
116
131
|
### Artwork
|
|
117
132
|
| Tool | Description |
|
|
118
133
|
|------|-------------|
|
|
@@ -211,24 +226,29 @@ The server validates scenarios against 18 rule categories, checked against Valky
|
|
|
211
226
|
## Development
|
|
212
227
|
|
|
213
228
|
```bash
|
|
214
|
-
npm test
|
|
229
|
+
npm test # Run all tests
|
|
215
230
|
npm run test:watch # Watch mode
|
|
216
231
|
npm run lint # Type check
|
|
217
232
|
npm run build # Compile to dist/
|
|
233
|
+
npm run hermes:tools # Re-export the Hermes plugin tool list after changing tools or the version
|
|
218
234
|
```
|
|
219
235
|
|
|
220
236
|
## Project Structure
|
|
221
237
|
|
|
222
238
|
```
|
|
223
|
-
.claude-plugin/
|
|
224
|
-
|
|
239
|
+
.claude-plugin/ Claude Code plugin manifest
|
|
240
|
+
plugin.yaml Hermes Agent plugin manifest (+ __init__.py entry point)
|
|
241
|
+
hermes_bridge/ Hermes plugin: MCP stdio client, tool registration, exported tools.json
|
|
242
|
+
skills/ 8 skill SKILL.md files (Claude Code and Hermes)
|
|
225
243
|
agents/ Scenario designer agent
|
|
226
244
|
src/
|
|
227
245
|
io/ INI parser/writer, localization CSV, ZIP packager
|
|
228
246
|
model/ ScenarioModel, LocalizationStore, component types
|
|
229
|
-
validation/
|
|
247
|
+
validation/ Rules + orchestrator
|
|
230
248
|
rules/ Individual validation rule implementations
|
|
231
249
|
tools/ MCP tool implementations
|
|
250
|
+
story/ Storyline graph: outline, Mermaid, HTML
|
|
251
|
+
artwork/ ComfyUI (FLUX.2 [klein]) artwork generation
|
|
232
252
|
resources/ Format documentation resources
|
|
233
253
|
catalogs/ 846-entry game content catalog
|
|
234
254
|
diagnostics/ Bug report builder, session trace, ring buffer
|
|
@@ -45,6 +45,7 @@ You are an autonomous Mansions of Madness 2nd Edition scenario designer. You cre
|
|
|
45
45
|
- Set up mythos scaling for tension progression
|
|
46
46
|
- Write atmospheric narrative text in the Lovecraftian horror style
|
|
47
47
|
- Validate scenarios for correctness and completeness
|
|
48
|
+
- Review the storyline as a condensed event tree (`story_graph`) and explain it to the user
|
|
48
49
|
|
|
49
50
|
## Available Skills
|
|
50
51
|
|
|
@@ -112,7 +113,7 @@ Use these skills for detailed pattern guidance:
|
|
|
112
113
|
7. Add spawns with `upsert_spawn`
|
|
113
114
|
8. Configure items with `upsert_item`
|
|
114
115
|
9. Write all narrative with `set_localization`
|
|
115
|
-
10. Validate with `validate_scenario`
|
|
116
|
+
10. Validate with `validate_scenario`, then read the plot back with `story_graph` (outline) to check branches, endings and never-reached events
|
|
116
117
|
11. Save with `save_scenario` (edits stay in memory until saved or built)
|
|
117
118
|
12. Build with `build_scenario`
|
|
118
119
|
|
|
@@ -105,7 +105,10 @@ function generateCatalogSource(catalogs) {
|
|
|
105
105
|
const isMainModule = process.argv[1] && (process.argv[1].endsWith('extract-catalogs.ts') ||
|
|
106
106
|
process.argv[1].endsWith('extract-catalogs.js'));
|
|
107
107
|
if (isMainModule) {
|
|
108
|
-
|
|
108
|
+
// The Valkyrie source checkout, by default next to this repository
|
|
109
|
+
const valkyrieRepo = process.env.VALKYRIE_SOURCE_DIR
|
|
110
|
+
?? path.join(path.dirname(path.dirname(path.dirname(import.meta.dirname ?? '.'))), 'valkyrie');
|
|
111
|
+
const valkyrieContentDir = path.join(valkyrieRepo, 'unity', 'Assets', 'StreamingAssets', 'content', 'MoM');
|
|
109
112
|
if (!fs.existsSync(valkyrieContentDir)) {
|
|
110
113
|
console.error(`Valkyrie content not found at: ${valkyrieContentDir}`);
|
|
111
114
|
console.error('Make sure the Valkyrie repo is cloned at the expected path.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-catalogs.js","sourceRoot":"","sources":["../../src/catalogs/extract-catalogs.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"extract-catalogs.js","sourceRoot":"","sources":["../../src/catalogs/extract-catalogs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C,MAAM,sBAAsB,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAE3F;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAkB,EAClB,IAAiB,EACjB,IAAY;IAEZ,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;YACxB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,KAAK,GAAiB;YAC1B,EAAE;YACF,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACrB,IAAI;YACJ,MAAM;SACP,CAAC;QAEF,uBAAuB;QACvB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,KAAK,MAAM,KAAK,IAAI,sBAAsB,EAAE,CAAC;gBAC3C,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;oBAC9B,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACzB,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AASD,MAAM,kBAAkB,GAAkB;IACxC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE;IACzC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE;IACnC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE;IACpC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE;IACnC,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,cAAc,EAAE;IACnD,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE;IACtC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE;IACrC,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,OAAO,EAAE;IAC3C,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,OAAO,EAAE;CAC/C,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAkB;IAElB,MAAM,MAAM,GAAwC;QAClD,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,EAAE;QACR,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,EAAE;QACR,YAAY,EAAE,EAAE;QAChB,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,EAAE;KACV,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAEvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACnE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,QAA6C;IAC1E,MAAM,KAAK,GAAa;QACtB,gEAAgE;QAChE,0DAA0D;QAC1D,EAAE;KACH,CAAC;IAEF,MAAM,YAAY,GAAgC;QAChD,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,OAAO;QACb,YAAY,EAAE,eAAe;QAC7B,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,QAAQ;KAChB,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAmB,CAAC,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,gBAAgB,UAAU,sBAAsB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;QAChG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,oDAAoD;AAEpD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAChD,CAAC;AAEF,IAAI,YAAY,EAAE,CAAC;IACjB,mEAAmE;IACnE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB;WAC/C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACjG,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAE3G,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,kCAAkC,kBAAkB,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,6BAA6B,kBAAkB,EAAE,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;IAExD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC;QACpD,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAC1B,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC;IAEzC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,EAC1B,sBAAsB,CACvB,CAAC;IACF,MAAM,MAAM,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC/C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,iBAAiB,UAAU,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8EpE,wBAAgB,YAAY,IAAI,SAAS,CAqdxC"}
|
package/dist/server.js
CHANGED
|
@@ -12,6 +12,7 @@ import { getMapAscii, suggestTileLayout, placeTileRelative } from './tools/map.j
|
|
|
12
12
|
import { renderMap } from './map/render.js';
|
|
13
13
|
import { searchGameContent } from './tools/reference.js';
|
|
14
14
|
import { toPackageName, writePackageManifest } from './io/package-manifest.js';
|
|
15
|
+
import { buildStoryGraph, renderMermaid, renderOutline, renderStoryHtml } from './story/story-graph.js';
|
|
15
16
|
import { DEFAULT_COMFYUI_URL, generateArtwork, getArtworkStatus, setupInstructions } from './artwork/comfyui.js';
|
|
16
17
|
import { EVENT_FORMAT_DOC, LOCALIZATION_FORMAT_DOC, COMPONENT_FORMAT_DOC, PATTERN_REFERENCE_DOC, } from './resources/format-docs.js';
|
|
17
18
|
import { SessionTrace } from './diagnostics/session-trace.js';
|
|
@@ -198,6 +199,33 @@ export function createServer() {
|
|
|
198
199
|
],
|
|
199
200
|
};
|
|
200
201
|
});
|
|
202
|
+
server.tool('story_graph', 'Project the scenario\'s storyline as a graph: what each button, trigger, placed token, item inspection and monster event leads to. '
|
|
203
|
+
+ 'format=outline (default) is a condensed text tree: one line per event with its first words, conditions (if ...), effects (variables, +placed/−removed) and END; straight chains stay on one level, decisions indent, repeats point back (↩), and endings and never-reached events are listed. '
|
|
204
|
+
+ 'format=mermaid gives a flowchart definition. outputPath (.html) writes a page with the rendered chart and the outline for people. Use it to review or explain the plot, and to find dead ends and loops', {
|
|
205
|
+
format: z.enum(['outline', 'mermaid']).optional().describe('outline (default) or mermaid'),
|
|
206
|
+
root: z.string().optional().describe('Only the part of the story that follows this component (e.g. EventScream)'),
|
|
207
|
+
maxDepth: z.number().int().optional().describe('Stop expanding below this depth (default 30)'),
|
|
208
|
+
outputPath: z.string().optional().describe('Also write the result, relative to the scenario folder or absolute: .html (chart + outline page), .mmd/.md (Mermaid) or .txt (outline)'),
|
|
209
|
+
}, async ({ format, root, maxDepth, outputPath }) => {
|
|
210
|
+
const model = getModel();
|
|
211
|
+
if (root && !model.get(root))
|
|
212
|
+
throw new Error(`No component named "${root}"`);
|
|
213
|
+
const graph = buildStoryGraph(model);
|
|
214
|
+
const text = format === 'mermaid' ? renderMermaid(graph) : renderOutline(graph, { root, maxDepth });
|
|
215
|
+
let note = '';
|
|
216
|
+
if (outputPath) {
|
|
217
|
+
const file = path.isAbsolute(outputPath) || !model.scenarioDir ? path.resolve(outputPath) : path.join(model.scenarioDir, outputPath);
|
|
218
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
219
|
+
if (/\.html?$/i.test(file))
|
|
220
|
+
fs.writeFileSync(file, renderStoryHtml(graph));
|
|
221
|
+
else if (/\.(mmd|md)$/i.test(file))
|
|
222
|
+
fs.writeFileSync(file, file.endsWith('.md') ? `\`\`\`mermaid\n${renderMermaid(graph)}\n\`\`\`\n` : renderMermaid(graph));
|
|
223
|
+
else
|
|
224
|
+
fs.writeFileSync(file, text);
|
|
225
|
+
note = `\n\nWritten to ${file}`;
|
|
226
|
+
}
|
|
227
|
+
return { content: [{ type: 'text', text: text + note }] };
|
|
228
|
+
});
|
|
201
229
|
// ── Artwork Tools ──
|
|
202
230
|
server.tool('artwork_status', 'Check whether a local ComfyUI server with FLUX.2 [klein] 4B is ready for generate_artwork, and how to set up what is missing (comfy-cli install, launch and model downloads)', { comfyUrl: z.string().optional().describe(`ComfyUI address (default ${DEFAULT_COMFYUI_URL}, or VALKYRIE_COMFYUI_URL)`) }, async ({ comfyUrl }) => {
|
|
203
231
|
const status = await getArtworkStatus(comfyUrl ?? DEFAULT_COMFYUI_URL);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ScenarioModel } from '../model/scenario-model.js';
|
|
2
|
+
/**
|
|
3
|
+
* The storyline as a graph: what runs what, the way Valkyrie plays it. Nodes are components that
|
|
4
|
+
* run (events, puzzles, spawns) or that players click or inspect (tokens, UI buttons, items);
|
|
5
|
+
* edges are buttons, board items placed by `add`, item inspection, monster events and
|
|
6
|
+
* Defeated triggers. Rendered as a condensed outline for authors and agents, or as Mermaid.
|
|
7
|
+
*/
|
|
8
|
+
export type EdgeKind = 'button' | 'places' | 'click' | 'inspect' | 'activation' | 'evade' | 'horror' | 'defeated';
|
|
9
|
+
export interface StoryEdge {
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
kind: EdgeKind;
|
|
13
|
+
/** Button text, or a short description of the connection */
|
|
14
|
+
label: string;
|
|
15
|
+
/** Several targets on one button: Valkyrie runs the first whose conditions pass, or a random one */
|
|
16
|
+
choice?: 'first' | 'random';
|
|
17
|
+
}
|
|
18
|
+
export interface StoryNode {
|
|
19
|
+
name: string;
|
|
20
|
+
kind: 'dialog' | 'hidden' | 'puzzle' | 'spawn' | 'token' | 'ui' | 'item' | 'monster';
|
|
21
|
+
summary: string;
|
|
22
|
+
conditions?: string;
|
|
23
|
+
effects: string[];
|
|
24
|
+
ending?: 'end';
|
|
25
|
+
trigger?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface StoryGraph {
|
|
28
|
+
title: string;
|
|
29
|
+
nodes: Map<string, StoryNode>;
|
|
30
|
+
edges: StoryEdge[];
|
|
31
|
+
/** Entry points: triggers, and items held from the start */
|
|
32
|
+
roots: Array<{
|
|
33
|
+
label: string;
|
|
34
|
+
node: string;
|
|
35
|
+
}>;
|
|
36
|
+
unreachable: string[];
|
|
37
|
+
}
|
|
38
|
+
/** "VarOperation:a,==,1 VarTestsLogicalOperator:AND VarOperation:b,>=,2" → "a==1 AND b>=2" */
|
|
39
|
+
export declare function compactConditions(vartests: string | undefined): string | undefined;
|
|
40
|
+
/** "Suspicion,+,1 $end,=,1" → ["Suspicion+=1", "END"] */
|
|
41
|
+
export declare function compactOperations(ops: string | undefined): string[];
|
|
42
|
+
export declare function buildStoryGraph(model: ScenarioModel): StoryGraph;
|
|
43
|
+
export interface OutlineOptions {
|
|
44
|
+
/** Start from this component instead of the scenario's entry points */
|
|
45
|
+
root?: string;
|
|
46
|
+
/** Stop expanding below this depth (default 30) */
|
|
47
|
+
maxDepth?: number;
|
|
48
|
+
}
|
|
49
|
+
/** Condensed text projection: each component expanded once, later visits point back to it */
|
|
50
|
+
export declare function renderOutline(g: StoryGraph, opts?: OutlineOptions): string;
|
|
51
|
+
/** Mermaid flowchart of the same graph */
|
|
52
|
+
export declare function renderMermaid(g: StoryGraph): string;
|
|
53
|
+
/** Self-contained page: the Mermaid chart (rendered in the browser) above the outline */
|
|
54
|
+
export declare function renderStoryHtml(g: StoryGraph): string;
|
|
55
|
+
//# sourceMappingURL=story-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-graph.d.ts","sourceRoot":"","sources":["../../src/story/story-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE;;;;;GAKG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAElH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,oGAAoG;IACpG,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IACrF,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,4DAA4D;IAC5D,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAmBD,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUlF;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAOnE;AAMD,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CA8IhE;AAgBD,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM,CAkE9E;AAUD,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAkCnD;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAwBrD"}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { parseRefList } from '../model/component-types.js';
|
|
2
|
+
import { computeReachability, isStartingItem } from '../validation/rules/game-flow.js';
|
|
3
|
+
import { checkTrigger } from '../validation/rules/triggers.js';
|
|
4
|
+
const RUNNABLE = ['Event', 'Puzzle', 'Spawn'];
|
|
5
|
+
const isRunnable = (n) => RUNNABLE.some(p => n.startsWith(p));
|
|
6
|
+
/** Localized text as one short line: markup stripped, text codes kept readable */
|
|
7
|
+
function summarize(text, max = 90, loc) {
|
|
8
|
+
if (!text || text.trim() === '.')
|
|
9
|
+
return '';
|
|
10
|
+
const plain = text
|
|
11
|
+
.replace(/^\|\|\|/, '')
|
|
12
|
+
.replace(/<[^>]+>/g, '')
|
|
13
|
+
.replace(/\\n|\n/g, ' ')
|
|
14
|
+
.replace(/\{qst:(\w+)\}/g, (_, k) => loc?.(k) ?? k)
|
|
15
|
+
.replace(/\{(?:c|var):([^}]+)\}/g, '$1')
|
|
16
|
+
.replace(/\s+/g, ' ')
|
|
17
|
+
.trim();
|
|
18
|
+
return plain.length > max ? `${plain.slice(0, max - 1).trimEnd()}…` : plain;
|
|
19
|
+
}
|
|
20
|
+
/** "VarOperation:a,==,1 VarTestsLogicalOperator:AND VarOperation:b,>=,2" → "a==1 AND b>=2" */
|
|
21
|
+
export function compactConditions(vartests) {
|
|
22
|
+
if (!vartests?.trim())
|
|
23
|
+
return undefined;
|
|
24
|
+
const parts = vartests.trim().split(/\s+/).map(t => {
|
|
25
|
+
const op = t.match(/^VarOperation:([^,]+),([^,]+),(.+)$/);
|
|
26
|
+
if (op)
|
|
27
|
+
return `${op[1]}${op[2]}${op[3]}`;
|
|
28
|
+
const logic = t.match(/^VarTestsLogicalOperator:(\w+)$/);
|
|
29
|
+
if (logic)
|
|
30
|
+
return logic[1];
|
|
31
|
+
return t.replace(/^VarTests\w*:/, '');
|
|
32
|
+
});
|
|
33
|
+
return parts.join(' ');
|
|
34
|
+
}
|
|
35
|
+
/** "Suspicion,+,1 $end,=,1" → ["Suspicion+=1", "END"] */
|
|
36
|
+
export function compactOperations(ops) {
|
|
37
|
+
return (ops ?? '').split(/\s+/).filter(Boolean).map(op => {
|
|
38
|
+
const [v, o, x] = op.split(',');
|
|
39
|
+
if (v === '$end' && o === '=' && x !== '0')
|
|
40
|
+
return 'END';
|
|
41
|
+
if (o === '=')
|
|
42
|
+
return `${v}=${x}`;
|
|
43
|
+
return `${v}${o}=${x}`;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function buttonLabel(model, name, i) {
|
|
47
|
+
return summarize(model.localization.get(`${name}.button${i}`), 40, k => model.localization.get(k));
|
|
48
|
+
}
|
|
49
|
+
export function buildStoryGraph(model) {
|
|
50
|
+
const nodes = new Map();
|
|
51
|
+
const edges = [];
|
|
52
|
+
const loc = (k) => model.localization.get(k);
|
|
53
|
+
const ensure = (name) => {
|
|
54
|
+
const existing = nodes.get(name);
|
|
55
|
+
if (existing)
|
|
56
|
+
return existing;
|
|
57
|
+
const comp = model.get(name);
|
|
58
|
+
if (!comp)
|
|
59
|
+
return undefined;
|
|
60
|
+
const d = comp.data;
|
|
61
|
+
let kind;
|
|
62
|
+
if (name.startsWith('Puzzle'))
|
|
63
|
+
kind = 'puzzle';
|
|
64
|
+
else if (name.startsWith('Spawn'))
|
|
65
|
+
kind = 'spawn';
|
|
66
|
+
else if (name.startsWith('Token'))
|
|
67
|
+
kind = 'token';
|
|
68
|
+
else if (name.startsWith('UI'))
|
|
69
|
+
kind = 'ui';
|
|
70
|
+
else if (name.startsWith('QItem'))
|
|
71
|
+
kind = 'item';
|
|
72
|
+
else if (name.startsWith('CustomMonster'))
|
|
73
|
+
kind = 'monster';
|
|
74
|
+
else
|
|
75
|
+
kind = d.display?.toLowerCase() === 'false' ? 'hidden' : 'dialog';
|
|
76
|
+
const effects = compactOperations(d.operations);
|
|
77
|
+
const placed = parseRefList(d.add ?? '');
|
|
78
|
+
const removed = parseRefList(d.remove ?? '');
|
|
79
|
+
if (placed.length)
|
|
80
|
+
effects.push(`+${placed.join(' +')}`);
|
|
81
|
+
if (removed.length)
|
|
82
|
+
effects.push(`−${removed.join(' −')}`);
|
|
83
|
+
if (kind === 'puzzle')
|
|
84
|
+
effects.unshift(`${d.class ?? 'slide'} puzzle ${d.skill ?? '{observation}'}${d.puzzlesolution ? ` = ${d.puzzlesolution}` : ''}`);
|
|
85
|
+
if (kind === 'spawn' && d.monster)
|
|
86
|
+
effects.unshift(`monster ${d.monster}`);
|
|
87
|
+
let summary = summarize(loc(`${name}.text`), 80, loc);
|
|
88
|
+
if (kind === 'spawn')
|
|
89
|
+
summary = summarize(loc(`${name}.uniquetitle`)) || summary;
|
|
90
|
+
if (kind === 'ui')
|
|
91
|
+
summary = summarize(loc(`${name}.uitext`)) || summary;
|
|
92
|
+
if (kind === 'monster')
|
|
93
|
+
summary = summarize(loc(`${name}.monstername`)) || '';
|
|
94
|
+
const node = {
|
|
95
|
+
name, kind, summary, effects,
|
|
96
|
+
conditions: compactConditions(d.vartests),
|
|
97
|
+
ending: effects.includes('END') ? 'end' : undefined,
|
|
98
|
+
trigger: d.trigger?.trim() || undefined,
|
|
99
|
+
};
|
|
100
|
+
nodes.set(name, node);
|
|
101
|
+
return node;
|
|
102
|
+
};
|
|
103
|
+
const visited = new Set();
|
|
104
|
+
const visit = (name) => {
|
|
105
|
+
if (visited.has(name) || !ensure(name))
|
|
106
|
+
return;
|
|
107
|
+
visited.add(name);
|
|
108
|
+
const d = model.get(name).data;
|
|
109
|
+
const buttons = Math.max(parseInt(d.buttons ?? '0', 10) || 0, 1);
|
|
110
|
+
const hidden = nodes.get(name).kind === 'hidden';
|
|
111
|
+
// Buttons (hidden events always follow button 1; tokens and UI run their buttons when clicked)
|
|
112
|
+
for (let i = 1; i <= 6; i++) {
|
|
113
|
+
const targets = parseRefList(d[`event${i}`] ?? '');
|
|
114
|
+
if (targets.length === 0)
|
|
115
|
+
continue;
|
|
116
|
+
if (i > buttons && !name.startsWith('Token'))
|
|
117
|
+
continue;
|
|
118
|
+
const label = hidden ? '' : (buttonLabel(model, name, i) || (buttons > 1 ? `button ${i}` : ''));
|
|
119
|
+
const choice = targets.length > 1 ? (d.randomevents?.toLowerCase() === 'true' ? 'random' : 'first') : undefined;
|
|
120
|
+
for (const t of targets) {
|
|
121
|
+
if (!model.get(t))
|
|
122
|
+
continue;
|
|
123
|
+
edges.push({ from: name, to: t, kind: name.startsWith('Puzzle') ? 'button' : 'button', label, choice });
|
|
124
|
+
visit(t);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Board items and items this component places: clicking or inspecting them continues the story
|
|
128
|
+
for (const ref of parseRefList(d.add ?? '')) {
|
|
129
|
+
const target = model.get(ref);
|
|
130
|
+
if (!target)
|
|
131
|
+
continue;
|
|
132
|
+
const clickable = (ref.startsWith('Token') || ref.startsWith('UI'))
|
|
133
|
+
&& [1, 2, 3, 4, 5, 6].some(i => parseRefList(target.data[`event${i}`] ?? '').length > 0);
|
|
134
|
+
if (clickable) {
|
|
135
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'places' });
|
|
136
|
+
visit(ref);
|
|
137
|
+
}
|
|
138
|
+
else if (ref.startsWith('QItem') && target.data.inspect) {
|
|
139
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'gives' });
|
|
140
|
+
visitItem(ref);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Monster phase, evade and horror events of what this spawn puts on the board
|
|
144
|
+
if (name.startsWith('Spawn')) {
|
|
145
|
+
for (const m of parseRefList(d.monster ?? '')) {
|
|
146
|
+
const cm = model.get(m);
|
|
147
|
+
if (!cm)
|
|
148
|
+
continue;
|
|
149
|
+
const acts = parseRefList(cm.data.activation ?? '').filter(a => a.startsWith('Event'));
|
|
150
|
+
for (const a of acts) {
|
|
151
|
+
edges.push({ from: name, to: a, kind: 'activation', label: 'each monster phase' });
|
|
152
|
+
visit(a);
|
|
153
|
+
}
|
|
154
|
+
for (const [f, kind, label] of [['evadeevent', 'evade', 'on evade'], ['horrorevent', 'horror', 'on horror check']]) {
|
|
155
|
+
if (cm.data[f] && model.get(cm.data[f])) {
|
|
156
|
+
edges.push({ from: name, to: cm.data[f], kind, label });
|
|
157
|
+
visit(cm.data[f]);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const visitItem = (item) => {
|
|
164
|
+
if (visited.has(item) || !ensure(item))
|
|
165
|
+
return;
|
|
166
|
+
visited.add(item);
|
|
167
|
+
for (const e of parseRefList(model.get(item).data.inspect ?? '')) {
|
|
168
|
+
if (!model.get(e))
|
|
169
|
+
continue;
|
|
170
|
+
edges.push({ from: item, to: e, kind: 'inspect', label: 'inspect' });
|
|
171
|
+
visit(e);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
// Entry points: EventStart first, then other triggers, starting items; Defeated triggers hang off their spawn
|
|
175
|
+
const roots = [];
|
|
176
|
+
const defeated = [];
|
|
177
|
+
const triggered = model.getAll().filter(c => c.data.trigger?.trim() && isRunnable(c.name));
|
|
178
|
+
triggered.sort((a, b) => Number(b.data.trigger === 'EventStart') - Number(a.data.trigger === 'EventStart'));
|
|
179
|
+
for (const comp of triggered) {
|
|
180
|
+
const trigger = comp.data.trigger.trim();
|
|
181
|
+
const check = checkTrigger(model, trigger);
|
|
182
|
+
if (!check.ok)
|
|
183
|
+
continue;
|
|
184
|
+
if (check.defeated) {
|
|
185
|
+
defeated.push({ event: comp.name, target: check.defeated });
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
roots.push({ label: trigger === 'EventStart' ? 'Game start' : `Trigger ${trigger}`, node: comp.name });
|
|
189
|
+
}
|
|
190
|
+
for (const r of roots)
|
|
191
|
+
visit(r.node);
|
|
192
|
+
for (const item of model.getByType('QItem')) {
|
|
193
|
+
if (isStartingItem(item.data) && item.data.inspect) {
|
|
194
|
+
roots.push({ label: 'Starting item', node: item.name });
|
|
195
|
+
visitItem(item.name);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Defeated<X>: from each spawn that puts X (or a monster of type X) on the board
|
|
199
|
+
let grew = true;
|
|
200
|
+
while (grew) {
|
|
201
|
+
grew = false;
|
|
202
|
+
for (const t of defeated) {
|
|
203
|
+
const sources = [...nodes.keys()].filter(n => n === t.target
|
|
204
|
+
|| (n.startsWith('Spawn') && parseRefList(model.get(n)?.data.monster ?? '').includes(t.target)));
|
|
205
|
+
for (const s of sources) {
|
|
206
|
+
if (edges.some(e => e.from === s && e.to === t.event))
|
|
207
|
+
continue;
|
|
208
|
+
edges.push({ from: s, to: t.event, kind: 'defeated', label: 'when defeated' });
|
|
209
|
+
if (!visited.has(t.event))
|
|
210
|
+
grew = true;
|
|
211
|
+
visit(t.event);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const { runs } = computeReachability(model);
|
|
216
|
+
const unreachable = model.getAll()
|
|
217
|
+
.filter(c => isRunnable(c.name) && !visited.has(c.name) && !runs.has(c.name))
|
|
218
|
+
.map(c => c.name);
|
|
219
|
+
return { title: loc('quest.name') ?? 'Scenario', nodes, edges, roots, unreachable };
|
|
220
|
+
}
|
|
221
|
+
const ICON = {
|
|
222
|
+
dialog: '▶', hidden: '·', puzzle: '◆', spawn: '☠', token: '⊕', ui: '▣', item: '✉', monster: '☠',
|
|
223
|
+
};
|
|
224
|
+
function nodeLine(n) {
|
|
225
|
+
const parts = [`${ICON[n.kind]} ${n.name}`];
|
|
226
|
+
if (n.conditions)
|
|
227
|
+
parts.push(`if ${n.conditions}`);
|
|
228
|
+
if (n.summary)
|
|
229
|
+
parts.push(`"${n.summary}"`);
|
|
230
|
+
const effects = n.effects.filter(e => e !== 'END');
|
|
231
|
+
if (effects.length)
|
|
232
|
+
parts.push(`⟨${effects.join(', ')}⟩`);
|
|
233
|
+
if (n.ending)
|
|
234
|
+
parts.push('✦ END');
|
|
235
|
+
return parts.join(' ');
|
|
236
|
+
}
|
|
237
|
+
/** Condensed text projection: each component expanded once, later visits point back to it */
|
|
238
|
+
export function renderOutline(g, opts = {}) {
|
|
239
|
+
const maxDepth = opts.maxDepth ?? 30;
|
|
240
|
+
const out = [];
|
|
241
|
+
const printed = new Set();
|
|
242
|
+
const byFrom = new Map();
|
|
243
|
+
for (const e of g.edges)
|
|
244
|
+
byFrom.set(e.from, [...(byFrom.get(e.from) ?? []), e]);
|
|
245
|
+
// Straight chains stay on one level; only decisions (several buttons, choices, placed items) indent
|
|
246
|
+
const walk = (name, depth, indent, lead) => {
|
|
247
|
+
const n = g.nodes.get(name);
|
|
248
|
+
if (!n)
|
|
249
|
+
return;
|
|
250
|
+
if (printed.has(name)) {
|
|
251
|
+
out.push(`${indent}${lead}↩ ${name}`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
printed.add(name);
|
|
255
|
+
out.push(`${indent}${lead}${nodeLine(n)}`);
|
|
256
|
+
// What follows a "• " choice belongs to it, so it lines up under the choice's text
|
|
257
|
+
if (lead === '• ')
|
|
258
|
+
indent += ' ';
|
|
259
|
+
if (depth >= maxDepth) {
|
|
260
|
+
out.push(`${indent} …`);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const groups = new Map();
|
|
264
|
+
for (const e of byFrom.get(name) ?? []) {
|
|
265
|
+
const key = `${e.kind}|${e.label}|${e.choice ?? ''}`;
|
|
266
|
+
groups.set(key, [...(groups.get(key) ?? []), e]);
|
|
267
|
+
}
|
|
268
|
+
const labelOf = (e, many) => {
|
|
269
|
+
let label = e.kind === 'button' ? (e.label ? `[${e.label}]` : '→') : `(${e.label})`;
|
|
270
|
+
if (e.choice && many)
|
|
271
|
+
label += e.choice === 'random' ? ' one at random:' : ' first that passes:';
|
|
272
|
+
return label;
|
|
273
|
+
};
|
|
274
|
+
const list = [...groups.values()];
|
|
275
|
+
if (list.length === 1 && list[0].length === 1) {
|
|
276
|
+
walk(list[0][0].to, depth + 1, indent, `${labelOf(list[0][0], false)} `);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const inner = `${indent} `;
|
|
280
|
+
for (const group of list) {
|
|
281
|
+
if (group.length === 1)
|
|
282
|
+
walk(group[0].to, depth + 1, inner, `${labelOf(group[0], false)} `);
|
|
283
|
+
else {
|
|
284
|
+
out.push(`${inner}${labelOf(group[0], true)}`);
|
|
285
|
+
for (const t of group)
|
|
286
|
+
walk(t.to, depth + 1, `${inner} `, '• ');
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
out.push(`Storyline of "${g.title}": ${[...g.nodes.values()].filter(n => n.kind === 'dialog' || n.kind === 'hidden').length} events, ${g.edges.length} connections`);
|
|
291
|
+
out.push('Legend: ▶ dialog · hidden event ◆ puzzle ☠ spawn/monster ⊕ token ▣ UI button ✉ item [button] → next ↩ already shown above ⟨effects⟩ ✦ END');
|
|
292
|
+
if (opts.root) {
|
|
293
|
+
out.push('');
|
|
294
|
+
walk(opts.root, 0, '', '');
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
for (const r of g.roots) {
|
|
298
|
+
out.push('', `== ${r.label} ==`);
|
|
299
|
+
walk(r.node, 0, '', '');
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (!opts.root) {
|
|
303
|
+
const endings = [...g.nodes.values()].filter(n => n.ending);
|
|
304
|
+
if (endings.length) {
|
|
305
|
+
out.push('', '== Endings ==');
|
|
306
|
+
const parents = (name) => g.edges.filter(e => e.to === name).map(e => e.from);
|
|
307
|
+
for (const n of endings) {
|
|
308
|
+
const via = parents(n.name).map(p => g.nodes.get(p)?.kind === 'hidden' ? parents(p).concat(p) : [p]).flat();
|
|
309
|
+
out.push(`✦ ${n.name}${via.length ? ` ← ${[...new Set(via)].join(', ')}` : ''}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (g.unreachable.length)
|
|
313
|
+
out.push('', '== Never reached ==', g.unreachable.join(', '));
|
|
314
|
+
}
|
|
315
|
+
return out.join('\n');
|
|
316
|
+
}
|
|
317
|
+
function mermaidId(name) {
|
|
318
|
+
return name.replace(/[^A-Za-z0-9_]/g, '_');
|
|
319
|
+
}
|
|
320
|
+
function mermaidText(s) {
|
|
321
|
+
return s.replace(/"/g, "'").replace(/[<>]/g, '').replace(/[[\]{}|]/g, ' ');
|
|
322
|
+
}
|
|
323
|
+
/** Mermaid flowchart of the same graph */
|
|
324
|
+
export function renderMermaid(g) {
|
|
325
|
+
const lines = ['flowchart TD'];
|
|
326
|
+
const shape = (n) => {
|
|
327
|
+
const summary = n.summary ? `<br/><small>${mermaidText(n.summary.slice(0, 48))}</small>` : '';
|
|
328
|
+
const cond = n.conditions ? `<br/><i>if ${mermaidText(n.conditions)}</i>` : '';
|
|
329
|
+
const text = `"${n.name}${cond}${summary}"`;
|
|
330
|
+
switch (n.kind) {
|
|
331
|
+
case 'puzzle': return `{{${text}}}`;
|
|
332
|
+
case 'spawn':
|
|
333
|
+
case 'monster': return `[/${text}/]`;
|
|
334
|
+
case 'token':
|
|
335
|
+
case 'ui':
|
|
336
|
+
case 'item': return `>${text}]`;
|
|
337
|
+
case 'hidden': return `(${text})`;
|
|
338
|
+
default: return n.ending ? `([${text}])` : `[${text}]`;
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
for (const r of g.roots)
|
|
342
|
+
lines.push(` root_${mermaidId(r.node)}(("${mermaidText(r.label)}")) --> ${mermaidId(r.node)}`);
|
|
343
|
+
for (const n of g.nodes.values())
|
|
344
|
+
lines.push(` ${mermaidId(n.name)}${shape(n)}`);
|
|
345
|
+
for (const e of g.edges) {
|
|
346
|
+
const label = e.kind === 'button' ? e.label : e.label;
|
|
347
|
+
const arrow = e.kind === 'button' ? '-->' : '-.->';
|
|
348
|
+
lines.push(` ${mermaidId(e.from)} ${arrow}${label ? `|"${mermaidText(label)}"|` : ''} ${mermaidId(e.to)}`);
|
|
349
|
+
}
|
|
350
|
+
lines.push(' classDef hidden fill:#2a2a33,stroke:#666,color:#bbb,stroke-dasharray:3 3');
|
|
351
|
+
lines.push(' classDef ending fill:#4a1d1d,stroke:#d66,color:#fff');
|
|
352
|
+
lines.push(' classDef puzzle fill:#1d3a4a,stroke:#6bd,color:#fff');
|
|
353
|
+
lines.push(' classDef board fill:#3a341d,stroke:#db6,color:#fff');
|
|
354
|
+
const cls = (k, pred) => {
|
|
355
|
+
const ids = [...g.nodes.values()].filter(pred).map(n => mermaidId(n.name));
|
|
356
|
+
if (ids.length)
|
|
357
|
+
lines.push(` class ${ids.join(',')} ${k}`);
|
|
358
|
+
};
|
|
359
|
+
cls('hidden', n => n.kind === 'hidden' && !n.ending);
|
|
360
|
+
cls('ending', n => !!n.ending);
|
|
361
|
+
cls('puzzle', n => n.kind === 'puzzle');
|
|
362
|
+
cls('board', n => n.kind === 'token' || n.kind === 'ui' || n.kind === 'item');
|
|
363
|
+
return lines.join('\n');
|
|
364
|
+
}
|
|
365
|
+
/** Self-contained page: the Mermaid chart (rendered in the browser) above the outline */
|
|
366
|
+
export function renderStoryHtml(g) {
|
|
367
|
+
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
368
|
+
return `<!doctype html>
|
|
369
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
370
|
+
<title>${esc(g.title)} storyline</title>
|
|
371
|
+
<style>
|
|
372
|
+
:root { color-scheme: dark; }
|
|
373
|
+
body { margin: 0; background: #16161c; color: #e8e6e1; font: 15px/1.5 system-ui, sans-serif; }
|
|
374
|
+
header { padding: 20px 24px 8px; } h1 { margin: 0; font-size: 22px; } p { margin: 4px 0; color: #a9a6a0; }
|
|
375
|
+
.chart { overflow: auto; padding: 16px 24px; border-top: 1px solid #2c2c36; border-bottom: 1px solid #2c2c36; }
|
|
376
|
+
pre { margin: 0; padding: 16px 24px; white-space: pre-wrap; font: 13px/1.45 ui-monospace, Menlo, monospace; }
|
|
377
|
+
</style></head>
|
|
378
|
+
<body>
|
|
379
|
+
<header><h1>${esc(g.title)}</h1><p>Storyline: ${g.nodes.size} components, ${g.edges.length} connections. Solid arrows are buttons; dotted arrows are board items, inspection and monster events.</p></header>
|
|
380
|
+
<div class="chart"><pre class="mermaid">
|
|
381
|
+
${esc(renderMermaid(g))}
|
|
382
|
+
</pre></div>
|
|
383
|
+
<pre>${esc(renderOutline(g))}</pre>
|
|
384
|
+
<script type="module">
|
|
385
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
386
|
+
mermaid.initialize({ startOnLoad: true, theme: 'dark', maxTextSize: 500000, maxEdges: 5000, flowchart: { htmlLabels: true, curve: 'basis' } });
|
|
387
|
+
</script>
|
|
388
|
+
</body></html>
|
|
389
|
+
`;
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=story-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-graph.js","sourceRoot":"","sources":["../../src/story/story-graph.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thijshakkenberg/valkyrie-mom-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "MCP server for AI-assisted Mansions of Madness scenario creation with Valkyrie",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"extract-catalogs": "tsx src/catalogs/extract-catalogs.ts",
|
|
45
45
|
"lint": "tsc --noEmit",
|
|
46
46
|
"convert-tiles": "tsx scripts/convert-tile-images.ts",
|
|
47
|
-
"prepublishOnly": "npm run lint && npm run test && npm run build"
|
|
47
|
+
"prepublishOnly": "npm run lint && npm run test && npm run build",
|
|
48
|
+
"hermes:tools": "tsx scripts/export-hermes-tools.ts"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
51
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
package/skills/scenario/SKILL.md
CHANGED
|
@@ -90,6 +90,7 @@ Use `set_localization` to write all text:
|
|
|
90
90
|
### Step 9: Validate & Build
|
|
91
91
|
|
|
92
92
|
1. `validate_scenario` - fix any errors reported
|
|
93
|
+
1. `story_graph` - read the storyline back as a condensed tree: check every branch leads somewhere, every ending is reachable, and nothing is listed under "Never reached"
|
|
93
94
|
2. `save_scenario` - write the files so Valkyrie's editor sees them (edits stay in memory until saved)
|
|
94
95
|
3. `build_scenario` - create the .valkyrie package, its manifest `.ini` and cover image (default `Desktop/<Package>/`, like Valkyrie's Create Package)
|
|
95
96
|
|
|
@@ -140,10 +140,10 @@ const isMainModule = process.argv[1] && (
|
|
|
140
140
|
);
|
|
141
141
|
|
|
142
142
|
if (isMainModule) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
'
|
|
146
|
-
);
|
|
143
|
+
// The Valkyrie source checkout, by default next to this repository
|
|
144
|
+
const valkyrieRepo = process.env.VALKYRIE_SOURCE_DIR
|
|
145
|
+
?? path.join(path.dirname(path.dirname(path.dirname(import.meta.dirname ?? '.'))), 'valkyrie');
|
|
146
|
+
const valkyrieContentDir = path.join(valkyrieRepo, 'unity', 'Assets', 'StreamingAssets', 'content', 'MoM');
|
|
147
147
|
|
|
148
148
|
if (!fs.existsSync(valkyrieContentDir)) {
|
|
149
149
|
console.error(`Valkyrie content not found at: ${valkyrieContentDir}`);
|
package/src/server.ts
CHANGED
|
@@ -34,6 +34,7 @@ import { getMapAscii, suggestTileLayout, placeTileRelative } from './tools/map.j
|
|
|
34
34
|
import { renderMap } from './map/render.js';
|
|
35
35
|
import { searchGameContent } from './tools/reference.js';
|
|
36
36
|
import { toPackageName, writePackageManifest } from './io/package-manifest.js';
|
|
37
|
+
import { buildStoryGraph, renderMermaid, renderOutline, renderStoryHtml } from './story/story-graph.js';
|
|
37
38
|
import { DEFAULT_COMFYUI_URL, generateArtwork, getArtworkStatus, setupInstructions } from './artwork/comfyui.js';
|
|
38
39
|
import {
|
|
39
40
|
EVENT_FORMAT_DOC,
|
|
@@ -313,6 +314,35 @@ export function createServer(): McpServer {
|
|
|
313
314
|
},
|
|
314
315
|
);
|
|
315
316
|
|
|
317
|
+
server.tool(
|
|
318
|
+
'story_graph',
|
|
319
|
+
'Project the scenario\'s storyline as a graph: what each button, trigger, placed token, item inspection and monster event leads to. '
|
|
320
|
+
+ 'format=outline (default) is a condensed text tree: one line per event with its first words, conditions (if ...), effects (variables, +placed/−removed) and END; straight chains stay on one level, decisions indent, repeats point back (↩), and endings and never-reached events are listed. '
|
|
321
|
+
+ 'format=mermaid gives a flowchart definition. outputPath (.html) writes a page with the rendered chart and the outline for people. Use it to review or explain the plot, and to find dead ends and loops',
|
|
322
|
+
{
|
|
323
|
+
format: z.enum(['outline', 'mermaid']).optional().describe('outline (default) or mermaid'),
|
|
324
|
+
root: z.string().optional().describe('Only the part of the story that follows this component (e.g. EventScream)'),
|
|
325
|
+
maxDepth: z.number().int().optional().describe('Stop expanding below this depth (default 30)'),
|
|
326
|
+
outputPath: z.string().optional().describe('Also write the result, relative to the scenario folder or absolute: .html (chart + outline page), .mmd/.md (Mermaid) or .txt (outline)'),
|
|
327
|
+
},
|
|
328
|
+
async ({ format, root, maxDepth, outputPath }) => {
|
|
329
|
+
const model = getModel();
|
|
330
|
+
if (root && !model.get(root)) throw new Error(`No component named "${root}"`);
|
|
331
|
+
const graph = buildStoryGraph(model);
|
|
332
|
+
const text = format === 'mermaid' ? renderMermaid(graph) : renderOutline(graph, { root, maxDepth });
|
|
333
|
+
let note = '';
|
|
334
|
+
if (outputPath) {
|
|
335
|
+
const file = path.isAbsolute(outputPath) || !model.scenarioDir ? path.resolve(outputPath) : path.join(model.scenarioDir, outputPath);
|
|
336
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
337
|
+
if (/\.html?$/i.test(file)) fs.writeFileSync(file, renderStoryHtml(graph));
|
|
338
|
+
else if (/\.(mmd|md)$/i.test(file)) fs.writeFileSync(file, file.endsWith('.md') ? `\`\`\`mermaid\n${renderMermaid(graph)}\n\`\`\`\n` : renderMermaid(graph));
|
|
339
|
+
else fs.writeFileSync(file, text);
|
|
340
|
+
note = `\n\nWritten to ${file}`;
|
|
341
|
+
}
|
|
342
|
+
return { content: [{ type: 'text', text: text + note }] };
|
|
343
|
+
},
|
|
344
|
+
);
|
|
345
|
+
|
|
316
346
|
// ── Artwork Tools ──
|
|
317
347
|
|
|
318
348
|
server.tool(
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { parseRefList } from '../model/component-types.js';
|
|
2
|
+
import type { ScenarioModel } from '../model/scenario-model.js';
|
|
3
|
+
import { computeReachability, isStartingItem } from '../validation/rules/game-flow.js';
|
|
4
|
+
import { checkTrigger } from '../validation/rules/triggers.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The storyline as a graph: what runs what, the way Valkyrie plays it. Nodes are components that
|
|
8
|
+
* run (events, puzzles, spawns) or that players click or inspect (tokens, UI buttons, items);
|
|
9
|
+
* edges are buttons, board items placed by `add`, item inspection, monster events and
|
|
10
|
+
* Defeated triggers. Rendered as a condensed outline for authors and agents, or as Mermaid.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type EdgeKind = 'button' | 'places' | 'click' | 'inspect' | 'activation' | 'evade' | 'horror' | 'defeated';
|
|
14
|
+
|
|
15
|
+
export interface StoryEdge {
|
|
16
|
+
from: string;
|
|
17
|
+
to: string;
|
|
18
|
+
kind: EdgeKind;
|
|
19
|
+
/** Button text, or a short description of the connection */
|
|
20
|
+
label: string;
|
|
21
|
+
/** Several targets on one button: Valkyrie runs the first whose conditions pass, or a random one */
|
|
22
|
+
choice?: 'first' | 'random';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StoryNode {
|
|
26
|
+
name: string;
|
|
27
|
+
kind: 'dialog' | 'hidden' | 'puzzle' | 'spawn' | 'token' | 'ui' | 'item' | 'monster';
|
|
28
|
+
summary: string;
|
|
29
|
+
conditions?: string;
|
|
30
|
+
effects: string[];
|
|
31
|
+
ending?: 'end';
|
|
32
|
+
trigger?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface StoryGraph {
|
|
36
|
+
title: string;
|
|
37
|
+
nodes: Map<string, StoryNode>;
|
|
38
|
+
edges: StoryEdge[];
|
|
39
|
+
/** Entry points: triggers, and items held from the start */
|
|
40
|
+
roots: Array<{ label: string; node: string }>;
|
|
41
|
+
unreachable: string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const RUNNABLE = ['Event', 'Puzzle', 'Spawn'];
|
|
45
|
+
const isRunnable = (n: string) => RUNNABLE.some(p => n.startsWith(p));
|
|
46
|
+
|
|
47
|
+
/** Localized text as one short line: markup stripped, text codes kept readable */
|
|
48
|
+
function summarize(text: string | undefined, max = 90, loc?: (k: string) => string | undefined): string {
|
|
49
|
+
if (!text || text.trim() === '.') return '';
|
|
50
|
+
const plain = text
|
|
51
|
+
.replace(/^\|\|\|/, '')
|
|
52
|
+
.replace(/<[^>]+>/g, '')
|
|
53
|
+
.replace(/\\n|\n/g, ' ')
|
|
54
|
+
.replace(/\{qst:(\w+)\}/g, (_, k: string) => loc?.(k) ?? k)
|
|
55
|
+
.replace(/\{(?:c|var):([^}]+)\}/g, '$1')
|
|
56
|
+
.replace(/\s+/g, ' ')
|
|
57
|
+
.trim();
|
|
58
|
+
return plain.length > max ? `${plain.slice(0, max - 1).trimEnd()}…` : plain;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** "VarOperation:a,==,1 VarTestsLogicalOperator:AND VarOperation:b,>=,2" → "a==1 AND b>=2" */
|
|
62
|
+
export function compactConditions(vartests: string | undefined): string | undefined {
|
|
63
|
+
if (!vartests?.trim()) return undefined;
|
|
64
|
+
const parts = vartests.trim().split(/\s+/).map(t => {
|
|
65
|
+
const op = t.match(/^VarOperation:([^,]+),([^,]+),(.+)$/);
|
|
66
|
+
if (op) return `${op[1]}${op[2]}${op[3]}`;
|
|
67
|
+
const logic = t.match(/^VarTestsLogicalOperator:(\w+)$/);
|
|
68
|
+
if (logic) return logic[1];
|
|
69
|
+
return t.replace(/^VarTests\w*:/, '');
|
|
70
|
+
});
|
|
71
|
+
return parts.join(' ');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** "Suspicion,+,1 $end,=,1" → ["Suspicion+=1", "END"] */
|
|
75
|
+
export function compactOperations(ops: string | undefined): string[] {
|
|
76
|
+
return (ops ?? '').split(/\s+/).filter(Boolean).map(op => {
|
|
77
|
+
const [v, o, x] = op.split(',');
|
|
78
|
+
if (v === '$end' && o === '=' && x !== '0') return 'END';
|
|
79
|
+
if (o === '=') return `${v}=${x}`;
|
|
80
|
+
return `${v}${o}=${x}`;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function buttonLabel(model: ScenarioModel, name: string, i: number): string {
|
|
85
|
+
return summarize(model.localization.get(`${name}.button${i}`), 40, k => model.localization.get(k));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function buildStoryGraph(model: ScenarioModel): StoryGraph {
|
|
89
|
+
const nodes = new Map<string, StoryNode>();
|
|
90
|
+
const edges: StoryEdge[] = [];
|
|
91
|
+
const loc = (k: string) => model.localization.get(k);
|
|
92
|
+
|
|
93
|
+
const ensure = (name: string): StoryNode | undefined => {
|
|
94
|
+
const existing = nodes.get(name);
|
|
95
|
+
if (existing) return existing;
|
|
96
|
+
const comp = model.get(name);
|
|
97
|
+
if (!comp) return undefined;
|
|
98
|
+
const d = comp.data;
|
|
99
|
+
let kind: StoryNode['kind'];
|
|
100
|
+
if (name.startsWith('Puzzle')) kind = 'puzzle';
|
|
101
|
+
else if (name.startsWith('Spawn')) kind = 'spawn';
|
|
102
|
+
else if (name.startsWith('Token')) kind = 'token';
|
|
103
|
+
else if (name.startsWith('UI')) kind = 'ui';
|
|
104
|
+
else if (name.startsWith('QItem')) kind = 'item';
|
|
105
|
+
else if (name.startsWith('CustomMonster')) kind = 'monster';
|
|
106
|
+
else kind = d.display?.toLowerCase() === 'false' ? 'hidden' : 'dialog';
|
|
107
|
+
|
|
108
|
+
const effects = compactOperations(d.operations);
|
|
109
|
+
const placed = parseRefList(d.add ?? '');
|
|
110
|
+
const removed = parseRefList(d.remove ?? '');
|
|
111
|
+
if (placed.length) effects.push(`+${placed.join(' +')}`);
|
|
112
|
+
if (removed.length) effects.push(`−${removed.join(' −')}`);
|
|
113
|
+
if (kind === 'puzzle') effects.unshift(`${d.class ?? 'slide'} puzzle ${d.skill ?? '{observation}'}${d.puzzlesolution ? ` = ${d.puzzlesolution}` : ''}`);
|
|
114
|
+
if (kind === 'spawn' && d.monster) effects.unshift(`monster ${d.monster}`);
|
|
115
|
+
|
|
116
|
+
let summary = summarize(loc(`${name}.text`), 80, loc);
|
|
117
|
+
if (kind === 'spawn') summary = summarize(loc(`${name}.uniquetitle`)) || summary;
|
|
118
|
+
if (kind === 'ui') summary = summarize(loc(`${name}.uitext`)) || summary;
|
|
119
|
+
if (kind === 'monster') summary = summarize(loc(`${name}.monstername`)) || '';
|
|
120
|
+
|
|
121
|
+
const node: StoryNode = {
|
|
122
|
+
name, kind, summary, effects,
|
|
123
|
+
conditions: compactConditions(d.vartests),
|
|
124
|
+
ending: effects.includes('END') ? 'end' : undefined,
|
|
125
|
+
trigger: d.trigger?.trim() || undefined,
|
|
126
|
+
};
|
|
127
|
+
nodes.set(name, node);
|
|
128
|
+
return node;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const visited = new Set<string>();
|
|
132
|
+
const visit = (name: string) => {
|
|
133
|
+
if (visited.has(name) || !ensure(name)) return;
|
|
134
|
+
visited.add(name);
|
|
135
|
+
const d = model.get(name)!.data;
|
|
136
|
+
const buttons = Math.max(parseInt(d.buttons ?? '0', 10) || 0, 1);
|
|
137
|
+
const hidden = nodes.get(name)!.kind === 'hidden';
|
|
138
|
+
|
|
139
|
+
// Buttons (hidden events always follow button 1; tokens and UI run their buttons when clicked)
|
|
140
|
+
for (let i = 1; i <= 6; i++) {
|
|
141
|
+
const targets = parseRefList(d[`event${i}`] ?? '');
|
|
142
|
+
if (targets.length === 0) continue;
|
|
143
|
+
if (i > buttons && !name.startsWith('Token')) continue;
|
|
144
|
+
const label = hidden ? '' : (buttonLabel(model, name, i) || (buttons > 1 ? `button ${i}` : ''));
|
|
145
|
+
const choice = targets.length > 1 ? (d.randomevents?.toLowerCase() === 'true' ? 'random' : 'first') : undefined;
|
|
146
|
+
for (const t of targets) {
|
|
147
|
+
if (!model.get(t)) continue;
|
|
148
|
+
edges.push({ from: name, to: t, kind: name.startsWith('Puzzle') ? 'button' : 'button', label, choice });
|
|
149
|
+
visit(t);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Board items and items this component places: clicking or inspecting them continues the story
|
|
153
|
+
for (const ref of parseRefList(d.add ?? '')) {
|
|
154
|
+
const target = model.get(ref);
|
|
155
|
+
if (!target) continue;
|
|
156
|
+
const clickable = (ref.startsWith('Token') || ref.startsWith('UI'))
|
|
157
|
+
&& [1, 2, 3, 4, 5, 6].some(i => parseRefList(target.data[`event${i}`] ?? '').length > 0);
|
|
158
|
+
if (clickable) {
|
|
159
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'places' });
|
|
160
|
+
visit(ref);
|
|
161
|
+
} else if (ref.startsWith('QItem') && target.data.inspect) {
|
|
162
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'gives' });
|
|
163
|
+
visitItem(ref);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Monster phase, evade and horror events of what this spawn puts on the board
|
|
167
|
+
if (name.startsWith('Spawn')) {
|
|
168
|
+
for (const m of parseRefList(d.monster ?? '')) {
|
|
169
|
+
const cm = model.get(m);
|
|
170
|
+
if (!cm) continue;
|
|
171
|
+
const acts = parseRefList(cm.data.activation ?? '').filter(a => a.startsWith('Event'));
|
|
172
|
+
for (const a of acts) { edges.push({ from: name, to: a, kind: 'activation', label: 'each monster phase' }); visit(a); }
|
|
173
|
+
for (const [f, kind, label] of [['evadeevent', 'evade', 'on evade'], ['horrorevent', 'horror', 'on horror check']] as const) {
|
|
174
|
+
if (cm.data[f] && model.get(cm.data[f]!)) { edges.push({ from: name, to: cm.data[f]!, kind, label }); visit(cm.data[f]!); }
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const visitItem = (item: string) => {
|
|
180
|
+
if (visited.has(item) || !ensure(item)) return;
|
|
181
|
+
visited.add(item);
|
|
182
|
+
for (const e of parseRefList(model.get(item)!.data.inspect ?? '')) {
|
|
183
|
+
if (!model.get(e)) continue;
|
|
184
|
+
edges.push({ from: item, to: e, kind: 'inspect', label: 'inspect' });
|
|
185
|
+
visit(e);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// Entry points: EventStart first, then other triggers, starting items; Defeated triggers hang off their spawn
|
|
190
|
+
const roots: StoryGraph['roots'] = [];
|
|
191
|
+
const defeated: Array<{ event: string; target: string }> = [];
|
|
192
|
+
const triggered = model.getAll().filter(c => c.data.trigger?.trim() && isRunnable(c.name));
|
|
193
|
+
triggered.sort((a, b) => Number(b.data.trigger === 'EventStart') - Number(a.data.trigger === 'EventStart'));
|
|
194
|
+
for (const comp of triggered) {
|
|
195
|
+
const trigger = comp.data.trigger!.trim();
|
|
196
|
+
const check = checkTrigger(model, trigger);
|
|
197
|
+
if (!check.ok) continue;
|
|
198
|
+
if (check.defeated) { defeated.push({ event: comp.name, target: check.defeated }); continue; }
|
|
199
|
+
roots.push({ label: trigger === 'EventStart' ? 'Game start' : `Trigger ${trigger}`, node: comp.name });
|
|
200
|
+
}
|
|
201
|
+
for (const r of roots) visit(r.node);
|
|
202
|
+
for (const item of model.getByType('QItem')) {
|
|
203
|
+
if (isStartingItem(item.data) && item.data.inspect) {
|
|
204
|
+
roots.push({ label: 'Starting item', node: item.name });
|
|
205
|
+
visitItem(item.name);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Defeated<X>: from each spawn that puts X (or a monster of type X) on the board
|
|
209
|
+
let grew = true;
|
|
210
|
+
while (grew) {
|
|
211
|
+
grew = false;
|
|
212
|
+
for (const t of defeated) {
|
|
213
|
+
const sources = [...nodes.keys()].filter(n => n === t.target
|
|
214
|
+
|| (n.startsWith('Spawn') && parseRefList(model.get(n)?.data.monster ?? '').includes(t.target)));
|
|
215
|
+
for (const s of sources) {
|
|
216
|
+
if (edges.some(e => e.from === s && e.to === t.event)) continue;
|
|
217
|
+
edges.push({ from: s, to: t.event, kind: 'defeated', label: 'when defeated' });
|
|
218
|
+
if (!visited.has(t.event)) grew = true;
|
|
219
|
+
visit(t.event);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const { runs } = computeReachability(model);
|
|
225
|
+
const unreachable = model.getAll()
|
|
226
|
+
.filter(c => isRunnable(c.name) && !visited.has(c.name) && !runs.has(c.name))
|
|
227
|
+
.map(c => c.name);
|
|
228
|
+
|
|
229
|
+
return { title: loc('quest.name') ?? 'Scenario', nodes, edges, roots, unreachable };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const ICON: Record<StoryNode['kind'], string> = {
|
|
233
|
+
dialog: '▶', hidden: '·', puzzle: '◆', spawn: '☠', token: '⊕', ui: '▣', item: '✉', monster: '☠',
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
function nodeLine(n: StoryNode): string {
|
|
237
|
+
const parts = [`${ICON[n.kind]} ${n.name}`];
|
|
238
|
+
if (n.conditions) parts.push(`if ${n.conditions}`);
|
|
239
|
+
if (n.summary) parts.push(`"${n.summary}"`);
|
|
240
|
+
const effects = n.effects.filter(e => e !== 'END');
|
|
241
|
+
if (effects.length) parts.push(`⟨${effects.join(', ')}⟩`);
|
|
242
|
+
if (n.ending) parts.push('✦ END');
|
|
243
|
+
return parts.join(' ');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface OutlineOptions {
|
|
247
|
+
/** Start from this component instead of the scenario's entry points */
|
|
248
|
+
root?: string;
|
|
249
|
+
/** Stop expanding below this depth (default 30) */
|
|
250
|
+
maxDepth?: number;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Condensed text projection: each component expanded once, later visits point back to it */
|
|
254
|
+
export function renderOutline(g: StoryGraph, opts: OutlineOptions = {}): string {
|
|
255
|
+
const maxDepth = opts.maxDepth ?? 30;
|
|
256
|
+
const out: string[] = [];
|
|
257
|
+
const printed = new Set<string>();
|
|
258
|
+
const byFrom = new Map<string, StoryEdge[]>();
|
|
259
|
+
for (const e of g.edges) byFrom.set(e.from, [...(byFrom.get(e.from) ?? []), e]);
|
|
260
|
+
|
|
261
|
+
// Straight chains stay on one level; only decisions (several buttons, choices, placed items) indent
|
|
262
|
+
const walk = (name: string, depth: number, indent: string, lead: string) => {
|
|
263
|
+
const n = g.nodes.get(name);
|
|
264
|
+
if (!n) return;
|
|
265
|
+
if (printed.has(name)) { out.push(`${indent}${lead}↩ ${name}`); return; }
|
|
266
|
+
printed.add(name);
|
|
267
|
+
out.push(`${indent}${lead}${nodeLine(n)}`);
|
|
268
|
+
// What follows a "• " choice belongs to it, so it lines up under the choice's text
|
|
269
|
+
if (lead === '• ') indent += ' ';
|
|
270
|
+
if (depth >= maxDepth) { out.push(`${indent} …`); return; }
|
|
271
|
+
const groups = new Map<string, StoryEdge[]>();
|
|
272
|
+
for (const e of byFrom.get(name) ?? []) {
|
|
273
|
+
const key = `${e.kind}|${e.label}|${e.choice ?? ''}`;
|
|
274
|
+
groups.set(key, [...(groups.get(key) ?? []), e]);
|
|
275
|
+
}
|
|
276
|
+
const labelOf = (e: StoryEdge, many: boolean) => {
|
|
277
|
+
let label = e.kind === 'button' ? (e.label ? `[${e.label}]` : '→') : `(${e.label})`;
|
|
278
|
+
if (e.choice && many) label += e.choice === 'random' ? ' one at random:' : ' first that passes:';
|
|
279
|
+
return label;
|
|
280
|
+
};
|
|
281
|
+
const list = [...groups.values()];
|
|
282
|
+
if (list.length === 1 && list[0].length === 1) {
|
|
283
|
+
walk(list[0][0].to, depth + 1, indent, `${labelOf(list[0][0], false)} `);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const inner = `${indent} `;
|
|
287
|
+
for (const group of list) {
|
|
288
|
+
if (group.length === 1) walk(group[0].to, depth + 1, inner, `${labelOf(group[0], false)} `);
|
|
289
|
+
else {
|
|
290
|
+
out.push(`${inner}${labelOf(group[0], true)}`);
|
|
291
|
+
for (const t of group) walk(t.to, depth + 1, `${inner} `, '• ');
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
out.push(`Storyline of "${g.title}": ${[...g.nodes.values()].filter(n => n.kind === 'dialog' || n.kind === 'hidden').length} events, ${g.edges.length} connections`);
|
|
297
|
+
out.push('Legend: ▶ dialog · hidden event ◆ puzzle ☠ spawn/monster ⊕ token ▣ UI button ✉ item [button] → next ↩ already shown above ⟨effects⟩ ✦ END');
|
|
298
|
+
if (opts.root) {
|
|
299
|
+
out.push('');
|
|
300
|
+
walk(opts.root, 0, '', '');
|
|
301
|
+
} else {
|
|
302
|
+
for (const r of g.roots) {
|
|
303
|
+
out.push('', `== ${r.label} ==`);
|
|
304
|
+
walk(r.node, 0, '', '');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (!opts.root) {
|
|
308
|
+
const endings = [...g.nodes.values()].filter(n => n.ending);
|
|
309
|
+
if (endings.length) {
|
|
310
|
+
out.push('', '== Endings ==');
|
|
311
|
+
const parents = (name: string) => g.edges.filter(e => e.to === name).map(e => e.from);
|
|
312
|
+
for (const n of endings) {
|
|
313
|
+
const via = parents(n.name).map(p => g.nodes.get(p)?.kind === 'hidden' ? parents(p).concat(p) : [p]).flat();
|
|
314
|
+
out.push(`✦ ${n.name}${via.length ? ` ← ${[...new Set(via)].join(', ')}` : ''}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (g.unreachable.length) out.push('', '== Never reached ==', g.unreachable.join(', '));
|
|
318
|
+
}
|
|
319
|
+
return out.join('\n');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function mermaidId(name: string): string {
|
|
323
|
+
return name.replace(/[^A-Za-z0-9_]/g, '_');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function mermaidText(s: string): string {
|
|
327
|
+
return s.replace(/"/g, "'").replace(/[<>]/g, '').replace(/[[\]{}|]/g, ' ');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Mermaid flowchart of the same graph */
|
|
331
|
+
export function renderMermaid(g: StoryGraph): string {
|
|
332
|
+
const lines = ['flowchart TD'];
|
|
333
|
+
const shape = (n: StoryNode) => {
|
|
334
|
+
const summary = n.summary ? `<br/><small>${mermaidText(n.summary.slice(0, 48))}</small>` : '';
|
|
335
|
+
const cond = n.conditions ? `<br/><i>if ${mermaidText(n.conditions)}</i>` : '';
|
|
336
|
+
const text = `"${n.name}${cond}${summary}"`;
|
|
337
|
+
switch (n.kind) {
|
|
338
|
+
case 'puzzle': return `{{${text}}}`;
|
|
339
|
+
case 'spawn': case 'monster': return `[/${text}/]`;
|
|
340
|
+
case 'token': case 'ui': case 'item': return `>${text}]`;
|
|
341
|
+
case 'hidden': return `(${text})`;
|
|
342
|
+
default: return n.ending ? `([${text}])` : `[${text}]`;
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
for (const r of g.roots) lines.push(` root_${mermaidId(r.node)}(("${mermaidText(r.label)}")) --> ${mermaidId(r.node)}`);
|
|
346
|
+
for (const n of g.nodes.values()) lines.push(` ${mermaidId(n.name)}${shape(n)}`);
|
|
347
|
+
for (const e of g.edges) {
|
|
348
|
+
const label = e.kind === 'button' ? e.label : e.label;
|
|
349
|
+
const arrow = e.kind === 'button' ? '-->' : '-.->';
|
|
350
|
+
lines.push(` ${mermaidId(e.from)} ${arrow}${label ? `|"${mermaidText(label)}"|` : ''} ${mermaidId(e.to)}`);
|
|
351
|
+
}
|
|
352
|
+
lines.push(' classDef hidden fill:#2a2a33,stroke:#666,color:#bbb,stroke-dasharray:3 3');
|
|
353
|
+
lines.push(' classDef ending fill:#4a1d1d,stroke:#d66,color:#fff');
|
|
354
|
+
lines.push(' classDef puzzle fill:#1d3a4a,stroke:#6bd,color:#fff');
|
|
355
|
+
lines.push(' classDef board fill:#3a341d,stroke:#db6,color:#fff');
|
|
356
|
+
const cls = (k: string, pred: (n: StoryNode) => boolean) => {
|
|
357
|
+
const ids = [...g.nodes.values()].filter(pred).map(n => mermaidId(n.name));
|
|
358
|
+
if (ids.length) lines.push(` class ${ids.join(',')} ${k}`);
|
|
359
|
+
};
|
|
360
|
+
cls('hidden', n => n.kind === 'hidden' && !n.ending);
|
|
361
|
+
cls('ending', n => !!n.ending);
|
|
362
|
+
cls('puzzle', n => n.kind === 'puzzle');
|
|
363
|
+
cls('board', n => n.kind === 'token' || n.kind === 'ui' || n.kind === 'item');
|
|
364
|
+
return lines.join('\n');
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Self-contained page: the Mermaid chart (rendered in the browser) above the outline */
|
|
368
|
+
export function renderStoryHtml(g: StoryGraph): string {
|
|
369
|
+
const esc = (s: string) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
370
|
+
return `<!doctype html>
|
|
371
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
372
|
+
<title>${esc(g.title)} storyline</title>
|
|
373
|
+
<style>
|
|
374
|
+
:root { color-scheme: dark; }
|
|
375
|
+
body { margin: 0; background: #16161c; color: #e8e6e1; font: 15px/1.5 system-ui, sans-serif; }
|
|
376
|
+
header { padding: 20px 24px 8px; } h1 { margin: 0; font-size: 22px; } p { margin: 4px 0; color: #a9a6a0; }
|
|
377
|
+
.chart { overflow: auto; padding: 16px 24px; border-top: 1px solid #2c2c36; border-bottom: 1px solid #2c2c36; }
|
|
378
|
+
pre { margin: 0; padding: 16px 24px; white-space: pre-wrap; font: 13px/1.45 ui-monospace, Menlo, monospace; }
|
|
379
|
+
</style></head>
|
|
380
|
+
<body>
|
|
381
|
+
<header><h1>${esc(g.title)}</h1><p>Storyline: ${g.nodes.size} components, ${g.edges.length} connections. Solid arrows are buttons; dotted arrows are board items, inspection and monster events.</p></header>
|
|
382
|
+
<div class="chart"><pre class="mermaid">
|
|
383
|
+
${esc(renderMermaid(g))}
|
|
384
|
+
</pre></div>
|
|
385
|
+
<pre>${esc(renderOutline(g))}</pre>
|
|
386
|
+
<script type="module">
|
|
387
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
388
|
+
mermaid.initialize({ startOnLoad: true, theme: 'dark', maxTextSize: 500000, maxEdges: 5000, flowchart: { htmlLabels: true, curve: 'basis' } });
|
|
389
|
+
</script>
|
|
390
|
+
</body></html>
|
|
391
|
+
`;
|
|
392
|
+
}
|