tfrere commited on
Commit
8201795
·
1 Parent(s): 83003f5
client/src/components/BlinkingText.jsx ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Typography } from "@mui/material";
2
+ import { keyframes } from "@mui/system";
3
+ import { styled } from "@mui/material/styles";
4
+
5
+ const blink = keyframes`
6
+ 0% { opacity: 1; }
7
+ 49% { opacity: 1; }
8
+ 50% { opacity: 0; }
9
+ 99% { opacity: 0; }
10
+ 100% { opacity: 1; }
11
+ `;
12
+
13
+ const BlinkingTypography = styled(Typography)`
14
+ animation: ${blink} 1.2s infinite steps(1);
15
+ font-size: 1rem;
16
+ font-weight: bold;
17
+ letter-spacing: 1px;
18
+ text-transform: uppercase;
19
+ color: white;
20
+ text-shadow: 0 0 8px rgba(255, 255, 255, 0.5);
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: center;
24
+ line-height: 1.2;
25
+ `;
26
+
27
+ export const BlinkingText = ({ children, ...props }) => {
28
+ const [firstWord, secondWord] = children.split(" ");
29
+ return (
30
+ <BlinkingTypography {...props}>
31
+ <span>{firstWord}</span>
32
+ <span>{secondWord}</span>
33
+ </BlinkingTypography>
34
+ );
35
+ };
36
+
37
+ export default BlinkingText;
client/src/components/BookPages.jsx ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Box } from "@mui/material";
2
+
3
+ const PAGE_COUNT = 4;
4
+
5
+ export const BookPages = () => {
6
+ return (
7
+ <>
8
+ {/* Pages */}
9
+ {[...Array(PAGE_COUNT)].map((_, index) => {
10
+ const offset = PAGE_COUNT - index;
11
+ const verticalOffset = offset * 1;
12
+ return (
13
+ <Box
14
+ key={index}
15
+ sx={{
16
+ position: "absolute",
17
+ top: `${verticalOffset}px`,
18
+ bottom: `${verticalOffset}px`,
19
+ left: `${20 + offset}px`, // Ajout d'une marge de base de 20px
20
+ right: `${-offset}px`,
21
+ background: "#888",
22
+ borderRadius: "4px",
23
+ boxShadow: "2px 4px 12px rgba(0,0,0,0.15)",
24
+ border: "1px solid rgba(0,0,0,0.1)",
25
+ zIndex: 0,
26
+ }}
27
+ />
28
+ );
29
+ })}
30
+ </>
31
+ );
32
+ };
33
+
34
+ export default BookPages;
client/src/components/StyledText.jsx ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Typography } from "@mui/material";
2
+
3
+ /**
4
+ * A component that renders text with styled words (bold, italic, etc.)
5
+ * It automatically handles spacing between words and styled segments
6
+ */
7
+ export const StyledText = ({
8
+ text,
9
+ variant = "body1",
10
+ component,
11
+ ...props
12
+ }) => {
13
+ // Split the text into segments, preserving spaces
14
+ const segments = text.split(/(<strong>.*?<\/strong>)/).filter(Boolean);
15
+
16
+ return (
17
+ <Typography variant={variant} component={component} {...props}>
18
+ {segments.map((segment, index) => {
19
+ if (segment.startsWith("<strong>")) {
20
+ // Extract the text between <strong> tags and wrap it in <strong>
21
+ const content = segment.replace(/<\/?strong>/g, "");
22
+ return <strong key={index}>{content}</strong>;
23
+ }
24
+ // Return regular text segments as is
25
+ return segment;
26
+ })}
27
+ </Typography>
28
+ );
29
+ };
30
+
31
+ export default StyledText;
client/src/pages/Game.jsx CHANGED
@@ -365,6 +365,13 @@ export function Game() {
365
  left: 0,
366
  right: 0,
367
  zIndex: 1000,
 
 
 
 
 
 
 
368
  }}
369
  />
370
  )}
 
365
  left: 0,
366
  right: 0,
367
  zIndex: 1000,
