Skip to content

Commit 4354ceb

Browse files
authored
Add story settings and Moment links
Adds reusable story-level settings, optional Moment setting references, schema documentation, examples, and validation fixture cleanup.
1 parent 0b9ab12 commit 4354ceb

13 files changed

Lines changed: 172 additions & 44 deletions

HISTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Recent Schema Updates
44

5+
- Added optional `story.settings[]` entries for reusable story-level Settings and optional `narratives[].storytelling.moments[].setting_id` references so Moments can point at a shared Setting while preserving free-text `setting`.
6+
- Added a canonical story settings example and refreshed validation fixtures so canonical Storybeats omit legacy `signpost` keys.
57
- Added optional `subtext.storybeats[].appreciation` as a derived interoperability field based on `throughline + scope + sequence`.
68
- Clarified that Storybeat importers should derive the appreciation identity when the field is omitted so lighter-weight payloads remain compatible.
79
- Clarified that canonical Storybeat objects do not expose a `signpost` key; any internal grouping should be derived from structural scope, sequence, and parent relationships.

SPECIFICATION.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,22 @@ For open-source adopters, this creates a shared on-ramp: communities can exchang
9393
```
9494

9595

96+
## Story Settings
97+
98+
NCP supports optional reusable story-level Settings for places or environments that recur across Moments. `story.settings[]` defines the shared setting once, while each Moment keeps its own free-text `setting` and may optionally reference the shared entry with `setting_id`.
99+
100+
This avoids repeating the same place details across multiple Moments without making every producer model setting identity. Producers that only need free-text Moment settings can omit `story.settings[]` and `setting_id`.
101+
102+
```json
103+
"settings": [
104+
{
105+
"id": "setting_precinct_archive",
106+
"name": "Precinct Archive",
107+
"description": "A dimly lit archive room where old case files preserve institutional memory."
108+
}
109+
]
110+
```
111+
96112
## Narrative: Structuring Subtext & Storytelling
97113

98114
A single story may contain one or more narratives (e.g., _The Empire Strikes Back_ has the Luke/Yoda Storyform and the Han/Leia Storyform, _Barbie_ has the Barbie/Ken Storyform and the Barbie/Gloria Storyform). Most stories, however, exhibit a single central narrative (e.g., _Anora_, _Anatomy of a Fall_, etc.).
@@ -414,6 +430,7 @@ Organizational narrative units—such as Acts, Scenes, Sequences, Chapters, and
414430
"summary": "Infiltrating the neon-lit heart of a dystopian metropolis, Alex plunges into a shadowy realm teeming with digital outlaws.",
415431
"synopsis": "Freshly arrived in the neon chaos of Neo-Tokyo, Alex is swiftly ensnared in a perilous game played by cyber-criminals, underground syndicates, and relentless AI-driven enforcers.",
416432
"setting": "The pulsating streets of Neo-Tokyo, where holographic ads blend with the shadowy back alleys controlled by syndicate bosses.",
433+
"setting_id": "setting_neo_tokyo_streets",
417434
"timing": "Late night, just hours after Alex's first unsettling discovery upon arriving in the city.",
418435
"imperatives": "- Establish the dark, chaotic atmosphere of Neo-Tokyo\n- Introduce key threats: cyber-criminals and AI enforcers\n- Show Alex's initial vulnerabilities and resourcefulness",
419436
"audience_experiential_pov": "third_person_limited",

docs/narrative-context-protocol-schema.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,22 @@ Quick heuristic:
104104
- If it is an event chain or conflict progression, put it in `plot`.
105105
- If it is a framing/experience contract with the audience, put it in `genre`.
106106

107+
## Story Settings
108+
109+
`story.settings[]` is an optional story-level glossary for reusable places or environments. Each setting requires an `id` and `name`, with an optional `description`. Moments may keep their local free-text `setting` prose while also pointing at a shared setting with `setting_id`.
110+
111+
Use this when multiple Moments occur in the same place and producers want a stable reference instead of repeating or string-matching setting descriptions.
112+
113+
```json
114+
"settings": [
115+
{
116+
"id": "setting_precinct_archive",
117+
"name": "Precinct Archive",
118+
"description": "A dimly lit archive room where old case files preserve institutional memory."
119+
}
120+
]
121+
```
122+
107123
## Narrative Layers
108124

109125
Each item in `story.narratives[]` is a Dramatica storyform: a single, complete argument structure within the story, expressed through `subtext` and `storytelling` layers.
@@ -290,7 +306,9 @@ Required keys per item:
290306

291307
Optional keys:
292308

293-
- `id`, `act`, `order`, `maximum_steps`, `fabric`, `audience_experiential_pov`
309+
- `id`, `setting_id`, `act`, `order`, `maximum_steps`, `fabric`, `audience_experiential_pov`
310+
311+
`setting` remains the Moment-specific free-text description. `setting_id` may reference a `story.settings[]` entry when the Moment occurs in a reusable story-level setting.
294312

295313
`storybeats` inside a moment is an ordered reference list:
296314

examples/anora.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@
169169
"id": "beat_anora_signpost_1",
170170
"scope": "signpost",
171171
"sequence": 1,
172-
"signpost": 1,
173172
"throughline": "Main Character",
174173
"narrative_function": "Present",
175174
"summary": "Ani experiences the immediate thrill and danger of rapid escalation.",
@@ -184,7 +183,6 @@
184183
"id": "beat_anora_progression_3",
185184
"scope": "progression",
186185
"sequence": 3,
187-
"signpost": 1,
188186
"throughline": "Objective Story",
189187
"narrative_function": "Learning",
190188
"summary": "The family applies escalating leverage to force compliance.",

examples/complete-storyform-template.json

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,6 @@
11911191
"id": "beat_objective_story_signpost_1",
11921192
"scope": "signpost",
11931193
"sequence": 1,
1194-
"signpost": 1,
11951194
"throughline": "Objective Story",
11961195
"summary": "",
11971196
"storytelling": "",
@@ -1205,7 +1204,6 @@
12051204
"id": "beat_objective_story_signpost_2",
12061205
"scope": "signpost",
12071206
"sequence": 2,
1208-
"signpost": 2,
12091207
"throughline": "Objective Story",
12101208
"summary": "",
12111209
"storytelling": "",
@@ -1219,7 +1217,6 @@
12191217
"id": "beat_objective_story_signpost_3",
12201218
"scope": "signpost",
12211219
"sequence": 3,
1222-
"signpost": 3,
12231220
"throughline": "Objective Story",
12241221
"summary": "",
12251222
"storytelling": "",
@@ -1233,7 +1230,6 @@
12331230
"id": "beat_objective_story_signpost_4",
12341231
"scope": "signpost",
12351232
"sequence": 4,
1236-
"signpost": 4,
12371233
"throughline": "Objective Story",
12381234
"summary": "",
12391235
"storytelling": "",
@@ -1247,7 +1243,6 @@
12471243
"id": "beat_main_character_signpost_1",
12481244
"scope": "signpost",
12491245
"sequence": 1,
1250-
"signpost": 1,
12511246
"throughline": "Main Character",
12521247
"summary": "",
12531248
"storytelling": "",
@@ -1261,7 +1256,6 @@
12611256
"id": "beat_main_character_signpost_2",
12621257
"scope": "signpost",
12631258
"sequence": 2,
1264-
"signpost": 2,
12651259
"throughline": "Main Character",
12661260
"summary": "",
12671261
"storytelling": "",
@@ -1275,7 +1269,6 @@
12751269
"id": "beat_main_character_signpost_3",
12761270
"scope": "signpost",
12771271
"sequence": 3,
1278-
"signpost": 3,
12791272
"throughline": "Main Character",
12801273
"summary": "",
12811274
"storytelling": "",
@@ -1289,7 +1282,6 @@
12891282
"id": "beat_main_character_signpost_4",
12901283
"scope": "signpost",
12911284
"sequence": 4,
1292-
"signpost": 4,
12931285
"throughline": "Main Character",
12941286
"summary": "",
12951287
"storytelling": "",
@@ -1303,7 +1295,6 @@
13031295
"id": "beat_influence_character_signpost_1",
13041296
"scope": "signpost",
13051297
"sequence": 1,
1306-
"signpost": 1,
13071298
"throughline": "Influence Character",
13081299
"summary": "",
13091300
"storytelling": "",
@@ -1317,7 +1308,6 @@
13171308
"id": "beat_influence_character_signpost_2",
13181309
"scope": "signpost",
13191310
"sequence": 2,
1320-
"signpost": 2,
13211311
"throughline": "Influence Character",
13221312
"summary": "",
13231313
"storytelling": "",
@@ -1331,7 +1321,6 @@
13311321
"id": "beat_influence_character_signpost_3",
13321322
"scope": "signpost",
13331323
"sequence": 3,
1334-
"signpost": 3,
13351324
"throughline": "Influence Character",
13361325
"summary": "",
13371326
"storytelling": "",
@@ -1345,7 +1334,6 @@
13451334
"id": "beat_influence_character_signpost_4",
13461335
"scope": "signpost",
13471336
"sequence": 4,
1348-
"signpost": 4,
13491337
"throughline": "Influence Character",
13501338
"summary": "",
13511339
"storytelling": "",
@@ -1359,7 +1347,6 @@
13591347
"id": "beat_relationship_story_signpost_1",
13601348
"scope": "signpost",
13611349
"sequence": 1,
1362-
"signpost": 1,
13631350
"throughline": "Relationship Story",
13641351
"summary": "",
13651352
"storytelling": "",
@@ -1373,7 +1360,6 @@
13731360
"id": "beat_relationship_story_signpost_2",
13741361
"scope": "signpost",
13751362
"sequence": 2,
1376-
"signpost": 2,
13771363
"throughline": "Relationship Story",
13781364
"summary": "",
13791365
"storytelling": "",
@@ -1387,7 +1373,6 @@
13871373
"id": "beat_relationship_story_signpost_3",
13881374
"scope": "signpost",
13891375
"sequence": 3,
1390-
"signpost": 3,
13911376
"throughline": "Relationship Story",
13921377
"summary": "",
13931378
"storytelling": "",
@@ -1401,7 +1386,6 @@
14011386
"id": "beat_relationship_story_signpost_4",
14021387
"scope": "signpost",
14031388
"sequence": 4,
1404-
"signpost": 4,
14051389
"throughline": "Relationship Story",
14061390
"summary": "",
14071391
"storytelling": "",

examples/example-story.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
"genre": "Mystery Thriller",
77
"logline": "A hardened detective uncovers clues linking a cold case to his own haunting history.",
88
"created_at": "2025-12-01T12:34:56Z",
9+
"settings": [
10+
{
11+
"id": "setting_precinct_archive",
12+
"name": "Precinct Archive",
13+
"description": "A dimly lit archive room where old case files preserve institutional memory and unresolved history."
14+
}
15+
],
916
"ideation": {
1017
"character": [
1118
{
@@ -112,7 +119,6 @@
112119
"id": "beat_001",
113120
"scope": "signpost",
114121
"sequence": 2,
115-
"signpost": 2,
116122
"throughline": "Main Character",
117123
"narrative_function": "Preconscious",
118124
"summary": "A moment where the past resurfaces, influencing his current investigation.",
@@ -149,6 +155,7 @@
149155
"summary": "The inciting discovery",
150156
"synopsis": "John uncovers an old case file that hints at deeper connections to his own past.",
151157
"setting": "A dimly lit precinct archive room.",
158+
"setting_id": "setting_precinct_archive",
152159
"timing": "Late night, after hours.",
153160
"imperatives": "Investigate the link before the evidence disappears.",
154161
"storybeats": [

examples/story-settings.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"schema_version": "1.3.0",
3+
"story": {
4+
"id": "story_settings_demo",
5+
"title": "Shared Settings Demo",
6+
"logline": "A detective returns to the same archive twice and discovers that the room itself carries meaning.",
7+
"created_at": "2026-05-12T20:10:00Z",
8+
"settings": [
9+
{
10+
"id": "setting_precinct_archive",
11+
"name": "Precinct Archive",
12+
"description": "A dim archive room where unresolved cases gather institutional dust."
13+
}
14+
],
15+
"narratives": [
16+
{
17+
"id": "narrative_settings_demo",
18+
"title": "Central Narrative",
19+
"subtext": {
20+
"perspectives": [],
21+
"players": [],
22+
"dynamics": [],
23+
"storypoints": [],
24+
"storybeats": []
25+
},
26+
"storytelling": {
27+
"overviews": [],
28+
"moments": [
29+
{
30+
"id": "moment_archive_return",
31+
"summary": "The detective returns to the archive.",
32+
"synopsis": "A second visit to the archive reframes the old evidence as a personal warning.",
33+
"setting": "The same archive room, now colder and less familiar.",
34+
"setting_id": "setting_precinct_archive",
35+
"timing": "After midnight.",
36+
"imperatives": "Show that the shared place has taken on new meaning.",
37+
"storybeats": []
38+
}
39+
]
40+
}
41+
}
42+
]
43+
}
44+
}

examples/storypoint-throughline-both-refs.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"narratives": [
1010
{
1111
"id": "narrative_storypoint_throughline_with_perspective",
12+
"title": "Throughline Perspective Narrative",
1213
"subtext": {
1314
"perspectives": [
1415
{

examples/storypoint-throughline-empty-perspectives.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"narratives": [
1010
{
1111
"id": "narrative_storypoint_throughline_empty_perspectives",
12+
"title": "Throughline Placeholder Narrative",
1213
"subtext": {
1314
"perspectives": [],
1415
"players": [],

examples/the-shawshank-redemption.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@
179179
"id": "beat_shawshank_signpost_1",
180180
"scope": "signpost",
181181
"sequence": 1,
182-
"signpost": 1,
183182
"throughline": "Objective Story",
184183
"narrative_function": "Past",
185184
"summary": "Past convictions and institutional history define present constraints.",
@@ -194,7 +193,6 @@
194193
"id": "beat_shawshank_progression_6",
195194
"scope": "progression",
196195
"sequence": 6,
197-
"signpost": 2,
198196
"throughline": "Relationship Story",
199197
"narrative_function": "Trust",
200198
"summary": "Red and Andy move from caution toward mutual commitment.",

0 commit comments

Comments
 (0)