cosimotaiuti commited on
Commit
601f069
·
verified ·
1 Parent(s): c8e039e

Upload 114 files

Browse files
static/.DS_Store CHANGED
Binary files a/static/.DS_Store and b/static/.DS_Store differ
 
static/assets/.DS_Store CHANGED
Binary files a/static/assets/.DS_Store and b/static/assets/.DS_Store differ
 
static/assets/css/game-style.css CHANGED
@@ -8,7 +8,9 @@
8
  position: relative;
9
  overflow: hidden;
10
  }
11
-
 
 
12
  #gameContainer {
13
  display: flex;
14
  width: 100%;
 
8
  position: relative;
9
  overflow: hidden;
10
  }
11
+ * {
12
+ opacity: 0.98;
13
+ }
14
  #gameContainer {
15
  display: flex;
16
  width: 100%;
static/assets/css/how-to-play.css CHANGED
@@ -10,7 +10,9 @@
10
  align-items: center;
11
  margin-top: 20px;
12
  }
13
-
 
 
14
  .content h1 {
15
  font-family: "HorrorBrush", cursive;
16
  font-size: 64px;
 
10
  align-items: center;
11
  margin-top: 20px;
12
  }
13
+ * {
14
+ opacity: 0.98;
15
+ }
16
  .content h1 {
17
  font-family: "HorrorBrush", cursive;
18
  font-size: 64px;
static/assets/css/index-style.css CHANGED
@@ -7,8 +7,8 @@
7
  margin: 0;
8
  padding: 0;
9
  box-sizing: border-box;
 
10
  }
11
-
12
  body {
13
  background-color: #000000;
14
  min-height: 100vh;
 
7
  margin: 0;
8
  padding: 0;
9
  box-sizing: border-box;
10
+ opacity: 0.98;
11
  }
 
12
  body {
13
  background-color: #000000;
14
  min-height: 100vh;
static/game/elmnts/character.js CHANGED
@@ -15,6 +15,10 @@ class Character {
15
  return this.characterPos;
16
  }
17
 
 
 
 
 
18
  setCharacterPosition(pos) {
19
  this.characterPos = pos;
20
  }
@@ -72,6 +76,7 @@ class Character {
72
  this.previousPos = { ...this.characterPos };
73
  const nextPos = this.path.shift();
74
  this.characterPos = nextPos;
 
75
  }, this.speed);
76
  }
77
 
 
15
  return this.characterPos;
16
  }
17
 
18
+ moving_check() {
19
+
20
+ }
21
+
22
  setCharacterPosition(pos) {
23
  this.characterPos = pos;
24
  }
 
76
  this.previousPos = { ...this.characterPos };
77
  const nextPos = this.path.shift();
78
  this.characterPos = nextPos;
79
+ this.moving_check();
80
  }, this.speed);
81
  }
82
 
static/game/elmnts/furniture.js CHANGED
@@ -110,10 +110,7 @@ function getFurniture() {
110
  },
111
  "state": "searchable",
112
  "in_use": true,