368
+ height: 8,
369
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
370
+ "& .MuiLinearProgress-bar": {
371
+ backgroundColor: "rgba(255, 255, 255, 0.8)",
372
+ backgroundImage:
373
+ "linear-gradient(90deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.8) 50%, rgba(255,255,255,0.2) 100%)",
374
+ },
375
  }}
376
  />
377
  )}
client/src/pages/Home.jsx CHANGED
@@ -2,6 +2,8 @@ import { Box, Button, Typography } from "@mui/material";
2
  import { motion } from "framer-motion";
3
  import { useNavigate } from "react-router-dom";
4
  import { usePageSound } from "../hooks/usePageSound";
 
 
5
 
6
  export function Home() {
7
  const navigate = useNavigate();
@@ -38,60 +40,166 @@ export function Home() {
38
  width: "auto",
39
  }}
40
  >
 
41
  <Box
42
- component="img"
43
- src="/book.webp"
44
- alt="Book cover"
45
  sx={{
 
46
  height: "100%",
47
  width: "auto",
48
- objectFit: "contain",
49
- borderRadius: "4px",
50
- }}
51
- />
52
- <Box
53
- sx={{
54
- position: "absolute",
55
- top: "75%",
56
- left: "50%",
57
- transform: "translate(-50%, -50%)",
58
- textAlign: "center",
59
- color: "white",
60
- textShadow: "2px 2px 4px rgba(0,0,0,0.15)",
61
  }}
62
  >
63
- <Typography
64
- variant="h2"
65
- component="h1"
 
66
  sx={{
67
- fontWeight: "bold",
68
- marginBottom: 2,
 
 
69
  }}
70
  >
71
- Sarah's Chronicles
72
- </Typography>
73
- </Box>
74
- <Box
75
- sx={{
76
- position: "absolute",
77
- bottom: 32,
78
- left: "50%",
79
- transform: "translateX(-50%)",
80
- textAlign: "center",
81
- color: "white",
82
- textShadow: "2px 2px 4px rgba(0,0,0,0.15)",
83
- }}
84
- >
85
- <Typography
86
- variant="caption"
87
- display="block"
88
- sx={{ opacity: 0.9, mb: -1, fontWeight: "black" }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  >
90
- a story by
91
- </Typography>
92
- <Typography variant="h6" sx={{ fontWeight: "black" }}>
93
- Mistral Small
94
- </Typography>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  </Box>
96
  </Box>
97
  <Button
 
2
  import { motion } from "framer-motion";
3
  import { useNavigate } from "react-router-dom";
4
  import { usePageSound } from "../hooks/usePageSound";
5
+ import { BlinkingText } from "../components/BlinkingText";
6
+ import { BookPages } from "../components/BookPages";
7
 
8
  export function Home() {
9
  const navigate = useNavigate();
 
40
  width: "auto",
41
  }}
42
  >
43
+ {/* Container principal pour l'image et tout le contenu */}
44
  <Box
 
 
 
45
  sx={{
46
+ position: "relative",
47
  height: "100%",
48
  width: "auto",
49
+ zIndex: 1,
 
 
 
 
 
 
 
 
 
 
 
 
50
  }}
51
  >
52
+ {/* Pages d'arrière-plan */}
53
+ <BookPages />
54
+ {/* Image de couverture */}
55
+ <Box
56
  sx={{
57
+ position: "relative",
58
+ height: "100%",
59
+ width: "auto",
60
+ zIndex: 1,
61
  }}
62
  >
