Add story-graph narrative system (campaigns, editors, runtime)
Introduce the narrative layer as a directed story-flow graph: an authored campaign a player walks node by node, replacing the interim slot/chapter model. Schema (migrations 015-021): - mysteries, global NPC templates + named poses, per-user playthroughs - story_nodes, terminals, utterances (the flow graph and dialogue trees) - clean cutover: retire slot cutscenes/chapters/seen_dialogue Runtime: - New Game creates a playthrough bound to the JWT identity (dev test-user fallback) - advance() walks the graph cutscene -> dialogue -> level -> ..., auto-skipping gates - branching dialogue: player choices route out through node terminals Admin authoring: - NPC editor: upload named poses to the gupi MinIO bucket - mystery graph editor: vertical node canvas, wiring, entrypoint, delete-by-click - dialogue crafter: utterance tree, Tab to add child, 1/2 speaker, undo Content authored via the manifest importer / admin panel and seeded for Glass Harbour. MinIO added to the dev stack; dev container runs in development mode. Also includes a folder-widget simplification (removes open/close) and a resolveUserId auth helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -123,6 +123,44 @@
|
||||
"metadata": { "lot": "117", "seller_reference": "MV-3/771", "estimate": "45,000–52,000 NOK" }
|
||||
}
|
||||
],
|
||||
"narrative": {
|
||||
"cast": [
|
||||
{ "key": "professor", "name": "Prof. Almira Vetch", "role": "Glitch University · Investigative Method", "defaultPose": "neutral" }
|
||||
],
|
||||
"graph": {
|
||||
"entry": "intro",
|
||||
"nodes": [
|
||||
{
|
||||
"key": "intro", "type": "cutscene", "label": "The Glass Harbour Diversion",
|
||||
"componentKey": "glass-harbour-diversion", "x": 200, "y": 60,
|
||||
"terminals": [{ "key": "continue", "to": "briefing" }]
|
||||
},
|
||||
{
|
||||
"key": "briefing", "type": "dialogue", "label": "Briefing", "x": 200, "y": 220,
|
||||
"terminals": [{ "key": "continue", "label": "Begin", "to": "investigate" }],
|
||||
"utterances": [
|
||||
{ "npc": "professor", "pose": "neutral", "text": "Principal Investigator. Good — you're early. Sit. The Society has handed us a mess: a restored Fresnel lens, bought and paid for, that never reached the lighthouse it was meant for." },
|
||||
{ "npc": "professor", "pose": "concerned", "text": "Greyhaven file 87-10. Between dispatch and installation the shipment simply changed course. Someone arranged that, and someone stood to profit. Both facts are in the documents — nowhere else." },
|
||||
{ "npc": "professor", "pose": "wry", "text": "I won't tell you who did it. That is the whole exercise. Classify every name, tie each party to the evidence, and reconstruct the order of events until the account defends itself." },
|
||||
{ "npc": "professor", "pose": "neutral", "text": "The terminal will not congratulate you. A solved board is one where your conclusion is the only one the paper trail still allows. Go." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "investigate", "type": "level", "label": "Investigate the board",
|
||||
"templateSlug": "glass-harbor", "x": 200, "y": 380,
|
||||
"terminals": [{ "key": "report_back", "label": "Report back", "to": "debrief" }]
|
||||
},
|
||||
{
|
||||
"key": "debrief", "type": "dialogue", "label": "Debrief", "x": 200, "y": 540,
|
||||
"terminals": [{ "key": "continue", "label": "End", "to": null }],
|
||||
"utterances": [
|
||||
{ "npc": "professor", "pose": "wry", "text": "There it is. The lens never sailed for the lighthouse — it sailed for a saleroom, and your thread shows exactly whose hand turned it." },
|
||||
{ "npc": "professor", "pose": "neutral", "text": "A defensible account, Principal Investigator. Greyhaven file 87-10 is closed. Get some sleep — there will be another." }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"folders": [
|
||||
{
|
||||
"key": "procurement-file",
|
||||
|
||||
Reference in New Issue
Block a user