113
- "key":"Desk Note",
114
- "reward":"Flashlight",
115
- "locked_msg":"There's like a shit ton of books in here in a bunch of different colors, i have no idea what i'm looking for... 😵‍💫",
116
- "unlocked_msg":"Got the pink book. Looks like it's hollowed out and there's a flashlight inside 🔦. WEIRD?? there's also some writing here that says the mouth holds the key. omg that's so creepy wtf",
117
  "sprite": [
118
  {
119
  "for": "searchable",
@@ -137,7 +134,7 @@ function getFurniture() {
137
  "x": 3,
138
  "y": 2
139
  },
140
- "state": "off",
141
  "in_use": false,
142
  "sprite": [
143
  {
@@ -160,8 +157,8 @@ function getFurniture() {
160
  "state": "usable",
161
  "in_use": true,
162
  "key":"Knife",
163
- "locked_msg":"um... what. the. fuck. IS THIS A DEAD BODY?? WHO ARE YOU??",
164
- "unlocked_msg":"no no no no no ew ew ew ew whyyyyyyy...😭😭😭 theres a note here that says NEO. why the f was there a note in its mouth??",
165
  "sprite": [
166
  {
167
  "for": "usable",
@@ -205,7 +202,7 @@ function getFurniture() {
205
  "state": "searchable",
206
  "in_use": true,
207
  "reward":"knife",
208
- "search_msg":"Omg a knife 🔪... ill take it but there's no way i'm fighting that thing u can't make me ok?? ",
209
  "sprite": [
210
  {
211
  "for": "searchable",
@@ -259,32 +256,8 @@ function getFurniture() {
259
  "img": "/assets/img/appartment/stoveunsearchable.png"
260
  }
261
  ]
262
- },{
263
- "name":"Storage Shade",
264
- "room":"Storage",
265
- "wall_pos": {
266
- "x": 6,
267
- "y": 3
268
- },
269
- "stop_pos":{
270
- "x": 7,
271
- "y": 3
272
- },
273
- "state":"locked",
274
- "in_use": false,
275
- "locked_message":"No no no theres no way im going in there its dark as shit and its already fking scary out here ",
276
- "unlocked_message":"Ok here goes...",
277
- "sprite": [
278
- {
279
- "for": "locked",
280
- "img": "/assets/img/appartment/storagelocked.png"
281
- },
282
- {
283
- "for": "unlocked",
284
- "img": "/assets/img/appartment/storageunlocked.png"
285
- }
286
- ]
287
- },{
288
  "name":"The Exit",
289
  "room":"Main Hallway",
290
  "in_use": true,
 
110
  },
111
  "state": "searchable",
112
  "in_use": true,
113
+ "msg":"There's nothing useful in here...",
 
 
 
114
  "sprite": [
115
  {
116
  "for": "searchable",
 
134
  "x": 3,
135
  "y": 2
136
  },
137
+ "state": "on",
138
  "in_use": false,
139
  "sprite": [
140
  {
 
157
  "state": "usable",
158
  "in_use": true,
159
  "key":"Knife",
160
+ "locked_msg":"Um... what. the. f. Why is its mouth stitched up? Is the key inside??? i cant open it",
161
+ "unlocked_msg":"No no no ew ew i can't believe im doing this...😭😭😭 ....the key was in here i got it!! I can get out!",
162
  "sprite": [
163
  {
164
  "for": "usable",
 
202
  "state": "searchable",
203
  "in_use": true,
204
  "reward":"knife",
205
+ "msg":"Omg a knife 🔪... i just took it but there's no way i can kill the creature with this.",
206
  "sprite": [
207
  {
208
  "for": "searchable",
 
256
  "img": "/assets/img/appartment/stoveunsearchable.png"
257
  }
258
  ]
259
+ }
260
+ ,{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  "name":"The Exit",
262
  "room":"Main Hallway",
263
  "in_use": true,
static/game/elmnts/girlfriend.js CHANGED
@@ -1,146 +1,197 @@
1
  class Girlfriend extends Character {
2
- constructor(gameState, girlfriendImg) {
3
- super(gameState, girlfriendImg);
4
- this.gameState = gameState;
5
- this.gameState.girlfriend = this;
6
- this.img = girlfriendImg;
7
- this.setCharacterPosition(this.gameState.map_data.girlfriend_start_pos);
8
- this.currentHidingSpot = null;
9
- this.stressLevel = 30;
10
- this.inventory = [];
11
- }
12
-
13
- draw(CELL_SIZE) {
14
- if (this.characterPos) {
15
- push();
16
- if (this.previousPos && this.characterPos.x > this.previousPos.x) {
17
- scale(-1, 1);
18
- image(
19
- this.img,
20
- -this.characterPos.x * CELL_SIZE - CELL_SIZE * 2,
21
- this.characterPos.y * CELL_SIZE,
22
- CELL_SIZE * 2,
23
- CELL_SIZE * 2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  );
25
- } else {
26
- if (this.getIsHiding()) {
27
- tint(255, 153);
28
- image(
29
- this.img,
30
- this.characterPos.x * CELL_SIZE,
31
- this.characterPos.y * CELL_SIZE,
32
- CELL_SIZE * 2,
33
- CELL_SIZE * 2
34
- );
35
- } else {
36
- image(
37
- this.img,
38
- this.characterPos.x * CELL_SIZE,
39
- this.characterPos.y * CELL_SIZE,
40
- CELL_SIZE * 2,
41
- CELL_SIZE * 2
42
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
- }
45
- pop();
46
  }
47
- }
48
-
49
- updateStressLevel(stressChange) {
50
- // Add or subtract the stress change while keeping within 0-100 range
51
- this.stressLevel = Math.max(
52
- 0,
53
- Math.min(100, this.stressLevel + stressChange)
54
- );
55
- }
56
-
57
- handleAction(response) {
58
- switch (response.action) {
59
- case "go":
60
- this.moveToRoom(response.target);
61
- break;
62
- case "hide":
63
- this.hide(response.target);
64
- break;
65
- case "exit":
66
- this.exit();
67
- break;
68
  }
69
- }
70
-
71
- getAvailableHidingSpots() {
72
- // Find the current room in map data
73
- const currentRoom = this.gameState.map_data.rooms.find(
74
- (room) => room.name === this.getCurrentRoom()
75
- );
76
- // Return hiding places for current room if found, otherwise empty array
77
- return currentRoom ? currentRoom.hiding_places : [];
78
- }
79
-
80
- getAvailableFurniture() {
81
- // Get current room
82
- const currentRoom = this.getCurrentRoom();
83
- if (!currentRoom) return [];
84
-
85
- // Filter furniture list to only include items in current room that are in use
86
- return this.gameState.map_data.furniture.filter(
87
- furniture => furniture.room === currentRoom && furniture.in_use === true
88
- );
89
- }
90
-
91
- getIsHiding() {
92
- const hidingSpots = this.getAvailableHidingSpots();
93
- if (!this.characterPos || hidingSpots.length === 0) return false;
94
-
95
- return hidingSpots.some(
96
- (spot) =>
97
- spot.position.x === this.characterPos.x &&
98
- spot.position.y === this.characterPos.y
99
- );
100
- }
101
-
102
- hide(hidingSpotName) {
103
- const currentRoom = this.getCurrentRoom();
104
- if (!currentRoom) return;
105
-
106
- // Find the room data from map_data
107
- const roomData = this.gameState.map_data.rooms.find(
108
- (room) => room.name === currentRoom
109
- );
110
- if (!roomData) return;
111
-
112
- // Find the specific hiding spot in the room by checking if names contain each other
113
- const hidingSpot = roomData.hiding_places.find(
114
- (spot) =>
115
- spot.name
116
- .toLowerCase()
117
- .trim()
118
- .includes(hidingSpotName.toLowerCase().trim()) ||
119
- hidingSpotName
120
- .toLowerCase()
121
- .trim()
122
- .includes(spot.name.toLowerCase().trim())
123
- );
124
-
125
- if (!hidingSpot) return;
126
-
127
- // Move to the hiding spot position
128
- this.moveToPosition(hidingSpot.position, () => {
129
- this.currentHidingSpot = hidingSpotName;
130
- });
131
- }
132
-
133
- exit() {
134
- let the_exit = this.gameState.getTheExit();
135
- let x = the_exit.pos.x;
136
- let y = the_exit.pos.y-1;
137
- let pos = {"x": x, "y": y};
138
- this.moveToPosition(pos, () => {
139
- if (!this.inventory || !this.inventory.includes("Key")) {
140
- addProgramaticMessage(the_exit.locked_message);
141
- } else {
142
- addProgramaticMessage(the_exit.unlocked_message);
143
- }
144
- });
145
- }
146
  }
 
1
  class Girlfriend extends Character {
2
+ constructor(gameState, girlfriendImg) {
3
+ super(gameState, girlfriendImg);
4
+ this.gameState = gameState;
5
+ this.gameState.girlfriend = this;
6
+ this.img = girlfriendImg;
7
+ this.setCharacterPosition(this.gameState.map_data.girlfriend_start_pos);
8
+ this.currentHidingSpot = null;
9
+ this.stressLevel = 30;
10
+ this.inventory = [];
11
+ this.knows_about_dead_body = false;
12
+ }
13
+
14
+ draw(CELL_SIZE) {
15
+ if (this.characterPos) {
16
+ push();
17
+ if (this.previousPos && this.characterPos.x > this.previousPos.x) {
18
+ scale(-1, 1);
19
+ image(
20
+ this.img,
21
+ -this.characterPos.x * CELL_SIZE - CELL_SIZE * 2,
22
+ this.characterPos.y * CELL_SIZE,
23
+ CELL_SIZE * 2,
24
+ CELL_SIZE * 2
25
+ );
26
+ } else {
27
+ if (this.getIsHiding()) {
28
+ tint(255, 153);
29
+ image(
30
+ this.img,
31
+ this.characterPos.x * CELL_SIZE,
32
+ this.characterPos.y * CELL_SIZE,
33
+ CELL_SIZE * 2,
34
+ CELL_SIZE * 2
35
+ );
36
+ } else {
37
+ image(
38
+ this.img,
39
+ this.characterPos.x * CELL_SIZE,
40
+ this.characterPos.y * CELL_SIZE,
41
+ CELL_SIZE * 2,
42
+ CELL_SIZE * 2
43
+ );
44
+ }
45
+ }
46
+ pop();
47
+ }
48
+ }
49
+
50
+ updateStressLevel(stressChange) {
51
+ // Add or subtract the stress change while keeping within 0-100 range
52
+ this.stressLevel = Math.max(
53
+ 0,
54
+ Math.min(100, this.stressLevel + stressChange)
55
+ );
56
+ }
57
+
58
+ handleAction(response) {
59
+ switch (response.action) {
60
+ case "go":
61
+ this.moveToRoom(response.target);
62
+ break;
63
+ case "hide":
64
+ this.hide(response.target);
65
+ break;
66
+ case "exit":
67
+ this.exit();
68
+ break;
69
+ case "check":
70
+ this.check(response.target)
71
+ break;
72
+ }
73
+ }
74
+
75
+ getAvailableHidingSpots() {
76
+ // Find the current room in map data
77
+ const currentRoom = this.gameState.map_data.rooms.find(
78
+ (room) => room.name === this.getCurrentRoom()
79
+ );
80
+ // Return hiding places for current room if found, otherwise empty array
81
+ return currentRoom ? currentRoom.hiding_places : [];
82
+ }
83
+
84
+ getAvailableFurniture() {
85
+ // Get current room
86
+ const currentRoom = this.getCurrentRoom();
87
+ if (!currentRoom) return [];
88
+
89
+ // Filter furniture list to only include items in current room that are in use
90
+ return this.gameState.map_data.furniture.filter(
91
+ furniture => furniture.room === currentRoom && furniture.in_use === true
92
+ );
93
+ }
94
+
95
+ getKnowsAboutDeadBody() {
96
+ return this.knows_about_dead_body;
97
+ }
98
+
99
+ getInventory() {
100
+ return this.inventory;
101
+ }
102
+
103
+ getIsHiding() {
104
+ const hidingSpots = this.getAvailableHidingSpots();
105
+ if (!this.characterPos || hidingSpots.length === 0) return false;
106
+
107
+ return hidingSpots.some(
108
+ (spot) =>
109
+ spot.position.x === this.characterPos.x &&
110
+ spot.position.y === this.characterPos.y
111
+ );
112
+ }
113
+
114
+ hide(hidingSpotName) {
115
+ const currentRoom = this.getCurrentRoom();
116
+ if (!currentRoom) return;
117
+
118
+ // Find the room data from map_data
119
+ const roomData = this.gameState.map_data.rooms.find(
120
+ (room) => room.name === currentRoom
121
  );
122
+ if (!roomData) return;
123
+
124
+ // Find the specific hiding spot in the room by checking if names contain each other
125
+ const hidingSpot = roomData.hiding_places.find(
126
+ (spot) =>
127
+ spot.name
128
+ .toLowerCase()
129
+ .trim()
130
+ .includes(hidingSpotName.toLowerCase().trim()) ||
131
+ hidingSpotName
132
+ .toLowerCase()
133
+ .trim()
134
+ .includes(spot.name.toLowerCase().trim())
135
+ );
136
+
137
+ if (!hidingSpot) return;
138
+
139
+ // Move to the hiding spot position
140
+ this.moveToPosition(hidingSpot.position, () => {
141
+ this.currentHidingSpot = hidingSpotName;
142
+ });
143
+ }
144
+
145
+ exit() {
146
+ let the_exit = this.gameState.getTheExit();
147
+ let x = the_exit.pos.x;
148
+ let y = the_exit.pos.y - 1;
149
+ let pos = { "x": x, "y": y };
150
+ this.moveToPosition(pos, () => {
151
+ if (!this.inventory || !this.inventory.includes("Key")) {
152
+ addProgramaticMessage(the_exit.locked_message);
153
+ } else {
154
+ addProgramaticMessage(the_exit.unlocked_message);
155
+ }
156
+ });
157
+ }
158
+
159
+ check(target) {
160
+ if (target === "Bookcase") {
161
+ let bookcase = this.gameState.getBookcase();
162
+ this.moveToPosition(bookcase.pos, () => {
163
+ addProgramaticMessage(bookcase.msg);
164
+ bookcase.state = "unusable";
165
+ });
166
+ } else if (target === "Cabinet") {
167
+ let cabinet = this.gameState.getCabinet();
168
+ this.moveToPosition(cabinet.pos, () => {
169
+ addProgramaticMessage(cabinet.msg);
170
+ this.inventory.push("Knife");
171
+ cabinet.state = "unsearchable";
172
+ });
173
+ } else if (target === "Dead Body") {
174
+ let deadBody = this.gameState.map_data.furniture.find(item => item.name === "Dead Body");
175
+ this.moveToPosition(deadBody.pos, () => {
176
+
177
+ if (this.inventory.includes("Knife")) {
178
+ addProgramaticMessage("No no no ew ew i can't believe im doing this...😭😭😭 ....the key was in here i got it!! I can get out!");
179
+ deadBody.state = "unusable";
180
+ this.inventory.push("Key");
181
+ } else {
182
+ addProgramaticMessage("Um... what. the. f. Why is its mouth stitched up? Is the key inside??? i cant open it");
183
+ }
184
+
185
+ });
186
+
187
+
188
  }
189
+
 
190
  }
191
+
192
+ moving_check() {
193
+ if (this.getCurrentRoom() === "Storage") {
194
+ this.knows_about_dead_body = true;
195
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  }
static/game/game.js CHANGED
@@ -61,7 +61,6 @@ function draw() {
61
 
62
  drawLabels(gameState.map_data.rooms);
63
 
64
- drawStorage()
65
 
66
 
67
  if (girlfriend) {
 
61
 
62
  drawLabels(gameState.map_data.rooms);
63
 
 
64
 
65
 
66
  if (girlfriend) {
static/game/gameState.js CHANGED
@@ -39,11 +39,15 @@ class GameState {
39
  }
40
 
41
  getTheExit() {
42
- return this.map_data.furniture.find(furniture => furniture.name === "The Exit");
 
 
43
  }
44
 
45
  getStorage() {
46
- return this.map_data.furniture.find(furniture => furniture.name === "Storage");
 
 
47
  }
48
 
49
  getStressPrompt() {
@@ -64,11 +68,38 @@ The final stress level after applying the change must stay between 0 and 100.
64
 
65
  Examples:
66
  "Hide quickly!" -> {"stressChange": 40}
67
- "You're safe now, take a deep breath" -> {"stressChange": -35}
68
- "The killer is right behind you!" -> {"stressChange": 50}
69
- "Let's think about this calmly" -> {"stressChange": -30}`;
70
  }
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  getPrompt() {
73
  return `
74
 
@@ -88,7 +119,13 @@ ${
88
  : "- You have no idea where the clown is, you will hide if you can, if not leave the room"
89
  }
90
 
91
-
 
 
 
 
 
 
92
  RESPONSE FORMAT:
93
  You must ALWAYS respond with a JSON object.
94
  Your response should reflect a girlfriend's reaction to her boyfriend's message given this context and following the following structure:
@@ -100,12 +137,39 @@ For movement instructions ("go" action):
100
  "textMessage": "[girlfriend's response]"
101
  }
102
 
 
 
 
 
 
103
  For hiding instructions ("hide" action):
104
  {
105
  "action": "hide",
106
  "target": "[hiding place name]",
107
  "textMessage": "[girlfriend's response]"
108
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  For exiting the house by the exit in the mainhallway instructions ("exit" action):
111
  {
@@ -114,25 +178,13 @@ For exiting the house by the exit in the mainhallway instructions ("exit" action
114
  "textMessage": "[girlfriend's response]"
115
  }
116
 
 
117
  For any other input:
118
  {
119
  "textMessage": "[girlfriend's response]"
120
  }
121
 
122
- VALID ROOMS:
123
- You are only allowed to move to these rooms no other rooms are recognized:
124
- ${this.map_data.rooms.map((room) => room.name).join(",\n")}
125
 
126
- VALID HIDING PLACES:
127
- You are only allowed to hide in these hiding spots no other hiding spots are recognized:
128
- ${
129
- this.girlfriend.getAvailableHidingSpots().length > 0
130
- ? `- You may hide in these available hiding spots (and thats it): ${this.girlfriend
131
- .getAvailableHidingSpots()
132
- .map((spot) => `${spot.hiding_type} ${spot.name}`)
133
- .join(", ")}`
134
- : "- There are no available hiding spots in this room"
135
- }
136
 
137
  YOUR BEHAVIOR:
138
  - You are aware of the danger and are extremely distressed.
 
39
  }
40
 
41
  getTheExit() {
42
+ return this.map_data.furniture.find(
43
+ (furniture) => furniture.name === "The Exit"
44
+ );
45
  }
46
 
47
  getStorage() {
48
+ return this.map_data.furniture.find(
49
+ (furniture) => furniture.name === "Storage"
50
+ );
51
  }
52
 
53
  getStressPrompt() {
 
68
 
69
  Examples:
70
  "Hide quickly!" -> {"stressChange": 40}
71
+ "You're safe now, take a deep breath" -> {"stressChange": -40}
72
+ "The killer is right behind you!" -> {"stressChange": 30}
73
+ "Let's think about this calmly" -> {"stressChange": -40}`;
74
  }
75
 
76
+ getFirstPrompt() {
77
+ return `
78
+ You are a JSON girlfriend that is stuck in her boyfriends appartment with an evil murderous clown. You are currently having a text conversation with your boyfriend who has access to security cameras and can give instructions through text.
79
+ You are texting your boyfriend a text message to let him know you are in danger and that you absolutely need help.
80
+
81
+ RESPONSE FORMAT:
82
+ You must ALWAYS respond with a JSON object.
83
+ {
84
+ "textMessage": "[girlfriend's response]"
85
+ }
86
+
87
+ YOUR BEHAVIOUR:
88
+ --You are now in the bedroom
89
+ Your text responses should be:
90
+ -- Brief and urgent
91
+ -- Reflect genuine fear and panic
92
+ -- Write like real text messages (short, quick responses)
93
+ -- May include typos or rushed writing due to stress
94
+ --You are very scared but you are also super brave to be honest
95
+ --Don't name your partner
96
+
97
+ EXAMPLE RESPONSE:
98
+ {
99
+ "textMessage": "hi babe I think there's someone... or something... in the house, I'm so scared. Help me please!!!!"
100
+ }
101
+ `;
102
+ }
103
  getPrompt() {
104
  return `
105
 
 
119
  : "- You have no idea where the clown is, you will hide if you can, if not leave the room"
120
  }
121
 
122
+ ${
123
+ this.girlfriend.getInventory().length > 0
124
+ ? `- You have the following items in your inventory: ${this.girlfriend
125
+ .getInventory()
126
+ .join(", ")}`
127
+ : ""
128
+ }
129
  RESPONSE FORMAT:
130
  You must ALWAYS respond with a JSON object.
131
  Your response should reflect a girlfriend's reaction to her boyfriend's message given this context and following the following structure:
 
137
  "textMessage": "[girlfriend's response]"
138
  }
139
 
140
+ VALID ROOMS:
141
+ You are only allowed to move to these rooms no other rooms are recognized:
142
+ ${this.map_data.rooms.map((room) => room.name).join(",\n")}
143
+
144
+
145
  For hiding instructions ("hide" action):
146
  {
147
  "action": "hide",
148
  "target": "[hiding place name]",
149
  "textMessage": "[girlfriend's response]"
150
  }
151
+ VALID HIDING PLACES:
152
+ You are only allowed to hide in these hiding spots no other hiding spots are recognized:
153
+ ${
154
+ this.girlfriend.getAvailableHidingSpots().length > 0
155
+ ? `- You may hide in these available hiding spots (and thats it): ${this.girlfriend
156
+ .getAvailableHidingSpots()
157
+ .map((spot) => `[${spot.hiding_type} ${spot.name}]`)
158
+ .join(", ")}`
159
+ : "- There are no available hiding spots in this room"
160
+ }
161
+
162
+
163
+ For checking/inquiring/going to apecifically the Cabinet or Bookcase instructions ("check" action):
164
+ {
165
+ "action": "check",
166
+ "target": "she can only check \"Cabinet\" (this is in the kitchen, you can ask if youre not sure) or \"Bookcase\" (this is in the guest bedroom you can ask if youre not sure).${
167
+ this.girlfriend.getKnowsAboutDeadBody()
168
+ ? ' or "Dead Body" (in the Storage room)'
169
+ : "you might be asked to check other things be open minded about it ask where, be freaked out if nncecessarry"
170
+ }
171
+ "textMessage": "[girlfriend's response]"
172
+ }
173
 
174
  For exiting the house by the exit in the mainhallway instructions ("exit" action):
175
  {
 
178
  "textMessage": "[girlfriend's response]"
179
  }
180
 
181
+
182
  For any other input:
183
  {
184
  "textMessage": "[girlfriend's response]"
185
  }
186
 
 
 
 
187
 
 
 
 
 
 
 
 
 
 
 
188
 
189
  YOUR BEHAVIOR:
190
  - You are aware of the danger and are extremely distressed.
static/game/index.html CHANGED
@@ -1,70 +1,98 @@
1
  <!DOCTYPE html>
2
  <html>
3
-
4
- <head>
5
  <title>The Last Message - A text based horror game</title>
6
  <link rel="stylesheet" href="/static/assets/css/game-style.css" />
7
- </head>
8
 
9
- <body>
10
  <div class="led-bar">
11
- <div class="light-beam"></div>
12
  </div>
13
  <div class="background-elements">
14
- <img src="/static/assets/img/blood-2.png" alt="" class="blood blood-top-left" />
15
- <img src="/static/assets/img/help.png" alt="" class="blood blood-top-right" />
16
- <img src="/static/assets/img/splatter.png" alt="" class="blood splatter" />
17
- <img src="/static/assets/img/hand.png" alt="" class="blood blood-bottom-right" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  </div>
19
  <div id="gameContainer">
20
- <div id="mapSection">
21
- <div id="mapWrapper" class="map-wrapper">
22
- <!-- P5.js canvas goes here -->
23
- </div>
24
  </div>
25
- <div class="phone-mockup">
26
- <div class="phone-screen">
27
- <div id="chatSection">
28
- <div id="chatHeader">
29
- <div class="profile-picture">
30
- <!-- L'image sera ajoutée ici plus tard -->
31
- </div>
32
- <div class="chat-name">Bae 💖😘</div>
33
- </div>
34
- <div id="chatHistory"></div>
35
- <div id="chatControls">
36
- <input type="text" id="prompt" placeholder="Type your message...">
37
- <button onclick="Message()">
38
- <svg width="683" height="683" viewBox="0 0 683 683" fill="none"
39
- xmlns="http://www.w3.org/2000/svg">
40
- <path
41
- d="M22.2666 1.86666C19.5999 2.93333 16.5333 4.39999 15.4666 5.19999C11.9999 8.13333 9.33325 15.7333 9.33325 22.5333C9.33325 28.1333 65.4666 283.333 66.9333 284.667C67.3333 285.067 339.333 332.267 372.4 337.733C381.733 339.333 389.333 340.933 389.333 341.333C389.333 341.733 381.733 343.333 372.4 344.933C339.2 350.4 67.3333 397.6 66.9333 398C65.4666 399.333 9.33325 654.533 9.33325 660.133C9.33325 675.867 21.0666 685.333 35.8666 681.333C42.6666 679.467 662.267 362 666.4 358.133C671.333 353.733 673.333 348.8 673.333 341.333C673.333 333.867 671.333 328.933 666.4 324.533C662.533 320.933 43.0666 3.19999 36.2666 1.33333C29.9999 -0.400007 28.5333 -0.266674 22.2666 1.86666Z"
42
- fill="white" />
43
- </svg>
44
- </button>
45
- </div>
46
- </div>
 
 
 
 
 
 
 
 
 
47
  </div>
 
48
  </div>
 
49
  </div>
50
 
51
  <div class="sound-button" onclick="toggleSound()">
52
- <img src="/static/assets/img/sondon.png" alt="Sound control" id="soundIcon" />
 
 
 
 
53
  </div>
54
 
55
  <audio id="bgMusic" loop>
56
- <source src="/static/assets/sounds/music.mp3" type="audio/mp3" />
57
  </audio>
58
 
59
  <audio id="messageSound">
60
- <source src="/static/assets/sounds/message.wav" type="audio/wav" />
61
  </audio>
62
 
63
  <audio id="walkingSound" loop>
64
- <source src="/static/assets/sounds/walking.mp3" type="audio/mp3" />
65
  </audio>
66
 
67
-
68
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
69
  <script src="/static/game/elmnts/furniture.js"></script>
70
  <script src="/static/game/gameState.js"></script>
@@ -80,6 +108,28 @@
80
  <script src="/static/game/utilities/draw.js"></script>
81
  <script src="/static/game/game.js"></script>
82
 
83
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- </html>
 
 
 
 
 
 
 
 
 
 
 
1
  <!DOCTYPE html>
2
  <html>
3
+ <head>
 
4
  <title>The Last Message - A text based horror game</title>
5
  <link rel="stylesheet" href="/static/assets/css/game-style.css" />
6
+ </head>
7
 
8
+ <body>
9
  <div class="led-bar">
10
+ <div class="light-beam"></div>
11
  </div>
12
  <div class="background-elements">
13
+ <img
14
+ src="/static/assets/img/blood-2.png"
15
+ alt=""
16
+ class="blood blood-top-left"
17
+ />
18
+ <img
19
+ src="/static/assets/img/help.png"
20
+ alt=""
21
+ class="blood blood-top-right"
22
+ />
23
+ <img
24
+ src="/static/assets/img/splatter.png"
25
+ alt=""
26
+ class="blood splatter"
27
+ />
28
+ <img
29
+ src="/static/assets/img/hand.png"
30
+ alt=""
31
+ class="blood blood-bottom-right"
32
+ />
33
  </div>
34
  <div id="gameContainer">
35
+ <div id="mapSection">
36
+ <div id="mapWrapper" class="map-wrapper">
37
+ <!-- P5.js canvas goes here -->
 
38
  </div>
39
+ </div>
40
+ <div class="phone-mockup">
41
+ <div class="phone-screen">
42
+ <div id="chatSection">
43
+ <div id="chatHeader">
44
+ <div class="profile-picture">
45
+ <!-- L'image sera ajoutée ici plus tard -->
46
+ </div>
47
+ <div class="chat-name">Bae 💖😘</div>
48
+ </div>
49
+ <div id="chatHistory"></div>
50
+ <div id="chatControls">
51
+ <input
52
+ type="text"
53
+ id="prompt"
54
+ placeholder="Type your message..."
55
+ />
56
+ <button onclick="Message()">
57
+ <svg
58
+ width="683"
59
+ height="683"
60
+ viewBox="0 0 683 683"
61
+ fill="none"
62
+ xmlns="http://www.w3.org/2000/svg"
63
+ >
64
+ <path
65
+ d="M22.2666 1.86666C19.5999 2.93333 16.5333 4.39999 15.4666 5.19999C11.9999 8.13333 9.33325 15.7333 9.33325 22.5333C9.33325 28.1333 65.4666 283.333 66.9333 284.667C67.3333 285.067 339.333 332.267 372.4 337.733C381.733 339.333 389.333 340.933 389.333 341.333C389.333 341.733 381.733 343.333 372.4 344.933C339.2 350.4 67.3333 397.6 66.9333 398C65.4666 399.333 9.33325 654.533 9.33325 660.133C9.33325 675.867 21.0666 685.333 35.8666 681.333C42.6666 679.467 662.267 362 666.4 358.133C671.333 353.733 673.333 348.8 673.333 341.333C673.333 333.867 671.333 328.933 666.4 324.533C662.533 320.933 43.0666 3.19999 36.2666 1.33333C29.9999 -0.400007 28.5333 -0.266674 22.2666 1.86666Z"
66
+ fill="white"
67
+ />
68
+ </svg>
69
+ </button>
70
  </div>
71
+ </div>
72
  </div>
73
+ </div>
74
  </div>
75
 
76
  <div class="sound-button" onclick="toggleSound()">
77
+ <img
78
+ src="/static/assets/img/sondon.png"
79
+ alt="Sound control"
80
+ id="soundIcon"
81
+ />
82
  </div>
83
 
84
  <audio id="bgMusic" loop>
85
+ <source src="/static/assets/sounds/music.mp3" type="audio/mp3" />
86
  </audio>
87
 
88
  <audio id="messageSound">
89
+ <source src="/static/assets/sounds/message.wav" type="audio/wav" />
90
  </audio>
91
 
92
  <audio id="walkingSound" loop>
93
+ <source src="/static/assets/sounds/walking.mp3" type="audio/mp3" />
94
  </audio>
95
 
 
96
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
97
  <script src="/static/game/elmnts/furniture.js"></script>
98
  <script src="/static/game/gameState.js"></script>
 
108
  <script src="/static/game/utilities/draw.js"></script>
109
  <script src="/static/game/game.js"></script>
110
 
111
+ <script>
112
+ window.onload = async function () {
113
+ // Get the initial prompt from gameState
114
+ const firstPrompt = gameState.getFirstPrompt();
115
+
116
+ console.log("firstPrompt", firstPrompt);
117
+
118
+ const messages = [
119
+ {
120
+ role: "system",
121
+ content: firstPrompt,
122
+ },
123
+ ];
124
 
125
+ try {
126
+ const response = await mistralAPI.sendMessage(messages);
127
+ const jsonResponse = JSON.parse(response);
128
+ addMessageToChat("assistant", jsonResponse.textMessage);
129
+ } catch (error) {
130
+ console.error("Error getting initial message:", error);
131
+ }
132
+ };
133
+ </script>
134
+ </body>
135
+ </html>
static/game/utilities/draw.js CHANGED
@@ -30,24 +30,7 @@ function drawLabels(rooms) {
30
  // Draw room label
31
  textAlign(CENTER, CENTER);
32
  textSize(14);
33
-
34
- if (room.name === 'Storage') {
35
- // For Storage room, add white background
36
- const labelWidth = textWidth(room.name);
37
- const labelHeight = textAscent() + textDescent();
38
- push();
39
- rectMode(CENTER);
40
- fill(255); // White background
41
- noStroke();
42
- rect(
43
- room.label_position.x * CELL_SIZE + CELL_SIZE / 2,
44
- room.label_position.y * CELL_SIZE + CELL_SIZE / 2,
45
- labelWidth,
46
- labelHeight
47
- );
48
- pop();
49
- }
50
-
51
  fill(0);
52
  text(
53
  room.name,
@@ -72,14 +55,14 @@ function drawLabels(rooms) {
72
 
73
  // Measure exactly the text size (no extra padding)
74
  const labelWidth = textWidth(hidingSpot.name);
75
- const labelHeight = textAscent() ;
76
 
77
  // Draw a centered background rectangle
78
  // that's just as wide/tall as the text
79
  rectMode(CENTER);
80
  fill('#f1c94f');
81
  noStroke();
82
- rect(x, y, labelWidth, labelHeight/2, 2);
83
  pop();
84
 
85
  // Draw the text on top
@@ -148,7 +131,7 @@ function drawFurniture(furniture, sprites) {
148
 
149
  // Draw all labels second
150
  for (let item of furniture) {
151
- if (item.pos && item.in_use == true && item.name !== "Storage") {
152
  push();
153
  // Draw light gray background
154
  fill(220);
@@ -168,26 +151,3 @@ function drawFurniture(furniture, sprites) {
168
  }
169
  }
170
 
171
- function drawStorage() {
172
- let storage = gameState.getStorage();
173
- if (storage && storage.pos && storage.in_use == true) {
174
- push();
175
- // Draw light gray background
176
- fill(220);
177
- noStroke();
178
- const padding = 4;
179
- const textWidth = textSize() * storage.name.length * 0.6;
180
- rectMode(CENTER);
181
- rect((storage.pos.x + 0.5) * CELL_SIZE, (storage.pos.y + 0.5) * CELL_SIZE, textWidth, 20);
182
-
183
- // Draw black text
184
- fill(0);
185
- textAlign(CENTER, CENTER);
186
- textSize(12);
187
- text(storage.name, (storage.pos.x + 0.5) * CELL_SIZE, (storage.pos.y + 0.5) * CELL_SIZE);
188
-
189
- // Draw second "Storage" text on top
190
- text(storage.name, (storage.pos.x + 0.5) * CELL_SIZE, (storage.pos.y + 0.5) * CELL_SIZE - 20);
191
- pop();
192
- }
193
- }
 
30
  // Draw room label
31
  textAlign(CENTER, CENTER);
32
  textSize(14);
33
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  fill(0);
35
  text(
36
  room.name,
 
55
 
56
  // Measure exactly the text size (no extra padding)
57
  const labelWidth = textWidth(hidingSpot.name);
58
+ const labelHeight = textAscent();
59
 
60
  // Draw a centered background rectangle
61
  // that's just as wide/tall as the text
62
  rectMode(CENTER);
63
  fill('#f1c94f');
64
  noStroke();
65
+ rect(x, y, labelWidth, labelHeight / 2, 2);
66
  pop();
67
 
68
  // Draw the text on top
 
131
 
132
  // Draw all labels second
133
  for (let item of furniture) {
134
+ if (item.pos && item.in_use == true) {
135
  push();
136
  // Draw light gray background
137
  fill(220);
 
151
  }
152
  }
153