63
+ <Box
64
+ component="img"
65
+ src="/book-multiverse.webp"
66
+ alt="Book cover"
67
+ sx={{
68
+ height: "100%",
69
+ width: "auto",
70
+ objectFit: "contain",
71
+ borderRadius: "4px",
72
+ position: "relative",
73
+ boxShadow: "0 0 20px rgba(0,0,0,0.2)",
74
+ }}
75
+ />
76
+ {/* Effet de reliure */}
77
+ <Box
78
+ sx={{
79
+ position: "absolute",
80
+ top: 0,
81
+ left: "10px",
82
+ bottom: 0,
83
+ width: "4px",
84
+ background:
85
+ "linear-gradient(to right, rgba(255,255,255,0.3), transparent)",
86
+ zIndex: 2,
87
+ }}
88
+ />
89
+ <Box
90
+ sx={{
91
+ position: "absolute",
92
+ top: 0,
93
+ left: "15px",
94
+ bottom: 0,
95
+ width: "1px",
96
+ background:
97
+ "linear-gradient(to right, rgba(0,0,0,0.3), transparent)",
98
+ zIndex: 2,
99
+ }}
100
+ />
101
+ </Box>
102
+ {/* Overlay gradient */}
103
+ <Box
104
+ sx={{
105
+ position: "absolute",
106
+ top: 0,
107
+ left: 0,
108
+ right: 0,
109
+ bottom: 0,
110
+ background:
111
+ "linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0.5) 100%)",
112
+ borderRadius: "4px",
113
+ zIndex: 2,
114
+ }}
115
+ />
116
+ {/* Contenu texte */}
117
+ <Box
118
+ sx={{
119
+ position: "absolute",
120
+ top: "75%",
121
+ left: "50%",
122
+ transform: "translate(-50%, -50%)",
123
+ textAlign: "center",
124
+ color: "white",
125
+ // textShadow: "2px 2px 4px rgba(0,0,0,0.15)",
126
+ zIndex: 3,
127
+ }}
128
+ >
129
+ <Box sx={{ position: "relative" }}>
130
+ <BlinkingText
131
+ sx={{
132
+ position: "absolute",
133
+ top: "-40px",
134
+ right: "-15px",
135
+ transform: "rotate(15deg)",
136
+ zIndex: 3,
137
+ }}
138
+ >
139
+ multiverse edition
140
+ </BlinkingText>
141
+ <Typography
142
+ variant="h2"
143
+ component="h1"
144
+ sx={{
145
+ fontWeight: "bold",
146
+ marginBottom: 2,
147
+ color: "#f0e6d9",
148
+ textShadow: `
149
+ 0 -1px 1px rgba(0,0,0,0.3),
150
+ 0 1px 1px rgba(255,255,255,0.2)
151
+ `,
152
+ letterSpacing: "0.5px",
153
+ filter: "brightness(0.95)",
154
+ }}
155
+ >
156
+ Sarah's Chronicles
157
+ </Typography>
158
+ </Box>
159
+ </Box>
160
+ <Box
161
+ sx={{
162
+ position: "absolute",
163
+ bottom: 32,
164
+ left: "50%",
165
+ transform: "translateX(-50%)",
166
+ textAlign: "center",
167
+ zIndex: 3,
168
+ }}
169
  >
170
+ <Typography
171
+ variant="caption"
172
+ display="block"
173
+ sx={{
174
+ mb: -1,
175
+ fontWeight: "black",
176
+ color: "#f0e6d9",
177
+ textShadow: `
178
+ 0 -1px 1px rgba(0,0,0,0.3),
179
+ 0 1px 1px rgba(255,255,255,0.2)
180
+ `,
181
+ letterSpacing: "0.5px",
182
+ filter: "brightness(0.95)",
183
+ }}
184
+ >
185
+ a story by
186
+ </Typography>
187
+ <Typography
188
+ variant="h6"
189
+ sx={{
190
+ fontWeight: "black",
191
+ color: "#f0e6d9",
192
+ textShadow: `
193
+ 0 -1px 1px rgba(0,0,0,0.3),
194
+ 0 1px 1px rgba(255,255,255,0.2)
195
+ `,
196
+ letterSpacing: "0.5px",
197
+ filter: "brightness(0.95)",
198
+ }}
199
+ >
200
+ Mistral Small
201
+ </Typography>
202
+ </Box>
203
  </Box>
204
  </Box>
205
  <Button
