reflexive 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,162 @@
1
+ // Noir Detective Mystery Story
2
+ // Generated by Reflexive AI Story Builder
3
+ // Theme: Mystery | Tone: Dramatic Noir Detective
4
+
5
+ import { StoryGameBuilder, StorySimulator } from './one-shot.js';
6
+
7
+ function createDetectiveMysteryStory() {
8
+ const builder = new StoryGameBuilder();
9
+
10
+ // Define story arcs
11
+ builder
12
+ .addArc('detective', { name: 'Professional Detective', weight: 1.0 })
13
+ .addArc('personal', { name: 'Personal Vendetta', weight: 1.0 })
14
+ .addArc('corrupt', { name: 'Corruption Path', weight: 1.0 })
15
+ .addArc('vigilante', { name: 'Vigilante Justice', weight: 1.0 });
16
+
17
+ // Build story nodes
18
+ builder
19
+ .addNode('crime_scene', {
20
+ text: "The body lies in the rain. Victoria Chen, tech mogul, murdered in her own penthouse. The killer left no trace—except a black orchid on her chest.",
21
+ arcTags: []
22
+ })
23
+ .addNode('by_the_book', {
24
+ text: "You call in forensics and secure the scene. This will be done properly, legally. The evidence will speak.",
25
+ arcTags: ['detective'],
26
+ onEnter: (state) => { state.evidence = (state.evidence || 0) + 5; state.reputation = (state.reputation || 0) + 10; }
27
+ })
28
+ .addNode('personal_connection', {
29
+ text: "Victoria was your informant. She called you hours before she died, terrified. You ignored it. Now she's dead—and you need answers.",
30
+ arcTags: ['personal'],
31
+ onEnter: (state) => { state.guilt = 10; state.determination = 15; }
32
+ })
33
+ .addNode('accept_bribe', {
34
+ text: "A man in an expensive suit offers you an envelope. 'Walk away, detective. Some cases aren't meant to be solved.' The money could change your life.",
35
+ arcTags: ['corrupt'],
36
+ onEnter: (state) => { state.money = (state.money || 0) + 50000; state.corruption = 10; }
37
+ })
38
+ .addNode('off_the_books', {
39
+ text: "You pocket evidence before forensics arrives. You'll solve this yourself, outside the system. No bureaucracy, no delays, no mercy.",
40
+ arcTags: ['vigilante'],
41
+ onEnter: (state) => { state.evidence = 3; state.rogue = true; }
42
+ })
43
+ .addNode('the_suspect', {
44
+ text: "All roads lead to Marcus Veil, Victoria's business partner. He has motive, opportunity, and a smile that doesn't reach his eyes.",
45
+ arcTags: []
46
+ })
47
+ .addNode('interrogation_room', {
48
+ text: "Marcus sits across from you in the interrogation room. He knows you have nothing solid. 'Prove it, detective,' he whispers.",
49
+ arcTags: []
50
+ })
51
+ .addNode('detective_triumph', {
52
+ text: "The evidence chain is perfect. Marcus Veil is convicted. Justice served, career intact. But Victoria's last words still haunt you: 'He's not working alone.'",
53
+ arcTags: ['detective']
54
+ })
55
+ .addNode('revenge_complete', {
56
+ text: "You found the truth: Victoria died because she knew too much. You delivered justice outside the courtroom. She can rest now. So can you.",
57
+ arcTags: ['personal']
58
+ })
59
+ .addNode('compromised', {
60
+ text: "The money kept coming. You buried evidence, lost yourself. Marcus walks free. You're rich, hollow, and owned. The black orchid arrives at your door.",
61
+ arcTags: ['corrupt']
62
+ });
63
+
64
+ // Add choices with arc modifiers
65
+ builder
66
+ .addChoice('crime_scene', {
67
+ text: 'Call it in by the book',
68
+ target: 'by_the_book',
69
+ weight: 1.0,
70
+ arcModifiers: { detective: 2.5 }
71
+ })
72
+ .addChoice('crime_scene', {
73
+ text: 'Remember she was your informant',
74
+ target: 'personal_connection',
75
+ weight: 1.0,
76
+ arcModifiers: { personal: 2.5 }
77
+ })
78
+ .addChoice('crime_scene', {
79
+ text: 'Accept the mysterious offer',
80
+ target: 'accept_bribe',
81
+ weight: 1.0,
82
+ arcModifiers: { corrupt: 2.5 }
83
+ })
84
+ .addChoice('crime_scene', {
85
+ text: 'Pocket key evidence quietly',
86
+ target: 'off_the_books',
87
+ weight: 1.0,
88
+ arcModifiers: { vigilante: 2.5 }
89
+ });
90
+
91
+ builder
92
+ .addChoice('by_the_book', {
93
+ text: 'Follow the evidence',
94
+ target: 'the_suspect',
95
+ weight: 1.0
96
+ })
97
+ .addChoice('personal_connection', {
98
+ text: 'Chase every lead',
99
+ target: 'the_suspect',
100
+ weight: 1.0
101
+ })
102
+ .addChoice('off_the_books', {
103
+ text: 'Hunt him down',
104
+ target: 'the_suspect',
105
+ weight: 1.0
106
+ });
107
+
108
+ builder
109
+ .addChoice('the_suspect', {
110
+ text: 'Bring him in for questioning',
111
+ target: 'interrogation_room',
112
+ weight: 1.0
113
+ });
114
+
115
+ builder
116
+ .addChoice('interrogation_room', {
117
+ text: 'Build the perfect case',
118
+ target: 'detective_triumph',
119
+ weight: 1.0,
120
+ arcModifiers: { detective: 3.0 },
121
+ weightFormula: (state, arcWeights) => {
122
+ return (arcWeights.get('detective') || 1.0) * 2.0;
123
+ },
124
+ condition: (state) => state.evidence >= 5
125
+ })
126
+ .addChoice('interrogation_room', {
127
+ text: 'Take matters into your own hands',
128
+ target: 'revenge_complete',
129
+ weight: 1.0,
130
+ arcModifiers: { personal: 2.0, vigilante: 2.0 },
131
+ weightFormula: (state, arcWeights) => {
132
+ const personalWeight = arcWeights.get('personal') || 1.0;
133
+ const vigilanteWeight = arcWeights.get('vigilante') || 1.0;
134
+ return Math.max(personalWeight, vigilanteWeight) * 1.5;
135
+ }
136
+ });
137
+
138
+ builder
139
+ .addChoice('accept_bribe', {
140
+ text: 'Take more money, bury deeper',
141
+ target: 'compromised',
142
+ weight: 1.0
143
+ });
144
+
145
+ return builder.getGame();
146
+ }
147
+
148
+ // Export for use
149
+ export { createDetectiveMysteryStory };
150
+
151
+ // If run directly, start the game
152
+ if (import.meta.url === `file://${process.argv[1]}`) {
153
+ const game = createDetectiveMysteryStory();
154
+ console.log('🕵️ NOIR DETECTIVE MYSTERY');
155
+ console.log('Generated by Reflexive AI\n');
156
+ console.log(`Story: ${game.nodes.length} nodes, ${game.arcs.length} arcs\n`);
157
+
158
+ const simulator = new StorySimulator(game);
159
+ simulator.start('crime_scene');
160
+
161
+ console.log('Use the main one-shot.js interface to play this story!');
162
+ }