@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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valkyrie-mom",
3
- "version": "2.2.0",
3
+ "version": "2.3.1",
4
4
  "description": "AI-assisted Mansions of Madness scenario editor for Valkyrie",
5
5
  "author": {
6
6
  "name": "Thijs Hakkenberg"
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 # Run all tests (1067 tests across 44 files)
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/ Plugin manifest
224
- skills/ 8 skill SKILL.md files
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/ 15 rules + orchestrator
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
- const valkyrieContentDir = path.resolve(import.meta.dirname ?? '.', '../../../valkyrie/unity/Assets/StreamingAssets/content/MoM');
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":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA6EpE,wBAAgB,YAAY,IAAI,SAAS,CAwbxC"}
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);
@@ -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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
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.2.0",
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",
@@ -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
- const valkyrieContentDir = path.resolve(
144
- import.meta.dirname ?? '.',
145
- '../../../valkyrie/unity/Assets/StreamingAssets/content/MoM',
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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
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
+ }