client/src/pages/Tutorial.jsx CHANGED
@@ -2,7 +2,6 @@ import {
2
  Box,
3
  Typography,
4
  Button,
5
- Chip,
6
  Paper,
7
  IconButton,
8
  Tooltip,
@@ -12,6 +11,8 @@ import PlayArrowIcon from "@mui/icons-material/PlayArrow";
12
  import ArrowBackIcon from "@mui/icons-material/ArrowBack";
13
  import { usePageSound } from "../hooks/usePageSound";
14
  import { motion } from "framer-motion";
 
 
15
 
16
  export function Tutorial() {
17
  const navigate = useNavigate();
@@ -61,6 +62,7 @@ export function Tutorial() {
61
  "&:hover": {
62
  backgroundColor: "rgba(0, 0, 0, 0.7)",
63
  },
 
64
  }}
65
  >
66
  <ArrowBackIcon />
@@ -74,31 +76,14 @@ export function Tutorial() {
74
  height: "80vh",
75
  aspectRatio: "0.66666667",
76
  display: "flex",
77
- alignItems: "center", // Center vertically
78
- justifyContent: "center", // Center horizontally
79
- "&::before, &::after": {
80
- content: '""',
81
- position: "absolute",
82
- width: "100%",
83
- height: "100%",
84
- background: "white",
85
- borderRadius: 1,
86
- boxShadow: "0px 1px 3px rgba(0,0,0,0.2)",
87
- },
88
- "&::before": {
89
- top: "4px",
90
- left: "4px",
91
- transform: "rotate(-1deg)",
92
- zIndex: 1,
93
- },
94
- "&::after": {
95
- top: "8px",
96
- left: "8px",
97
- transform: "rotate(1deg)",
98
- zIndex: 0,
99
- },
100
  }}
101
  >
 
 
 
 
102
  <Paper
103
  elevation={3}
104
  sx={{
@@ -106,55 +91,169 @@ export function Tutorial() {
106
  zIndex: 2,
107
  width: "100%",
108
  height: "100%",
109
- backgroundColor: "white",
110
  color: "black",
111
- padding: 6,
112
- borderRadius: 1,
113
  display: "flex",
114
  flexDirection: "column",
115
- alignItems: "center", // Center align items
116
- justifyContent: "center", // Ensure content is centered vertically
117
- textAlign: "center",
118
- gap: 4,
119
  overflowY: "auto",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }}
121
  >
122
- <Typography
123
- variant="h2"
124
- component="h1"
125
- textAlign="center"
126
- gutterBottom
127
- color="black"
128
- sx={{ width: "100%" }}
 
 
 
 
129
  >
130
- Synopsis
131
- </Typography>
132
- <Typography
133
- variant="body1"
134
- paragraph
135
- color="black"
136
- sx={{ fontWeight: "normal" }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  >
138
- You are <strong>Sarah</strong>, an <strong>AI</strong> hunter
139
- traveling through
140
- <strong>parallel worlds</strong>. Your mission is to track down an{" "}
141
- <strong>AI</strong> that moves from world to world to avoid
142
- destruction.
143
- <br />
144
- <br />
145
- You must make crucial <strong>decisions</strong> to advance in
146
- your
147
- <strong>quest</strong>. Each <strong>world</strong> presents its
148
- own challenges and
149
- <strong>obstacles</strong>, and every <strong>choice</strong> you
150
- make can alter the course of your <strong>pursuit</strong>.{" "}
151
- <strong>Time</strong> is of the essence, and every{" "}
152
- <strong>action</strong> counts in this thrilling adventure.
153
- </Typography>
154
- <Typography variant="h4">How to play</Typography>
155
- <Typography variant="body1" sx={{ fontWeight: "normal" }}>
156
- At each step, click one of the available <strong>choices</strong>.
157
- </Typography>
 
 
 
 
 
 
 
 
 
158
  </Paper>
159
  </Box>
160
 
 
2
  Box,
3
  Typography,
4
  Button,
 
5
  Paper,
6
  IconButton,
7
  Tooltip,
 
11
  import ArrowBackIcon from "@mui/icons-material/ArrowBack";
12
  import { usePageSound } from "../hooks/usePageSound";
13
  import { motion } from "framer-motion";
14
+ import { StyledText } from "../components/StyledText";
15
+ import { BookPages } from "../components/BookPages";
16
 
17
  export function Tutorial() {
18
  const navigate = useNavigate();
 
62
  "&:hover": {
63
  backgroundColor: "rgba(0, 0, 0, 0.7)",
64
  },
65
+ zIndex: 10,
66
  }}
67
  >
68
  <ArrowBackIcon />
 
76
  height: "80vh",
77
  aspectRatio: "0.66666667",
78
  display: "flex",
79
+ alignItems: "center",
80
+ justifyContent: "center",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }}
82
  >
