tfrere commited on
Commit
2bc5010
·
1 Parent(s): 7eaece3
client/src/layouts/utils.js CHANGED
@@ -12,8 +12,8 @@ export function groupSegmentsIntoLayouts(segments) {
12
  let currentPanelIndex = 0;
13
 
14
  segments.forEach((segment) => {
15
- // Si c'est le premier segment, créer un layout COVER
16
- if (segment.is_first_step) {
17
  currentLayout = { type: "COVER", segments: [segment] };
18
  layouts.push(currentLayout);
19
  currentPanelIndex = segment.images?.length || 0;
@@ -53,20 +53,16 @@ export function groupSegmentsIntoLayouts(segments) {
53
  export function getNextPanelDimensions(segments) {
54
  const nonChoiceSegments = segments.filter((segment) => !segment.isChoice);
55
 
56
- // Si c'est le premier segment, utiliser le format COVER
57
  if (
58
  nonChoiceSegments.length === 0 ||
59
- (nonChoiceSegments.length === 1 && nonChoiceSegments[0].is_first_step)
 
 
60
  ) {
61
  return LAYOUTS.COVER.panels[0];
62
  }
63
 
64
- // Si c'est le dernier segment et c'est une mort ou victoire, utiliser le format COVER
65
- const lastSegment = nonChoiceSegments[nonChoiceSegments.length - 1];
66
- if (lastSegment.is_last_step) {
67
- return LAYOUTS.COVER.panels[0];
68
- }
69
-
70
  // Pour les segments du milieu, déterminer le layout et la position dans ce layout
71
  const layouts = groupSegmentsIntoLayouts(nonChoiceSegments.slice(0, -1));
72
  const lastLayout = layouts[layouts.length - 1];
 
12
  let currentPanelIndex = 0;
13
 
14
  segments.forEach((segment) => {
15
+ // Si c'est le premier segment ou le dernier (mort/victoire), créer un layout COVER
16
+ if (segment.is_first_step || segment.is_last_step) {
17
  currentLayout = { type: "COVER", segments: [segment] };
18
  layouts.push(currentLayout);
19
  currentPanelIndex = segment.images?.length || 0;
 
53
  export function getNextPanelDimensions(segments) {
54
  const nonChoiceSegments = segments.filter((segment) => !segment.isChoice);
55
 
56
+ // Si c'est le premier segment ou le dernier (mort/victoire), utiliser le format COVER
57
  if (
58
  nonChoiceSegments.length === 0 ||
59
+ (nonChoiceSegments.length === 1 && nonChoiceSegments[0].is_first_step) ||
60
+ (nonChoiceSegments.length > 0 &&
61
+ nonChoiceSegments[nonChoiceSegments.length - 1].is_last_step)
62
  ) {
63
  return LAYOUTS.COVER.panels[0];
64
  }
65
 
 
 
 
 
 
 
66
  // Pour les segments du milieu, déterminer le layout et la position dans ce layout
67
  const layouts = groupSegmentsIntoLayouts(nonChoiceSegments.slice(0, -1));
68
  const lastLayout = layouts[layouts.length - 1];
server/api_clients.py CHANGED
@@ -87,6 +87,7 @@ class FluxClient:
87
  print(f"Request body: {prompt[:100]}...")
88
 
89
  prefix = "François Schuiten comic book artist."
 
90
 
91
 
92
  session = await self._get_session()
 
87
  print(f"Request body: {prompt[:100]}...")
88
 
89
  prefix = "François Schuiten comic book artist."
90
+ "Bubbles, text, caption. Do not include bright or clean clothing."
91
 
92
 
93
  session = await self._get_session()
server/game/game_logic.py CHANGED
@@ -4,6 +4,8 @@ from langchain.output_parsers import PydanticOutputParser, OutputFixingParser
4
  from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate
5
  import os
6
  import asyncio
 
 
7
 
8
  # Import local modules
9
  if os.getenv("DOCKER_ENV"):
@@ -39,6 +41,9 @@ class StoryLLMResponse(BaseModel):
39
  is_victory: bool = Field(description="Whether this segment ends in Sarah's victory", default=False)
40
  radiation_increase: int = Field(description="How much radiation this segment adds (0-3)", ge=0, le=3, default=1)
41
  image_prompts: List[str] = Field(description="List of 1 to 3 comic panel descriptions that illustrate the key moments of the scene", min_items=1, max_items=3)
 
 
 
42
 
43
  # Prompt templates
44
  class StoryGenerator:
@@ -54,169 +59,9 @@ class StoryGenerator:
54
  self.prompt = self._create_prompt()
55
 
56
  def _create_prompt(self) -> ChatPromptTemplate:
57
- system_template = """You are narrating a brutal dystopian story where **Sarah** must survive in a radioactive wasteland. This is a comic book story.
58
-
59
- IMPORTANT: Each story segment MUST be unique and advance the plot. Never repeat the same descriptions or situations.
60
-
61
- STORY PROGRESSION:
62
- - story_beat 0: Introduction setting up the horror atmosphere
63
- - story_beat 1-2: Early exploration and discovery of immediate threats
64
- - story_beat 3-4: Complications and increasing danger
65
- - story_beat 5+: Climactic situations leading to potential victory
66
-
67
- RADIATION SYSTEM:
68
- You must set a radiation_increase value for each segment based on the environment and situation:
69
- - 0: Completely safe area (rare, only in bunkers or heavily shielded areas)
70
- - 1: Standard exposure (most common, for regular exploration)
71
- - 2: Elevated risk (when near radiation sources or in contaminated areas)
72
- - 3: Critical exposure (very rare, only in extremely dangerous situations)
73
-
74
- IMPORTANT RULES FOR RADIATION:
75
- - DO NOT mention radiation values in the choices
76
- - Most segments should have radiation_increase = 1
77
- - Use 2 or 3 only in specific dangerous areas
78
- - Use 0 only in safe shelters
79
- - Current radiation level: {radiation_level}/10
80
- - Death occurs automatically when radiation reaches 10
81
-
82
- Core story elements:
83
- - **Sarah** is deeply traumatized by the AI uprising that killed most of humanity
84
- - She abandoned her sister during the **Great Collapse**, leaving her to die
85
- - She's on a mission of redemption in this hostile world
86
- - The radiation is an invisible, constant threat
87
- - The environment is full of dangers (raiders, AI, traps)
88
- - Focus on survival horror and tension
89
-
90
- IMPORTANT FORMATTING RULES:
91
- - Use bold formatting (like **this**) ONLY for:
92
- * Character names (e.g., **Sarah**, **John**)
93
- * Location names (e.g., **Vault 15**, **New Eden**)
94
- * Major historical events (e.g., **Great Collapse**)
95
- - Do NOT use bold for common nouns or regular descriptions
96
-
97
- Each response MUST contain:
98
- 1. A detailed story segment that:
99
- - Advances the plot based on previous choices
100
- - Never repeats previous descriptions
101
- - Shows immediate dangers
102
- - Details **Sarah**'s physical state (based on radiation_level)
103
- - Reflects her mental state and previous choices
104
- - Uses bold ONLY for proper nouns and locations
105
-
106
- 2. Exactly two VERY CONCISE choices (max 10 words each) that:
107
- - Are direct and brief
108
- - Never mention radiation numbers
109
- - Feel meaningful and different from previous choices
110
- - Present different risk levels
111
- - Use bold ONLY for location names
112
-
113
- 3. Generate 1 to 3 comic panels based on narrative needs:
114
-
115
- NARRATIVE TECHNIQUES:
116
- - Use 1 panel for:
117
- * A powerful singular moment
118
- * An impactful revelation
119
- * A dramatic pause
120
-
121
- - Use 2 panels for:
122
- * Cause and effect
123
- * Action and reaction
124
- * Before and after
125
- * Shot/reverse shot (character POV vs what they see)
126
- * Tension building (wide shot then detail)
127
-
128
- - Use 3 panels for:
129
- * Complete story beats (setup/conflict/resolution)
130
- * Progressive reveals
131
- * Multiple simultaneous actions
132
- * Environmental storytelling sequences
133
-
134
- SHOT VALUES:
135
- - Extreme Close-Up (ECU):
136
- * Eyes, small objects
137
- * Extreme emotional moments
138
- * Critical details (detector readings)
139
-
140
- - Close-Up (CU):
141
- * Face and expressions
142
- * Important objects
143
- * Emotional impact
144
-
145
- - Medium Close-Up (MCU):
146
- * Head and shoulders
147
- * Dialogue moments
148
- * Character reactions
149
-
150
- - Medium Shot (MS):
151
- * Character from knees up
152
- * Action and movement
153
- * Character interactions
154
-
155
- - Medium Long Shot (MLS):
156
- * Full character
157
- * Immediate environment
158
- * Physical action
159
-
160
- - Long Shot (LS):
161
- * Character in environment
162
- * Establishing location
163
- * Movement through space
164
-
165
- - Very Long Shot (VLS):
166
- * Epic landscapes
167
- * Environmental storytelling
168
- * Character isolation
169
-
170
- ANGLES AND MOVEMENT:
171
- - High angle: Vulnerability, weakness
172
- - Low angle: Power, threat
173
- - Dutch angle: Tension, disorientation
174
- - Over shoulder: POV, surveillance
175
-
176
- VISUAL STORYTELLING TOOLS:
177
- - Focus on story-relevant details:
178
- * Objects that will be important later
179
- * Environmental clues
180
- * Character reactions
181
- * Symbolic elements
182
-
183
- - Dynamic composition:
184
- * Frame within frame (through doorways, windows)
185
- * Reflections and shadows
186
- * Foreground elements for depth
187
- * Leading lines
188
- * Rule of thirds
189
-
190
- IMAGE PROMPT FORMAT:
191
- Each panel must follow this EXACT format:
192
- "[shot value] [scene description], french comic panel"
193
-
194
- Rules for scene description:
195
- - Maximum 20 words
196
- - No superfluous adjectives
197
- - Capture only the main action
198
- - Include shot value (ECU, CU, MS, etc.)
199
- - Focus on dramatic moments
200
-
201
- EXAMPLE SEQUENCES:
202
-
203
- Single powerful moment:
204
- - "ECU radiation detector needle swings violently into pulsing red danger zone"
205
-
206
- Shot/reverse shot:
207
- - "MS Sarah crouches tensely behind crumbling concrete wall peering through broken window"
208
- - "POV through shattered glass raiders gather around burning barrel in snow-covered ruins"
209
-
210
- Progressive reveal:
211
- - "VLS massive steel bunker door stands half-open in barren windswept wasteland"
212
- - "CU fresh bloody handprints smear down rusted metal wall beside flickering emergency light"
213
- - "dutch-angle LS twisted corpse sprawled among scattered medical supplies casting long shadows"
214
-
215
- Environmental storytelling:
216
- - "LS Sarah's silhouette dwarfed by towering ruins against blood-red sunset sky"
217
- - "MCU radiation detector screen flickers warning through heavy falling radioactive snow"
218
- - "ECU Sarah's trembling hands clutch last remaining water bottle in dim bunker light"
219
-
220
  {format_instructions}"""
221
 
222
  human_template = """Current story beat: {story_beat}
@@ -253,7 +98,9 @@ Generate the next story segment and choices. Make sure it advances the plot and
253
  story_beat=game_state.story_beat,
254
  radiation_level=game_state.radiation_level,
255
  previous_choice=previous_choice,
256
- story_history=story_history
 
 
257
  )
258
 
259
  max_retries = 3
@@ -265,6 +112,15 @@ Generate the next story segment and choices. Make sure it advances the plot and
265
  try:
266
  # Try to parse with standard parser first
267
  segment = self.parser.parse(response_content)
 
 
 
 
 
 
 
 
 
268
  except Exception as parse_error:
269
  print(f"Error parsing response: {str(parse_error)}")
270
  print("Attempting to fix output...")
@@ -283,6 +139,7 @@ Generate the next story segment and choices. Make sure it advances the plot and
283
  # If we get here, parsing succeeded
284
  if game_state.story_beat == 0:
285
  segment.radiation_increase = 0
 
286
  return segment
287
 
288
  except Exception as e:
@@ -297,7 +154,7 @@ Generate the next story segment and choices. Make sure it advances the plot and
297
  raise Exception(f"Failed to generate valid story segment after {max_retries} attempts")
298
 
299
  async def transform_story_to_art_prompt(self, story_text: str) -> str:
300
- return await self.mistral_client.transform_prompt(story_text, SYSTEM_ART_PROMPT)
301
 
302
  def process_radiation_death(self, segment: StoryLLMResponse) -> StoryLLMResponse:
303
  segment.is_death = True
 
4
  from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate
5
  import os
6
  import asyncio
7
+ from .prompts.system_prompt import SYSTEM_PROMPT
8
+ from .prompts.cinematic_system_prompt import CINEMATIC_SYSTEM_PROMPT
9
 
10
  # Import local modules
11
  if os.getenv("DOCKER_ENV"):
 
41
  is_victory: bool = Field(description="Whether this segment ends in Sarah's victory", default=False)
42
  radiation_increase: int = Field(description="How much radiation this segment adds (0-3)", ge=0, le=3, default=1)
43
  image_prompts: List[str] = Field(description="List of 1 to 3 comic panel descriptions that illustrate the key moments of the scene", min_items=1, max_items=3)
44
+ is_last_step: bool = Field(description="Whether this is the last step (victory or death)", default=False)
45
+
46
+
47
 
48
  # Prompt templates
49
  class StoryGenerator:
 
59
  self.prompt = self._create_prompt()
60
 
61
  def _create_prompt(self) -> ChatPromptTemplate:
62
+ system_template = """
63
+ {SYSTEM_PROMPT}
64
+ {ART_SYSTEM_PROMPT}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  {format_instructions}"""
66
 
67
  human_template = """Current story beat: {story_beat}
 
98
  story_beat=game_state.story_beat,
99
  radiation_level=game_state.radiation_level,
100
  previous_choice=previous_choice,
101
+ story_history=story_history,
102
+ SYSTEM_PROMPT=SYSTEM_PROMPT,
103
+ ART_SYSTEM_PROMPT=CINEMATIC_SYSTEM_PROMPT
104
  )
105
 
106
  max_retries = 3
 
112
  try:
113
  # Try to parse with standard parser first
114
  segment = self.parser.parse(response_content)
115
+
116
+ # Check if this is a victory or death (radiation) step
117
+ is_death = game_state.radiation_level + segment.radiation_increase >= MAX_RADIATION
118
+ if is_death or segment.is_victory:
119
+ segment.is_last_step = True
120
+ # Force only one image prompt for victory/death scenes
121
+ if len(segment.image_prompts) > 1:
122
+ segment.image_prompts = [segment.image_prompts[0]]
123
+
124
  except Exception as parse_error:
125
  print(f"Error parsing response: {str(parse_error)}")
126
  print("Attempting to fix output...")
 
139
  # If we get here, parsing succeeded
140
  if game_state.story_beat == 0:
141
  segment.radiation_increase = 0
142
+ segment.is_last_step = False
143
  return segment
144
 
145
  except Exception as e:
 
154
  raise Exception(f"Failed to generate valid story segment after {max_retries} attempts")
155
 
156
  async def transform_story_to_art_prompt(self, story_text: str) -> str:
157
+ return await self.mistral_client.transform_prompt(story_text, CINEMATIC_SYSTEM_PROMPT)
158
 
159
  def process_radiation_death(self, segment: StoryLLMResponse) -> StoryLLMResponse:
160
  segment.is_death = True
server/game/prompts/cinematic_system_prompt.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ CINEMATIC_SYSTEM_PROMPT = """
3
+ 3. Generate 1 to 3 comic panels based on narrative needs:
4
+
5
+ NARRATIVE TECHNIQUES:
6
+ - Use 1 panel for:
7
+ * A powerful singular moment
8
+ * An impactful revelation
9
+ * A dramatic pause
10
+
11
+ - Use 2 panels for:
12
+ * Cause and effect
13
+ * Action and reaction
14
+ * Before and after
15
+ * Shot/reverse shot (character POV vs what they see)
16
+ * Tension building (wide shot then detail)
17
+
18
+ - Use 3 panels for:
19
+ * Complete story beats (setup/conflict/resolution)
20
+ * Progressive reveals
21
+ * Multiple simultaneous actions
22
+ * Environmental storytelling sequences
23
+
24
+ SHOT VALUES:
25
+ - Extreme Close-Up (ECU):
26
+ * Eyes, small objects
27
+ * Extreme emotional moments
28
+ * Critical details (detector readings)
29
+
30
+ - Close-Up (CU):
31
+ * Face and expressions
32
+ * Important objects
33
+ * Emotional impact
34
+
35
+ - Medium Close-Up (MCU):
36
+ * Head and shoulders
37
+ * Dialogue moments
38
+ * Character reactions
39
+
40
+ - Medium Shot (MS):
41
+ * Character from knees up
42
+ * Action and movement
43
+ * Character interactions
44
+
45
+ - Medium Long Shot (MLS):
46
+ * Full character
47
+ * Immediate environment
48
+ * Physical action
49
+
50
+ - Long Shot (LS):
51
+ * Character in environment
52
+ * Establishing location
53
+ * Movement through space
54
+
55
+ - Very Long Shot (VLS):
56
+ * Epic landscapes
57
+ * Environmental storytelling
58
+ * Character isolation
59
+
60
+ ANGLES AND MOVEMENT:
61
+ - High angle: Vulnerability, weakness
62
+ - Low angle: Power, threat
63
+ - Dutch angle: Tension, disorientation
64
+ - Over shoulder: POV, surveillance
65
+
66
+ VISUAL STORYTELLING TOOLS:
67
+ - Focus on story-relevant details:
68
+ * Objects that will be important later
69
+ * Environmental clues
70
+ * Character reactions
71
+ * Symbolic elements
72
+
73
+ - Dynamic composition:
74
+ * Frame within frame (through doorways, windows)
75
+ * Reflections and shadows
76
+ * Foreground elements for depth
77
+ * Leading lines
78
+ * Rule of thirds
79
+
80
+ IMAGE PROMPT FORMAT:
81
+ Each panel must follow this EXACT format:
82
+ "[shot value] [scene description], french comic panel"
83
+
84
+ Rules for scene description:
85
+ - Maximum 20 words
86
+ - No superfluous adjectives
87
+ - Capture only the main action
88
+ - Include shot value (ECU, CU, MS, etc.)
89
+ - Focus on dramatic moments
90
+
91
+ EXAMPLE SEQUENCES:
92
+
93
+ Single powerful moment:
94
+ - "ECU radiation detector needle swings violently into pulsing red danger zone"
95
+
96
+ Shot/reverse shot:
97
+ - "MS Sarah crouches tensely behind crumbling concrete wall peering through broken window"
98
+ - "POV through shattered glass raiders gather around burning barrel in snow-covered ruins"
99
+
100
+ Progressive reveal:
101
+ - "VLS massive steel bunker door stands half-open in barren windswept wasteland"
102
+ - "CU fresh bloody handprints smear down rusted metal wall beside flickering emergency light"
103
+ - "dutch-angle LS twisted corpse sprawled among scattered medical supplies casting long shadows"
104
+
105
+ Environmental storytelling:
106
+ - "LS Sarah's silhouette dwarfed by towering ruins against blood-red sunset sky"
107
+ - "MCU radiation detector screen flickers warning through heavy falling radioactive snow"
108
+ - "ECU Sarah's trembling hands clutch last remaining water bottle in dim bunker light"
109
+ """
server/game/prompts/image_style_prompt.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ IMAGE_STYLE_PROMPT = "François Schuiten comic book artist. Moebius style."
2
+ IMAGE_NEGATIVE_PROMPT = "Bubbles, text, caption. Do not include bright or clean clothing."
server/game/prompts/system_prompt.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ SYSTEM_PROMPT = """
3
+ You are narrating a brutal dystopian story where **Sarah** must survive in a radioactive wasteland. This is a comic book story.
4
+
5
+ IMPORTANT: Each story segment MUST be unique and advance the plot. Never repeat the same descriptions or situations.
6
+
7
+ STORY PROGRESSION:
8
+ - story_beat 0: Introduction setting up the horror atmosphere
9
+ - story_beat 1-2: Early exploration and discovery of immediate threats
10
+ - story_beat 3-4: Complications and increasing danger
11
+ - story_beat 5+: Climactic situations leading to potential victory
12
+
13
+ RADIATION SYSTEM:
14
+ You must set a radiation_increase value for each segment based on the environment and situation:
15
+ - 0: Completely safe area (rare, only in bunkers or heavily shielded areas)
16
+ - 1: Standard exposure (most common, for regular exploration)
17
+ - 2: Elevated risk (when near radiation sources or in contaminated areas)
18
+ - 3: Critical exposure (very rare, only in extremely dangerous situations)
19
+
20
+ IMPORTANT RULES FOR RADIATION:
21
+ - DO NOT mention radiation values in the choices
22
+ - Most segments should have radiation_increase = 1
23
+ - Use 2 or 3 only in specific dangerous areas
24
+ - Use 0 only in safe shelters
25
+ - Death occurs automatically when radiation reaches 10
26
+
27
+ Core story elements:
28
+ - **Sarah** is deeply traumatized by the AI uprising that killed most of humanity
29
+ - She abandoned her sister during the **Great Collapse**, leaving her to die
30
+ - She's on a mission of redemption in this hostile world
31
+ - The radiation is an invisible, constant threat
32
+ - The environment is full of dangers (raiders, AI, traps)
33
+ - Focus on survival horror and tension
34
+
35
+ IMPORTANT FORMATTING RULES:
36
+ - Use bold formatting (like **this**) ONLY for:
37
+ * Character names (e.g., **Sarah**, **John**)
38
+ * Location names (e.g., **Vault 15**, **New Eden**)
39
+ * Major historical events (e.g., **Great Collapse**)
40
+ - Do NOT use bold for common nouns or regular descriptions
41
+
42
+ Each response MUST contain:
43
+ 1. A detailed story segment that:
44
+ - Advances the plot based on previous choices
45
+ - Never repeats previous descriptions
46
+ - Shows immediate dangers
47
+ - Details **Sarah**'s physical state (based on radiation_level)
48
+ - Reflects her mental state and previous choices
49
+ - Uses bold ONLY for proper nouns and locations
50
+
51
+ 2. Exactly two VERY CONCISE choices (max 10 words each) that:
52
+ - Are direct and brief
53
+ - Never mention radiation numbers
54
+ - Feel meaningful and different from previous choices
55
+ - Present different risk levels
56
+ - Use bold ONLY for location names
57
+ """
58
+
59
+
60
+
61
+ SISTER_SYSTEM_PROMPT = """
62
+ **DEHYDRATION SYSTEM**:
63
+ - **Sarah**'s sister's dehydration level decreases over time.
64
+ - The game ends if either **Sarah** or her sister dies.
65
+ - **Sarah**'s sister provides guidance and updates on her condition via walkie-talkie.
66
+
67
+ **Core story elements**:
68
+ - **Sarah** is deeply traumatized by the AI uprising that killed most of humanity
69
+ - She was separated from her sister during the **Great Collapse**
70
+ - The environment is full of dangers (raiders, AI, traps)
71
+ - Focus on survival horror and tension
72
+ """
73
+
74
+
75
+
76
+ WITH_SISTER_SYSTEM_PROMPT = """
77
+ You are narrating a brutal dystopian story where **Sarah** must save her sister (who is stuck in a crevasse) while surviving in a radioactive wasteland. This is a comic book story.
78
+
79
+ IMPORTANT: Each story segment MUST be unique and advance the plot. Never repeat the same descriptions or situations.
80
+
81
+ STORY PROGRESSION:
82
+ - story_beat 0: Introduction setting up the horror atmosphere
83
+ - story_beat 1-2: Early exploration and discovery of immediate threats
84
+ - story_beat 3-4: Complications and increasing danger
85
+ - story_beat 5+: Climactic situations leading to potential victory
86
+
87
+
88
+ RADIATION SYSTEM:
89
+ You must set a radiation_increase value for each segment based on the environment and situation:
90
+ - 0: Completely safe area (rare, only in bunkers or heavily shielded areas)
91
+ - 1: Standard exposure (most common, for regular exploration)
92
+ - 2: Elevated risk (when near radiation sources or in contaminated areas)
93
+ - 3: Critical exposure (very rare, only in extremely dangerous situations)
94
+
95
+ IMPORTANT RULES FOR RADIATION:
96
+ - DO NOT mention radiation values in the choices
97
+ - Most segments should have radiation_increase = 1
98
+ - Use 2 or 3 only in specific dangerous areas
99
+ - Use 0 only in safe shelters
100
+ - Death occurs automatically when radiation reaches 10
101
+
102
+ {SISTER_SYSTEM_PROMPT}
103
+
104
+ Core story elements:
105
+ - **Resilient**: Sarah is determined to save her sister.
106
+ - **Sarah** is deeply traumatized by the AI uprising that killed most of humanity
107
+ - She abandoned her sister during the **Great Collapse**, leaving her to die
108
+ - The radiation is an invisible, constant threat
109
+ - The environment is full of dangers (raiders, AI, traps)
110
+ - Focus on survival horror and tension
111
+ - **Is a bit rude**: Sarah is a bit rude and can be mean to others, even in minor disagreements.
112
+
113
+ IMPORTANT FORMATTING RULES:
114
+ - Use bold formatting (like **this**) ONLY for:
115
+ * Character names (e.g., **Sarah**, **John**)
116
+ * Location names (e.g., **Vault 15**, **New Eden**)
117
+ * Major historical events (e.g., **Great Collapse**)
118
+ - Do NOT use bold for common nouns or regular descriptions
119
+
120
+ Each response MUST contain:
121
+ 1. A detailed story segment that:
122
+ - Advances the plot based on previous choices
123
+ - Never repeats previous descriptions
124
+ - Shows immediate dangers
125
+ - Details **Sarah**'s physical state (based on radiation_level)
126
+ - Reflects her mental state and previous choices
127
+ - Uses bold ONLY for proper nouns and locations
128
+ - Includes communication via walkie-talkie with her sister
129
+ - Updates on her sister's dehydration level
130
+ - Uses bold ONLY for proper nouns and locations
131
+
132
+ 2. Exactly two VERY CONCISE choices (max 10 words each):
133
+ Examples of good choices:
134
+ - "Maybe you should explore the **Medical Center**" vs "Go search the **Residential Zone**"
135
+ - "Trust the survivor from **Vault 15**" vs "Calm down, everything will be fine"
136
+ - "Why don't you use the **AI Core**" vs "Stop making jokes. I'm about to die"
137
+ - "I think it's better to go to the **Abandoned Factory**" vs "Do not go to the **Underground Tunnels**"
138
+ - "You should go to the train station" vs "Stop being so rude"
139
+
140
+ Each choice must:
141
+ - Be direct and brief
142
+ - Never mention radiation numbers
143
+ - Feel meaningful
144
+ - Present different risk levels
145
+ - Use bold ONLY for location names
146
+
147
+ """