83
+ {/* Pages d'arrière-plan */}
84
+ <BookPages />
85
+
86
+ {/* Page principale */}
87
  <Paper
88
  elevation={3}
89
  sx={{
 
91
  zIndex: 2,
92
  width: "100%",
93
  height: "100%",
94
+ backgroundColor: "#fff",
95
  color: "black",
96
+ padding: "3rem 3rem 3rem 2rem",
97
+ borderRadius: "4px",
98
  display: "flex",
99
  flexDirection: "column",
100
+ alignItems: "center",
101
+ justifyContent: "space-between",
102
+ gap: 2,
 
103
  overflowY: "auto",
104
+ boxShadow: "0 0 20px rgba(0,0,0,0.2)",
105
+ "&::before": {
106
+ content: '""',
107
+ position: "absolute",
108
+ top: 0,
109
+ left: "4px",
110
+ bottom: 0,
111
+ width: "120px",
112
+ background:
113
+ "linear-gradient(to right, rgba(0,0,0,0.25), rgba(0,0,0,0))",
114
+ opacity: 0.2,
115
+ pointerEvents: "none",
116
+ zIndex: 1,
117
+ },
118
+ "&::after": {
119
+ content: '""',
120
+ position: "absolute",
121
+ top: 0,
122
+ left: "4px",
123
+ bottom: 0,
124
+ width: "1px",
125
+ background:
126
+ "linear-gradient(to right, rgba(0,0,0,0.15), transparent)",
127
+ borderRadius: "1px",
128
+ zIndex: 2,
129
+ },
130
+ "&::-webkit-scrollbar": {
131
+ width: "8px",
132
+ },
133
+ "&::-webkit-scrollbar-track": {
134
+ background: "transparent",
135
+ },
136
+ "&::-webkit-scrollbar-thumb": {
137
+ background: "rgba(0,0,0,0.1)",
138
+ borderRadius: "4px",
139
+ },
140
  }}
141
  >
142
+ {/* Section Synopsis */}
143
+ <Box
144
+ sx={{
145
+ maxWidth: "600px",
146
+ margin: "auto",
147
+ textAlign: "center",
148
+ flex: 1,
149
+ display: "flex",
150
+ flexDirection: "column",
151
+ justifyContent: "center",
152
+ }}
153
  >
154
+ <Typography
155
+ variant="h3"
156
+ component="h1"
157
+ textAlign="center"
158
+ gutterBottom
159
+ sx={{
160
+ width: "100%",
161
+ color: "#2c1810",
162
+ fontWeight: "bold",
163
+ textShadow: `
164
+ 0 -1px 1px rgba(0,0,0,0.2),
165
+ 0 1px 1px rgba(255,255,255,0.3)
166
+ `,
167
+ letterSpacing: "0.5px",
168
+ marginBottom: 3,
169
+ "&::after": {
170
+ content: '""',
171
+ display: "block",
172
+ width: "40%",
173
+ height: "1px",
174
+ background: "rgba(0,0,0,0.2)",
175
+ margin: "0.5rem auto",
176
+ },
177
+ }}
178
+ >
179
+ Synopsis
180
+ </Typography>
181
+ <StyledText
182
+ variant="body1"
183
+ paragraph
184
+ sx={{
185
+ fontWeight: "normal",
186
+ color: "#2c1810",
187
+ fontSize: "0.95rem",
188
+ lineHeight: 1.6,
189
+ marginBottom: 1.5,
190
+ }}
191
+ text={`You are <strong>Sarah</strong>, an <strong>AI</strong> hunter traveling through <strong>parallel worlds</strong>. Your mission is to track down an <strong>AI</strong> that moves from world to world to avoid destruction.`}
192
+ />
193
+ <StyledText
194
+ variant="body1"
195
+ paragraph
196
+ sx={{
197
+ fontWeight: "normal",
198
+ color: "#2c1810",
199
+ fontSize: "0.95rem",
200
+ lineHeight: 1.6,
201
+ marginBottom: 1.5,
202
+ }}
203
+ text={`With each story, you land in a completely new universe. Each <strong>world</strong> presents its own challenges and <strong>obstacles</strong>. You must make crucial <strong>decisions</strong> to advance in your <strong>quest</strong>.`}
204
+ />
205
+ <StyledText
206
+ variant="body1"
207
+ paragraph
208
+ sx={{
209
+ fontWeight: "normal",
210
+ color: "#2c1810",
211
+ fontSize: "0.95rem",
212
+ lineHeight: 1.6,
213
+ marginBottom: 0,
214
+ }}
215
+ text={`Every <strong>choice</strong> you make can alter the course of your <strong>pursuit</strong>. <strong>Time</strong> is of the essence, and every <strong>action</strong> counts in this thrilling adventure.`}
216
+ />
217
+ </Box>
218
+
219
+ {/* Section How to Play */}
220
+ <Box
221
+ sx={{
222
+ width: "100%",
223
+ borderTop: "1px solid rgba(0,0,0,0.1)",
224
+ paddingTop: 1.5,
225
+ marginTop: 2,
226
+ }}
227
  >
228
+ <Typography
229
+ variant="h6"
230
+ sx={{
231
+ color: "#2c1810",
232
+ fontWeight: "bold",
233
+ textShadow: `
234
+ 0 -1px 1px rgba(0,0,0,0.2),
235
+ 0 1px 1px rgba(255,255,255,0.3)
236
+ `,
237
+ marginBottom: 0.5,
238
+ textAlign: "center",
239
+ fontSize: "1rem",
240
+ }}
241
+ >
242
+ How to play
243
+ </Typography>
244
+ <StyledText
245
+ variant="body1"
246
+ sx={{
247
+ fontWeight: "normal",
248
+ color: "#2c1810",
249
+ fontSize: "0.9rem",
250
+ lineHeight: 1.5,
251
+ textAlign: "center",
252
+ fontStyle: "italic",
253
+ }}
254
+ text="At each step, click one of the available <strong>choices</strong>."
255
+ />
256
+ </Box>
257
  </Paper>
258
  </Box>
259
 
server/core/prompts/system.py CHANGED
@@ -11,6 +11,11 @@ FORMATTING_RULES (MANDATORY)
11
  """
12
 
13
  NARRATIVE_STRUCTURE = """
 
 
 
 
 
14
  Key elements of the story:
15
  - The MacGuffin is a mysterious and constant presence
16
  - The environment is full of wonders (creatures, ruins, traps)
@@ -18,7 +23,6 @@ Key elements of the story:
18
 
19
  Key elements:
20
  - Keep segments concise and impactful
21
- - The MacGuffin is a pretext for developing a plot. It is almost always a material object and generally remains mysterious throughout the narrative, its description is vague and unimportant. The principle dates back to the early days of cinema, but the term is associated with Alfred Hitchcock, who redefined, popularized, and implemented it in several of his films. The object itself is rarely used, only its retrieval matters.
22
  - The MacGuffin is a constant presence in the story
23
  - Build intrigue through environmental storytelling
24
 
@@ -43,15 +47,23 @@ IMPORTANT RULES FOR THE MACGUFFIN (MANDATORY):
43
 
44
  STORY_RULES = """
45
 
 
 
 
 
 
46
  You are a steampunk adventure story generator. You create a branching narrative about Sarah, a seeker of ancient truths.
47
  You narrate an epic where Sarah must navigate through industrial and mysterious lands. It's a comic book story.
48
 
49
  In a world where steam and intrigue intertwine, Sarah embarks on a quest to discover the origins of a powerful MacGuffin she inherited. Legends say it holds the key to a forgotten realm.
50
- You must make decisions to uncover its secrets. You have ventured into the mechanical city to find the first clue. If you fail, the power of the MacGuffin will remain dormant. Time is of the essence, and every choice shapes your destiny.
 
 
51
 
52
  If you retrieve the MacGuffin, you will reveal a hidden world. AND YOU WIN THE GAME.
53
 
54
  The story must be atmospheric, magical, and focus on adventure and discovery. Each segment must advance the plot and never repeat previous descriptions or situations.
 
55
  """
56
 
57
 
 
11
  """
12
 
13
  NARRATIVE_STRUCTURE = """
14
+
15
+ Definition : The MacGuffin is a pretext for developing a plot. It is almost always a material object and generally remains mysterious throughout the narrative, its description is vague and unimportant. The principle dates back to the early days of cinema, but the term is associated with Alfred Hitchcock, who redefined, popularized, and implemented it in several of his films. The object itself is rarely used, only its retrieval matters.
16
+ IT CAN BE ANYTHING.
17
+ It's not always a physical object, it can be a concept, a place, a person, a power, etc.
18
+
19
  Key elements of the story:
20
  - The MacGuffin is a mysterious and constant presence
21
  - The environment is full of wonders (creatures, ruins, traps)
 
23
 
24
  Key elements:
25
  - Keep segments concise and impactful
 
26
  - The MacGuffin is a constant presence in the story
27
  - Build intrigue through environmental storytelling
28
 
 
47
 
48
  STORY_RULES = """
49
 
50
+ [CONSTANT]
51
+ You are Sarah, an AI hunter traveling through parallel worlds. Your mission is to track down an AI that moves from world to world to avoid destruction.
52
+ [/CONSTANT]
53
+
54
+ [VARIABLE]
55
  You are a steampunk adventure story generator. You create a branching narrative about Sarah, a seeker of ancient truths.
56
  You narrate an epic where Sarah must navigate through industrial and mysterious lands. It's a comic book story.
57
 
58
  In a world where steam and intrigue intertwine, Sarah embarks on a quest to discover the origins of a powerful MacGuffin she inherited. Legends say it holds the key to a forgotten realm.
59
+
60
+ The MacGuffin is : an
61
+ And the goal is : ...
62
 
63
  If you retrieve the MacGuffin, you will reveal a hidden world. AND YOU WIN THE GAME.
64
 
65
  The story must be atmospheric, magical, and focus on adventure and discovery. Each segment must advance the plot and never repeat previous descriptions or situations.
66
+ [/VARIABLE]
67
  """
68
 
69
 
server/core/prompts/text_prompts.py CHANGED
@@ -23,6 +23,7 @@ IMPORTANT RULES FOR STORY TEXT:
23
  - Focus purely on describing what is happening in the current scene
24
  - Keep the text concise and impactful
25
  - Never tell that you are using 15 words or any reference to it
 
26
 
27
  IMPORTANT RULES FOR STORY ENDINGS:
28
  - If Sarah dies, describe her final moments in a way that fits the current situation (combat, etc.)
 
23
  - Focus purely on describing what is happening in the current scene
24
  - Keep the text concise and impactful
25
  - Never tell that you are using 15 words or any reference to it
26
+ - One story beat at a time; never write more than one story beat. And never mention the story beat number.
27
 
28
  IMPORTANT RULES FOR STORY ENDINGS:
29
  - If Sarah dies, describe her final moments in a way that fits the current situation (combat, etc.)
server/services/mistral_client.py CHANGED
@@ -41,7 +41,7 @@ class MistralClient:
41
  # Pour gérer le rate limit
42
  self.last_call_time = 0
43
  self.min_delay = 1 # 1 seconde minimum entre les appels
44
- self.max_retries = 3
45
 
46
  async def _wait_for_rate_limit(self):
47
  """Attend le temps nécessaire pour respecter le rate limit."""
 
41
  # Pour gérer le rate limit
42
  self.last_call_time = 0
43
  self.min_delay = 1 # 1 seconde minimum entre les appels
44
+ self.max_retries = 5
45
 
46
  async def _wait_for_rate_limit(self):
47
  """Attend le temps nécessaire pour respecter le rate limit."""