-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMy_last_days_here.py
More file actions
2084 lines (1771 loc) · 161 KB
/
My_last_days_here.py
File metadata and controls
2084 lines (1771 loc) · 161 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env python3
"""
My Last Days Here - An Enhanced Interactive Story Game
Part of the ChronoTale Collection
A deeply emotional narrative adventure about the final days of high school,
graduation, friendships, and the transition to adulthood.
Features comprehensive save/load system and extended storyline.
"""
import os
import sys
import json
import time
import random
from datetime import datetime
from typing import Dict, List, Tuple, Any, Optional
from colorama import init, Fore, Style
import platform
# Enhanced colorama initialization based on environment
if platform.system() == "Windows":
init(autoreset=True, convert=True, strip=False)
else:
# For Unix-like systems, use different settings
init(autoreset=True, convert=False, strip=None)
# Enhanced color management system
class ColorManager:
"""Enhanced color management with automatic fallback"""
@staticmethod
def is_color_supported() -> bool:
"""Check if terminal supports color output"""
try:
# Check if we're in a proper terminal
if not sys.stdout.isatty():
return False
# Check environment variables
term = os.environ.get('TERM', '').lower()
if 'color' in term or 'xterm' in term or 'screen' in term:
return True
# Check for common color-supporting terminals
if any(term.startswith(prefix) for prefix in ['xterm', 'screen', 'tmux', 'rxvt']):
return True
return False
except (OSError, AttributeError, ValueError):
return False
@staticmethod
def apply_color(text: str, color_code: str) -> str:
"""Apply color with automatic fallback"""
if ColorManager.is_color_supported():
try:
return f"{color_code}{text}{Style.RESET_ALL}"
except (AttributeError, ValueError, TypeError):
return text
return text
@staticmethod
def strip_ansi(text: str) -> str:
"""Remove ANSI color codes from text"""
import re
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
return ansi_escape.sub('', text)
# Global color manager instance
color_manager = ColorManager()
# Enhanced print functions with automatic color handling
def colored_print(text: str, color_code: str = "") -> None:
"""Print text with color support and automatic fallback"""
if color_code and color_manager.is_color_supported():
try:
print(f"{color_code}{text}{Style.RESET_ALL}")
except (AttributeError, ValueError, TypeError):
print(text)
else:
print(color_manager.strip_ansi(text) if not color_manager.is_color_supported() else text)
def safe_format(text: str, color_code: str = "") -> str:
"""Format text with color codes that are safely handled"""
if color_code and color_manager.is_color_supported():
try:
return f"{color_code}{text}{Style.RESET_ALL}"
except (AttributeError, ValueError, TypeError):
return text
return color_manager.strip_ansi(text) if not color_manager.is_color_supported() else text
# Constants
SAVE_DIR = "saves/my_last_days_here"
MAX_SAVES = 10
# Ensure save directory exists
os.makedirs(SAVE_DIR, exist_ok=True)
# Character Definitions with Interconnected Relationships
CHARACTERS = {
"hiroyuki": {
"name": "Hiroyuki",
"description": "The ordinary guy who secretly helped everyone",
"background": "A typical high school student who always blended into the background. With graduation approaching, he reflects on how he quietly helped his classmates throughout their years together - tutoring Hina in math, covering for Hana when she needed space, and being a reliable friend to everyone.",
"initial_stats": {"excitement": 45, "nostalgia": 35, "confidence": 30, "friendship": 35},
"unique_trait": "hidden_kindness",
"relationships": ["hina", "hana", "miyuki", "kazuha", "haruto", "rei", "sato", "andrew"],
"connections": {
"hina": "secret_tutor",
"hana": "class_helper",
"miyuki": "homework_helper",
"kazuha": "study_partner",
"haruto": "understanding_friend",
"rei": "photography_kindness",
"sato": "unexpected_support",
"andrew": "cultural_helper"
}
},
"hina": {
"name": "Hina",
"description": "The manga artist who drew everyone's stories",
"background": "An introverted artist who secretly drew manga featuring her classmates as heroes in their daily school adventures. As graduation approaches, she wonders if she should finally share her art with everyone and pursue her dream of becoming a professional manga artist.",
"initial_stats": {"excitement": 35, "nostalgia": 45, "confidence": 25, "friendship": 30},
"unique_trait": "observer_artist",
"relationships": ["hiroyuki", "hana", "miyuki", "kazuha", "haruto", "yuki", "rei", "andrew"],
"connections": {
"hiroyuki": "secret_reader",
"hana": "art_subject",
"miyuki": "admired_from_afar",
"kazuha": "sports_sketches",
"haruto": "understanding_friend",
"yuki": "shared_creativity",
"rei": "artistic_kinship",
"andrew": "cultural_fascination"
}
},
"hana": {
"name": "Hana",
"description": "The popular girl holding everyone together",
"background": "Outwardly cheerful and popular, she became the unofficial social coordinator of the class. As graduation looms, she's organizing farewell events while secretly worrying about whether the friendships she's helped nurture will survive after high school.",
"initial_stats": {"excitement": 40, "nostalgia": 50, "confidence": 35, "friendship": 45},
"unique_trait": "social_coordinator",
"relationships": ["hiroyuki", "hina", "miyuki", "kazuha", "haruto", "yuki", "andrew"],
"connections": {
"hiroyuki": "grateful_friend",
"hina": "encouraging_supporter",
"miyuki": "study_buddy",
"kazuha": "class_partner",
"haruto": "twin_sister",
"yuki": "welcoming_friend",
"andrew": "cultural_bridge"
}
},
"miyuki": {
"name": "Miyuki",
"description": "The perfect student facing future uncertainty",
"background": "Student council president with excellent grades who's always had her future planned out. As graduation approaches, she's starting to question whether the path she's chosen is really what she wants, while harboring unspoken feelings for a classmate.",
"initial_stats": {"excitement": 50, "nostalgia": 25, "confidence": 35, "friendship": 45},
"unique_trait": "perfectionist_questioning",
"relationships": ["hiroyuki", "hina", "hana", "kazuha", "haruto", "yuki", "andrew"],
"connections": {
"hiroyuki": "homework_helper",
"hina": "secret_admirer_of_art",
"hana": "study_partner",
"kazuha": "friendly_rival",
"haruto": "secret_crush",
"yuki": "academic_competitor",
"andrew": "language_exchange"
}
},
"kazuha": {
"name": "Kazuha",
"description": "The athlete bringing everyone together",
"background": "A star athlete and natural leader who became friends with everyone regardless of social groups. As graduation nears, he's organizing sports tournaments and team activities to create lasting memories with his classmates before they all go separate ways.",
"initial_stats": {"excitement": 55, "nostalgia": 30, "confidence": 50, "friendship": 60},
"unique_trait": "social_unifier",
"relationships": ["hiroyuki", "hina", "hana", "miyuki", "haruto", "yuki", "andrew"],
"connections": {
"hiroyuki": "study_buddy",
"hina": "encouraging_friend",
"hana": "festival_partner",
"miyuki": "friendly_rival",
"haruto": "best_friend",
"yuki": "sports_mentor",
"andrew": "sports_teammate"
}
},
"haruto": {
"name": "Haruto",
"description": "The quiet twin finding his voice",
"background": "Hana's twin brother who has always been more reserved than his outgoing sister. As graduation approaches, he's finally starting to open up to his friends and considering whether to pursue his interest in music or follow a more traditional path his family expects.",
"initial_stats": {"excitement": 35, "nostalgia": 40, "confidence": 30, "friendship": 45},
"unique_trait": "emerging_confidence",
"relationships": ["hiroyuki", "hina", "hana", "miyuki", "kazuha", "yuki", "rei", "sato", "andrew"],
"connections": {
"hiroyuki": "understanding_friend",
"hina": "art_appreciation",
"hana": "twin_brother",
"miyuki": "crush_interest",
"kazuha": "best_friend",
"yuki": "shared_creativity",
"rei": "music_collaboration",
"sato": "fellow_dreamer",
"andrew": "cultural_exchange"
}
},
"yuki": {
"name": "Yuki",
"description": "The transfer student finding her place",
"background": "Transferred to the school in her second year and initially struggled to fit in. Now, as graduation nears, she's grateful for the friendships she's built and is considering staying in the area for college to maintain these connections she's worked so hard to create.",
"initial_stats": {"excitement": 40, "nostalgia": 35, "confidence": 45, "friendship": 50},
"unique_trait": "grateful_newcomer",
"relationships": ["hina", "andrew", "haruto", "miyuki", "kazuha"],
"connections": {
"hina": "creative_friendship",
"andrew": "fellow_outsider",
"haruto": "shared_interests",
"miyuki": "study_partner",
"kazuha": "sports_encouragement"
}
},
"rei": {
"name": "Rei",
"description": "The photography club member capturing memories",
"background": "A quiet observer who documents school life through photography. She's been creating a secret yearbook of candid moments showing the real friendships and connections between classmates. As graduation approaches, she's planning to give everyone copies as a farewell gift.",
"initial_stats": {"excitement": 40, "nostalgia": 55, "confidence": 35, "friendship": 45},
"unique_trait": "memory_keeper",
"relationships": ["hina", "hiroyuki", "haruto", "andrew", "yuki", "sato"],
"connections": {
"hina": "artistic_friendship",
"hiroyuki": "captured_kindness",
"haruto": "music_collaboration",
"andrew": "cultural_documentation",
"yuki": "creative_partnership",
"sato": "unexpected_friendship"
}
},
"sato": {
"name": "Sato",
"description": "The class clown considering his future",
"background": "Always the entertainer who keeps everyone laughing, but graduation has him thinking seriously about what comes next. He's torn between pursuing comedy and entertainment or following a more stable career path, while treasuring the friendships that have sustained him through high school.",
"initial_stats": {"excitement": 45, "nostalgia": 40, "confidence": 35, "friendship": 55},
"unique_trait": "entertainer_dreamer",
"relationships": ["haruto", "rei", "andrew", "hiroyuki", "yuki"],
"connections": {
"haruto": "creative_collaboration",
"rei": "unexpected_friendship",
"andrew": "humor_exchange",
"hiroyuki": "supportive_friendship",
"yuki": "encouraging_friendship"
}
},
"andrew": {
"name": "Andrew",
"description": "The exchange student embracing Japanese culture",
"background": "An American exchange student who initially struggled with cultural differences but has grown to love Japanese school life. As his exchange program ends with graduation, he's conflicted about returning home and considering ways to stay in Japan longer.",
"initial_stats": {"excitement": 35, "nostalgia": 50, "confidence": 45, "friendship": 60},
"unique_trait": "cultural_bridge",
"relationships": ["yuki", "rei", "sato", "kazuha", "miyuki", "hina"],
"connections": {
"yuki": "fellow_outsider",
"rei": "photography_collaboration",
"sato": "humor_appreciation",
"kazuha": "sports_friendship",
"miyuki": "language_exchange",
"hina": "art_appreciation"
}
}
}
class GameState:
"""Manages the current state of the game"""
def __init__(self):
# Core game state
self.player_name: str = ""
self.selected_character: str = ""
self.character_background: Dict[str, Any] = {}
self.current_chapter: int = 1
self.choices_made: List[Dict[str, Any]] = []
self.character_stats: Dict[str, int] = {
"excitement": 50,
"nostalgia": 30,
"confidence": 20,
"friendship": 40
}
self.inventory: List[str] = []
self.discovered_memories: List[str] = []
self.relationships: Dict[str, int] = {}
self.playtime: float = 0.0
self.save_count: int = 0
self.achievements: List[str] = []
self.endings_unlocked: List[str] = []
self.start_time: float = time.time()
# Enhanced attributes for comprehensive save system
self.total_sessions: int = 1
self.character_growth: Dict[str, Any] = {}
self.personality_traits: Dict[str, Any] = {}
self.emotional_states: Dict[str, Any] = {}
self.character_arc: Dict[str, Any] = {}
self.skills: Dict[str, Any] = {}
self.confidence: Dict[str, Any] = {}
self.maturity: Dict[str, Any] = {}
self.friendship_levels: Dict[str, Any] = {}
self.completed_scenes: List[str] = []
self.unlocked_scenes: List[str] = []
self.optional_scenes: List[str] = []
self.dialogue_history: List[str] = []
self.narrative_branches: Dict[str, Any] = {}
self.story_flags: Dict[str, Any] = {}
self.chapter_times: Dict[str, float] = {}
self.emotional_moments: List[str] = []
self.memorable_quotes: List[str] = []
self.relationship_history: Dict[str, Any] = {}
self.friendship_milestones: Dict[str, Any] = {}
self.romantic_progress: Dict[str, Any] = {}
self.social_dynamics: Dict[str, Any] = {}
self.group_scenes: List[str] = []
self.conflicts_resolved: List[str] = []
self.trust_levels: Dict[str, Any] = {}
self.shared_memories: Dict[str, Any] = {}
self.play_style: Dict[str, Any] = {}
self.choice_patterns: Dict[str, Any] = {}
self.favorite_characters: List[str] = []
self.emotional_responses: Dict[str, Any] = {}
self.reading_speed: str = "normal"
self.accessibility: Dict[str, Any] = {}
self.language_settings: Dict[str, Any] = {}
self.content_warnings: List[str] = []
self.achievement_progress: Dict[str, Any] = {}
self.hidden_achievements: List[str] = []
self.completion_rate: float = 0.0
self.perfectionist_data: Dict[str, Any] = {}
self.speedrun_stats: Dict[str, Any] = {}
self.replay_stats: Dict[str, Any] = {}
self.exploration_rate: float = 0.0
self.memory_fragments: Dict[str, Any] = {}
self.photos: List[str] = []
self.diary_entries: List[str] = []
self.letters: List[str] = []
self.mementos: List[str] = []
self.scrapbook: List[str] = []
self.voice_messages: List[str] = []
self.words_read: int = 0
self.scenes_count: int = 0
self.dialogue_count: int = 0
self.emotional_peaks: int = 0
self.emotional_impact: int = 0
self.humor_moments: int = 0
self.heartfelt_count: int = 0
self.interaction_count: Dict[str, int] = {}
self.last_errors: List[str] = []
self.performance: Dict[str, Any] = {}
self.feature_flags: Dict[str, bool] = {}
self.debug_mode: bool = False
self.compatibility: Dict[str, Any] = {}
self.backup_saves: List[str] = []
def add_choice(self, chapter: int, choice_text: str, choice_id: str, impact: Dict[str, int]):
"""Record a choice made by the player"""
choice_data = {
"chapter": chapter,
"choice_text": choice_text,
"choice_id": choice_id,
"impact": impact,
"timestamp": datetime.now().isoformat()
}
self.choices_made.append(choice_data)
# Apply stat changes
for stat, change in impact.items():
if stat in self.character_stats:
self.character_stats[stat] = max(0, min(100, self.character_stats[stat] + change))
def update_playtime(self):
"""Update total playtime"""
if self.start_time:
self.playtime = time.time() - self.start_time
class SaveManager:
"""Handles comprehensive saving and loading of all game data"""
@staticmethod
def save_game(game_state: GameState, save_name: Optional[str] = None) -> bool:
"""Save the current game state with comprehensive data preservation"""
try:
game_state.update_playtime()
if not save_name:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
save_name = f"save_{timestamp}.json"
if not save_name.endswith('.json'):
save_name += '.json'
save_path = os.path.join(SAVE_DIR, save_name)
# Create comprehensive save data structure
comprehensive_save_data = {
# Core game state
"core_game_state": {
"player_name": game_state.player_name,
"selected_character": game_state.selected_character,
"character_background": game_state.character_background,
"current_chapter": game_state.current_chapter,
"choices_made": game_state.choices_made,
"character_stats": game_state.character_stats,
"inventory": game_state.inventory,
"discovered_memories": game_state.discovered_memories,
"relationships": game_state.relationships,
"achievements": game_state.achievements,
"endings_unlocked": game_state.endings_unlocked
},
# Save metadata and timing
"save_metadata": {
"save_timestamp": datetime.now().isoformat(),
"game_version": "3.0_enhanced",
"save_count": game_state.save_count + 1,
"playtime": game_state.playtime,
"session_start_time": getattr(game_state, 'start_time', time.time()),
"total_sessions": getattr(game_state, 'total_sessions', 1),
"save_file_name": save_name,
"platform": platform.system(),
"python_version": platform.python_version()
},
# Character progression and development
"character_progression": {
"character_growth_points": getattr(game_state, 'character_growth', {}),
"personality_traits": getattr(game_state, 'personality_traits', {}),
"emotional_states": getattr(game_state, 'emotional_states', {}),
"character_arc_progress": getattr(game_state, 'character_arc', {}),
"skill_development": getattr(game_state, 'skills', {}),
"confidence_levels": getattr(game_state, 'confidence', {}),
"maturity_indicators": getattr(game_state, 'maturity', {}),
"friendship_depths": getattr(game_state, 'friendship_levels', {})
},
# Story and narrative tracking
"story_data": {
"completed_scenes": getattr(game_state, 'completed_scenes', []),
"unlocked_scenes": getattr(game_state, 'unlocked_scenes', []),
"optional_scenes_encountered": getattr(game_state, 'optional_scenes', []),
"dialogue_choices_history": getattr(game_state, 'dialogue_history', []),
"narrative_branches": getattr(game_state, 'narrative_branches', {}),
"story_flags": getattr(game_state, 'story_flags', {}),
"chapter_completion_times": getattr(game_state, 'chapter_times', {}),
"emotional_moments": getattr(game_state, 'emotional_moments', []),
"memorable_quotes": getattr(game_state, 'memorable_quotes', [])
},
# Relationship and social dynamics
"relationship_data": {
"detailed_relationships": game_state.relationships,
"relationship_history": getattr(game_state, 'relationship_history', {}),
"friendship_milestones": getattr(game_state, 'friendship_milestones', {}),
"romantic_interests": getattr(game_state, 'romantic_progress', {}),
"social_dynamics": getattr(game_state, 'social_dynamics', {}),
"group_interactions": getattr(game_state, 'group_scenes', []),
"conflict_resolutions": getattr(game_state, 'conflicts_resolved', []),
"trust_levels": getattr(game_state, 'trust_levels', {}),
"shared_memories": getattr(game_state, 'shared_memories', {})
},
# Player experience and preferences
"player_data": {
"play_style_preferences": getattr(game_state, 'play_style', {}),
"choice_patterns": getattr(game_state, 'choice_patterns', {}),
"favorite_characters": getattr(game_state, 'favorite_characters', []),
"emotional_responses": getattr(game_state, 'emotional_responses', {}),
"reading_speed": getattr(game_state, 'reading_speed', 'normal'),
"accessibility_settings": getattr(game_state, 'accessibility', {}),
"language_preferences": getattr(game_state, 'language_settings', {}),
"content_warnings_seen": getattr(game_state, 'content_warnings', [])
},
# Achievement and completion tracking
"achievement_data": {
"unlocked_achievements": game_state.achievements,
"achievement_progress": getattr(game_state, 'achievement_progress', {}),
"hidden_achievements": getattr(game_state, 'hidden_achievements', []),
"completion_percentage": getattr(game_state, 'completion_rate', 0.0),
"perfectionist_flags": getattr(game_state, 'perfectionist_data', {}),
"speedrun_data": getattr(game_state, 'speedrun_stats', {}),
"replay_statistics": getattr(game_state, 'replay_stats', {}),
"exploration_completeness": getattr(game_state, 'exploration_rate', 0.0)
},
# Memory and collectibles system
"memory_system": {
"discovered_memories": game_state.discovered_memories,
"memory_fragments": getattr(game_state, 'memory_fragments', {}),
"photo_collection": getattr(game_state, 'photos', []),
"diary_entries": getattr(game_state, 'diary_entries', []),
"letter_collection": getattr(game_state, 'letters', []),
"memento_items": getattr(game_state, 'mementos', []),
"scrapbook_pages": getattr(game_state, 'scrapbook', []),
"voice_messages": getattr(game_state, 'voice_messages', [])
},
# Game statistics and analytics
"statistics": {
"total_choices_made": len(game_state.choices_made),
"words_read": getattr(game_state, 'words_read', 0),
"scenes_completed": getattr(game_state, 'scenes_count', 0),
"dialogues_participated": getattr(game_state, 'dialogue_count', 0),
"emotional_peaks": getattr(game_state, 'emotional_peaks', 0),
"tears_shed": getattr(game_state, 'emotional_impact', 0),
"laughs_shared": getattr(game_state, 'humor_moments', 0),
"heartfelt_moments": getattr(game_state, 'heartfelt_count', 0),
"character_interactions": getattr(game_state, 'interaction_count', {})
},
# Technical and debug information
"technical_data": {
"game_state_size": len(str(game_state.__dict__)),
"last_error_log": getattr(game_state, 'last_errors', []),
"performance_metrics": getattr(game_state, 'performance', {}),
"feature_flags": getattr(game_state, 'feature_flags', {}),
"debug_mode": getattr(game_state, 'debug_mode', False),
"compatibility_settings": getattr(game_state, 'compatibility', {}),
"backup_data": getattr(game_state, 'backup_saves', [])
}
}
# Update save count
game_state.save_count = comprehensive_save_data["save_metadata"]["save_count"]
with open(save_path, 'w', encoding='utf-8') as f:
json.dump(comprehensive_save_data, f, indent=2, ensure_ascii=False)
return True
except Exception as e:
print(f"{Fore.RED}Failed to save game: {e}{Style.RESET_ALL}")
return False
@staticmethod
def load_game(save_name: Optional[str] = None) -> Optional[GameState]:
"""Load a game state from file with comprehensive data restoration"""
try:
if not save_name:
saves = SaveManager.list_saves()
if not saves:
return None
save_name = saves[0]['filename']
# Ensure save_name is a valid string before processing
if save_name is None or not isinstance(save_name, str):
return None
if not save_name.endswith('.json'):
save_name += '.json'
save_path = os.path.join(SAVE_DIR, save_name)
if not os.path.exists(save_path):
return None
with open(save_path, 'r', encoding='utf-8') as f:
save_data = json.load(f)
game_state = GameState()
# Handle comprehensive save format
if "core_game_state" in save_data:
# Load core game state
core_data = save_data["core_game_state"]
game_state.player_name = core_data.get("player_name", "")
game_state.selected_character = core_data.get("selected_character", "")
game_state.character_background = core_data.get("character_background", {})
game_state.current_chapter = core_data.get("current_chapter", 1)
game_state.choices_made = core_data.get("choices_made", [])
game_state.character_stats = core_data.get("character_stats", {})
game_state.inventory = core_data.get("inventory", [])
game_state.discovered_memories = core_data.get("discovered_memories", [])
game_state.relationships = core_data.get("relationships", {})
game_state.achievements = core_data.get("achievements", [])
game_state.endings_unlocked = core_data.get("endings_unlocked", [])
# Load metadata
if "save_metadata" in save_data:
metadata = save_data["save_metadata"]
game_state.playtime = metadata.get("playtime", 0.0)
game_state.save_count = metadata.get("save_count", 0)
game_state.start_time = time.time() - game_state.playtime
# Restore extended metadata
game_state.total_sessions = metadata.get("total_sessions", 1)
# Restore character progression
if "character_progression" in save_data:
progression = save_data["character_progression"]
game_state.character_growth = progression.get("character_growth_points", {})
game_state.personality_traits = progression.get("personality_traits", {})
game_state.emotional_states = progression.get("emotional_states", {})
game_state.character_arc = progression.get("character_arc_progress", {})
game_state.skills = progression.get("skill_development", {})
game_state.confidence = progression.get("confidence_levels", {})
game_state.maturity = progression.get("maturity_indicators", {})
game_state.friendship_levels = progression.get("friendship_depths", {})
# Restore story data
if "story_data" in save_data:
story = save_data["story_data"]
game_state.completed_scenes = story.get("completed_scenes", [])
game_state.unlocked_scenes = story.get("unlocked_scenes", [])
game_state.optional_scenes = story.get("optional_scenes_encountered", [])
game_state.dialogue_history = story.get("dialogue_choices_history", [])
game_state.narrative_branches = story.get("narrative_branches", {})
game_state.story_flags = story.get("story_flags", {})
game_state.chapter_times = story.get("chapter_completion_times", {})
game_state.emotional_moments = story.get("emotional_moments", [])
game_state.memorable_quotes = story.get("memorable_quotes", [])
# Restore relationship data
if "relationship_data" in save_data:
relationships = save_data["relationship_data"]
game_state.relationship_history = relationships.get("relationship_history", {})
game_state.friendship_milestones = relationships.get("friendship_milestones", {})
game_state.romantic_progress = relationships.get("romantic_interests", {})
game_state.social_dynamics = relationships.get("social_dynamics", {})
game_state.group_scenes = relationships.get("group_interactions", [])
game_state.conflicts_resolved = relationships.get("conflict_resolutions", [])
game_state.trust_levels = relationships.get("trust_levels", {})
game_state.shared_memories = relationships.get("shared_memories", {})
# Restore player data
if "player_data" in save_data:
player = save_data["player_data"]
game_state.play_style = player.get("play_style_preferences", {})
game_state.choice_patterns = player.get("choice_patterns", {})
game_state.favorite_characters = player.get("favorite_characters", [])
game_state.emotional_responses = player.get("emotional_responses", {})
game_state.reading_speed = player.get("reading_speed", "normal")
game_state.accessibility = player.get("accessibility_settings", {})
game_state.language_settings = player.get("language_preferences", {})
game_state.content_warnings = player.get("content_warnings_seen", [])
# Restore achievement data
if "achievement_data" in save_data:
achievements = save_data["achievement_data"]
game_state.achievement_progress = achievements.get("achievement_progress", {})
game_state.hidden_achievements = achievements.get("hidden_achievements", [])
game_state.completion_rate = achievements.get("completion_percentage", 0.0)
game_state.perfectionist_data = achievements.get("perfectionist_flags", {})
game_state.speedrun_stats = achievements.get("speedrun_data", {})
game_state.replay_stats = achievements.get("replay_statistics", {})
game_state.exploration_rate = achievements.get("exploration_completeness", 0.0)
# Restore memory system
if "memory_system" in save_data:
memory = save_data["memory_system"]
game_state.memory_fragments = memory.get("memory_fragments", {})
game_state.photos = memory.get("photo_collection", [])
game_state.diary_entries = memory.get("diary_entries", [])
game_state.letters = memory.get("letter_collection", [])
game_state.mementos = memory.get("memento_items", [])
game_state.scrapbook = memory.get("scrapbook_pages", [])
game_state.voice_messages = memory.get("voice_messages", [])
# Restore statistics
if "statistics" in save_data:
stats = save_data["statistics"]
game_state.words_read = stats.get("words_read", 0)
game_state.scenes_count = stats.get("scenes_completed", 0)
game_state.dialogue_count = stats.get("dialogues_participated", 0)
game_state.emotional_peaks = stats.get("emotional_peaks", 0)
game_state.emotional_impact = stats.get("tears_shed", 0)
game_state.humor_moments = stats.get("laughs_shared", 0)
game_state.heartfelt_count = stats.get("heartfelt_moments", 0)
game_state.interaction_count = stats.get("character_interactions", {})
# Restore technical data
if "technical_data" in save_data:
technical = save_data["technical_data"]
game_state.last_errors = technical.get("last_error_log", [])
game_state.performance = technical.get("performance_metrics", {})
game_state.feature_flags = technical.get("feature_flags", {})
game_state.debug_mode = technical.get("debug_mode", False)
game_state.compatibility = technical.get("compatibility_settings", {})
game_state.backup_saves = technical.get("backup_data", [])
else:
# Handle legacy save format
game_state.player_name = save_data.get("player_name", "")
game_state.selected_character = save_data.get("selected_character", "")
game_state.character_background = save_data.get("character_background", {})
game_state.current_chapter = save_data.get("current_chapter", 1)
game_state.choices_made = save_data.get("choices_made", [])
game_state.character_stats = save_data.get("character_stats", {})
game_state.inventory = save_data.get("inventory", [])
game_state.discovered_memories = save_data.get("discovered_memories", [])
game_state.relationships = save_data.get("relationships", {})
game_state.playtime = save_data.get("playtime", 0.0)
game_state.save_count = save_data.get("save_count", 0)
game_state.achievements = save_data.get("achievements", [])
game_state.endings_unlocked = save_data.get("endings_unlocked", [])
game_state.start_time = time.time() - game_state.playtime
return game_state
except Exception as e:
print(f"{Fore.RED}Failed to load game: {e}{Style.RESET_ALL}")
return None
@staticmethod
def list_saves() -> List[Dict[str, Any]]:
"""List all available save files with comprehensive information"""
saves = []
try:
if not os.path.exists(SAVE_DIR):
return saves
for filename in os.listdir(SAVE_DIR):
if filename.endswith('.json'):
filepath = os.path.join(SAVE_DIR, filename)
try:
with open(filepath, 'r', encoding='utf-8') as f:
save_data = json.load(f)
# Handle comprehensive save format
if "core_game_state" in save_data and "save_metadata" in save_data:
core_data = save_data["core_game_state"]
metadata = save_data["save_metadata"]
save_info = {
"filename": filename,
"character": core_data.get("selected_character", "Unknown"),
"chapter": core_data.get("current_chapter", 1),
"playtime": metadata.get("playtime", 0),
"timestamp": metadata.get("save_timestamp", "Unknown"),
"player_name": core_data.get("player_name", "Unknown"),
"game_version": metadata.get("game_version", "3.0_enhanced"),
"save_count": metadata.get("save_count", 0),
"total_sessions": metadata.get("total_sessions", 1),
"achievements_count": len(core_data.get("achievements", [])),
"relationships_count": len(core_data.get("relationships", {})),
"memories_count": len(core_data.get("discovered_memories", []))
}
else:
# Handle legacy save format
save_info = {
"filename": filename,
"character": save_data.get("selected_character", "Unknown"),
"chapter": save_data.get("current_chapter", 1),
"playtime": save_data.get("playtime", 0),
"timestamp": save_data.get("save_timestamp", "Unknown"),
"player_name": save_data.get("player_name", "Unknown"),
"game_version": save_data.get("game_version", "2.0.0"),
"save_count": save_data.get("save_count", 0),
"total_sessions": 1,
"achievements_count": len(save_data.get("achievements", [])),
"relationships_count": len(save_data.get("relationships", {})),
"memories_count": len(save_data.get("discovered_memories", []))
}
saves.append(save_info)
except Exception:
continue
# Sort by timestamp (newest first)
saves.sort(key=lambda x: x["timestamp"], reverse=True)
except Exception:
pass
return saves
class CharacterStoryAdapter:
"""Adapts story content based on selected character"""
@staticmethod
def get_character_opening(character: str) -> str:
"""Get character-specific opening text"""
openings = {
"hiroyuki": "You stand at your bedroom window, looking out at the school you've attended for three years. Tomorrow is graduation, and you can't help but think about all the quiet moments when you helped your classmates without them ever knowing...",
"hina": "Your desk is covered with manga pages - secret drawings of your classmates living their daily adventures. Tomorrow is graduation, and you're wondering if you should finally share these stories that captured everyone's true hearts...",
"hana": "The graduation ceremony checklist sits before you, every detail planned perfectly. Tomorrow is the day you've been organizing for months, but tonight you're wondering if the friendships you've nurtured will survive beyond these school walls...",
"miyuki": "Your valedictorian speech is written and rewritten, but the words feel hollow. Tomorrow you'll stand before everyone with perfect grades and a perfect future planned, yet you're questioning if this path is truly yours...",
"kazuha": "The sports equipment room feels different tonight. Tomorrow is graduation, and you're thinking about how sports brought everyone together - the shy kids, the smart ones, the artists. Will these bonds last beyond the final whistle?",
"haruto": "Your guitar sits in the corner, still holding the melodies you've been too afraid to share. Tomorrow is graduation, and you're finally ready to let people hear your voice - but is it too late to change who you've been?",
"yuki": "The acceptance letter to the local college sits on your desk. Tomorrow is graduation from the school where you finally found your place. Should you stay near these hard-won friendships or follow your original dreams?",
"rei": "Your camera is full of candid photos showing the real connections between your classmates. Tomorrow is graduation, and you've prepared a special gift - a memory book that reveals the beautiful moments they never knew you captured...",
"sato": "The comedy club's final performance was yesterday, but tomorrow is graduation and the real world awaits. You've made everyone laugh for three years, but now you're wondering: can you turn these smiles into a future?",
"andrew": "Your plane ticket home sits next to your Japanese textbooks. Tomorrow is graduation, ending an exchange program that became so much more than you expected. How do you say goodbye to a place that taught you who you really are?"
}
return openings.get(character, "Tomorrow is graduation day, and everything is about to change...")
@staticmethod
def get_character_memories(character: str) -> List[Tuple[str, str, Dict[str, int]]]:
"""Get character-specific memory choices"""
if character == "hiroyuki":
return [
("Graduation day - tears in your eyes watching everyone you secretly helped succeed, knowing they'll never truly know", "graduation_memory", {"excitement": 20, "nostalgia": 25, "friendship": 15}),
("The night Hina cried over math homework and you spent four hours helping her understand, seeing her first genuine smile in weeks", "tutoring_hina", {"friendship": 20, "nostalgia": 15, "confidence": 8}),
("Staying up until 3am with Hana to make handwritten invitations for every classmate, watching her pour her heart into each one", "helping_hana", {"nostalgia": 25, "confidence": 12, "friendship": 15}),
("Finding Miyuki collapsed from exhaustion in the student council room and carrying her to the nurse, promising to help shoulder her burden", "helping_miyuki", {"friendship": 20, "nostalgia": 18, "confidence": 12}),
("The rainy evening when Haruto broke down about feeling invisible, and you held him while he sobbed about not knowing who he was", "haruto_friendship", {"nostalgia": 30, "friendship": 25, "confidence": 10})
]
elif character == "hina":
return [
("Graduation day - your hands trembling as you finally show everyone the manga pages that captured their hearts, watching their tears of recognition", "graduation_memory", {"excitement": 25, "nostalgia": 30, "confidence": 20}),
("Three years of secretly drawing your classmates during lunch breaks, each panel a love letter to friendships you were too shy to voice", "drawing_classmates", {"nostalgia": 25, "friendship": 20, "confidence": 8}),
("The moment Hiroyuki found your sketchbook and whispered 'You see us all so beautifully' - the first time anyone truly understood your art", "hiroyuki_validation", {"confidence": 30, "nostalgia": 20, "friendship": 15}),
("Capturing Kazuha's determination during the final sports festival, tears streaming down your face as you drew his unwavering spirit", "sketching_kazuha", {"nostalgia": 25, "friendship": 15, "confidence": 10}),
("Working through the night to finish a 50-page manga featuring everyone's dreams and fears, your final gift to the people who gave you a voice", "graduation_manga", {"excitement": 20, "nostalgia": 30, "friendship": 25})
]
elif character == "hana":
return [
("Graduation day - watching three years of careful planning unfold perfectly, but knowing this is the last time you'll bring everyone together", "graduation_memory", {"excitement": 30, "nostalgia": 35, "friendship": 25}),
("The night you secretly planned Haruto's farewell concert, seeing your shy twin brother finally shine as the musician you always knew he was", "haruto_surprise", {"nostalgia": 30, "friendship": 25, "confidence": 15}),
("Sitting with each classmate individually to help them write yearbook messages, holding back tears as they shared memories you helped create", "yearbook_messages", {"nostalgia": 25, "friendship": 30, "confidence": 18}),
("The school festival where you watched from backstage as everyone laughed and celebrated, knowing you'd given them one last perfect memory", "festival_success", {"confidence": 20, "nostalgia": 25, "excitement": 12}),
("Your final dance with Kazuha under the cherry blossoms, both of you crying as you realized childhood was ending in this very moment", "graduation_dance", {"excitement": 20, "nostalgia": 30, "friendship": 20})
]
elif character == "miyuki":
return [
("Graduation day - abandoning your planned valedictorian speech to speak from the heart about how your classmates taught you what truly matters", "graduation_memory", {"confidence": 25, "nostalgia": 30, "excitement": 20}),
("The rainy afternoon when you finally found Haruto alone in the music room, both of you crying as you confessed your feelings and fears about the future", "haruto_conversation", {"confidence": 20, "nostalgia": 25, "friendship": 20}),
("Three sleepless nights with Hana planning every detail of graduation, watching her sacrifice her own dreams to make everyone else's memories perfect", "hana_collaboration", {"friendship": 25, "nostalgia": 20, "confidence": 15}),
("The moment Kazuha made you laugh so hard during finals week that you forgot about being perfect and just felt young and free for once", "kazuha_laughs", {"nostalgia": 25, "friendship": 20, "confidence": 12}),
("Finding Hina's manga and realizing she saw beauty in everyone you thought were just competitors - learning what real friendship looks like", "discovering_hina", {"friendship": 20, "nostalgia": 18, "excitement": 8})
]
elif character == "kazuha":
return [
("Graduation day - looking at the empty sports field and remembering every laugh, every victory, every moment you brought outcasts and popular kids together through sheer determination", "graduation_memory", {"nostalgia": 35, "friendship": 30, "confidence": 20}),
("The final sports tournament where shy Hina cheered louder than anyone, quiet Haruto played music during breaks, and even Miyuki forgot about grades - your dream of unity finally real", "sports_tournament", {"excitement": 20, "nostalgia": 30, "friendship": 25}),
("Countless afternoons teaching Andrew not just Japanese sports terms, but watching him find belonging in a country that felt foreign until you made it home", "teaching_andrew", {"friendship": 25, "nostalgia": 20, "confidence": 15}),
("The night Haruto played guitar while you taught him to throw a baseball, both of you crying as you realized you'd found a brother in each other", "helping_haruto", {"friendship": 25, "nostalgia": 20, "confidence": 12}),
("Standing on the podium after the championship, not caring about the trophy but seeing everyone in the crowd cheering together - shy kids, smart kids, everyone united", "victory_celebration", {"excitement": 20, "nostalgia": 30, "friendship": 20})
]
elif character == "haruto":
return [
("Graduation day - your hands shaking as you perform the song you wrote about saying goodbye, watching everyone cry including yourself", "graduation_memory", {"excitement": 30, "nostalgia": 35, "confidence": 25}),
("The moment Kazuha grabbed your shoulders and said 'Your music saved me from the loneliness of being the only one who cared' - realizing your quiet strength mattered", "kazuha_encouragement", {"confidence": 25, "nostalgia": 20, "friendship": 20}),
("Finding Miyuki crying in the music room after hearing your song about feeling invisible, both of you finally understanding each other's hidden pain", "miyuki_connection", {"confidence": 20, "nostalgia": 25, "friendship": 18}),
("Discovering that Hina drew an entire manga chapter about your music bringing light to dark places, seeing yourself as the hero you never thought you were", "hina_collaboration", {"nostalgia": 25, "friendship": 20, "confidence": 15}),
("Hana surprising you with a concert she planned in secret, watching your twin sister wipe away tears as you finally let everyone hear your voice", "hana_support", {"excitement": 20, "nostalgia": 30, "friendship": 25})
]
elif character == "yuki":
return [
("Graduation day - standing with friends who chose to love you despite your broken Japanese and awkward moments, finally belonging somewhere", "graduation_memory", {"excitement": 25, "nostalgia": 30, "friendship": 25}),
("Crying with Andrew as you both practiced English and Japanese together, two outsiders who found home in each other's struggle", "andrew_help", {"friendship": 25, "nostalgia": 20, "confidence": 15}),
("The day Hina showed you her manga where you were the brave transfer student who saved everyone - seeing yourself as others saw you", "hina_manga", {"confidence": 25, "nostalgia": 20, "friendship": 18}),
("Kazuha refusing to let you sit alone during lunch until you finally joined the sports festival committee, tears of gratitude streaming down your face", "kazuha_inclusion", {"friendship": 25, "nostalgia": 18, "confidence": 15}),
("Late night study sessions with Miyuki where you both confessed your fears about the future, finding strength in shared vulnerability", "miyuki_dreams", {"nostalgia": 20, "friendship": 18, "confidence": 12})
]
elif character == "rei":
return [
("Graduation day - watching everyone cry over the photo books you made, realizing your quiet observations captured the love they didn't know they shared", "graduation_memory", {"excitement": 30, "nostalgia": 35, "friendship": 25}),
("Hiding behind your camera while Haruto performed, tears blurring your lens as you captured his transformation from invisible to unforgettable", "haruto_music", {"nostalgia": 30, "friendship": 20, "confidence": 15}),
("Andrew asking you to be his photographer because 'you see the real Japan, not the tourist version' - understanding your true artistic gift", "andrew_photos", {"friendship": 22, "nostalgia": 18, "confidence": 15}),
("Staying up all night with Hina combining your candid photos with her manga panels, creating a masterpiece that told everyone's true story", "hina_collaboration", {"excitement": 20, "nostalgia": 25, "friendship": 18}),
("Your teacher displaying your secret portraits with the caption 'The Heart of Friendship' - finally being seen as the artist you always were", "exhibition_success", {"confidence": 30, "excitement": 25, "nostalgia": 18})
]
elif character == "sato":
return [
("Graduation day - making everyone laugh through their tears, realizing your humor was the medicine that healed three years of teenage pain", "graduation_memory", {"excitement": 25, "nostalgia": 35, "friendship": 25}),
("The night your comedy show made even the shyest students laugh until they cried, watching Hina actually speak up to compliment your performance", "comedy_success", {"confidence": 25, "nostalgia": 20, "friendship": 20}),
("Andrew learning your jokes in broken Japanese and performing them back to you, both of you crying with laughter at the beautiful disaster", "andrew_humor", {"friendship": 20, "nostalgia": 18, "confidence": 15}),
("Hiroyuki staying after every performance to help you clean up, never asking for credit but always being there when you needed someone", "hiroyuki_support", {"friendship": 25, "nostalgia": 20, "confidence": 12}),
("Rei's photo of you mid-joke - mouth wide open, arms flailing - becoming the yearbook cover because it captured pure joy", "rei_photos", {"nostalgia": 25, "friendship": 18, "confidence": 15})
]
elif character == "andrew":
return [
("Graduation day - wearing your cap and gown with a small American flag pin, finally understanding that home isn't where you're from but where you choose to grow", "graduation_memory", {"excitement": 30, "nostalgia": 35, "friendship": 25}),
("Your presentation about cultural exchange where you broke down crying talking about how Japan saved you from loneliness, receiving a standing ovation", "presentation_success", {"confidence": 25, "nostalgia": 25, "excitement": 20}),
("Kazuha teaching you baseball while you taught him English curse words, both of you laughing until you couldn't breathe", "kazuha_friendship", {"friendship": 25, "nostalgia": 20, "confidence": 18}),
("Rei's photo series documenting your first year - from confused and isolated to laughing with friends - becoming your most treasured possession", "rei_documentation", {"nostalgia": 30, "friendship": 20, "confidence": 12}),
("The moment you decided to apply to Oxford to study Japan officially, knowing you needed to come back to the place that taught you who you really are", "staying_decision", {"excitement": 25, "nostalgia": 25, "confidence": 15})
]
else:
return [("A quiet moment of reflection about growing up", "default_memory", {"nostalgia": 10, "friendship": 5})]
@staticmethod
def get_character_relationships(character: str) -> List[Tuple[str, str, Dict[str, int]]]:
"""Get character-specific relationship choices"""
if character == "hiroyuki":
return [
("Hina - the artist whose talent you helped nurture", "hina_connection", {"friendship": 20, "confidence": 15}),
("Hana - who appreciated your behind-the-scenes help", "hana_connection", {"friendship": 18, "nostalgia": 12}),
("Miyuki - who relied on your quiet support", "miyuki_connection", {"friendship": 15, "confidence": 10}),
("Haruto - your closest confidant about the future", "haruto_connection", {"nostalgia": 25, "friendship": 20})
]
elif character == "hina":
return [
("Hiroyuki - who believed in your art when no one else did", "hiroyuki_connection", {"confidence": 25, "friendship": 20}),
("Rei - your fellow artist and creative collaborator", "rei_connection", {"excitement": 20, "friendship": 18}),
("Andrew - fascinated by your cultural storytelling", "andrew_connection", {"friendship": 15, "confidence": 12}),
("Yuki - who inspired characters in your graduation manga", "yuki_connection", {"nostalgia": 18, "friendship": 15})
]
elif character == "hana":
return [
("Haruto - your twin brother finding his musical voice", "haruto_connection", {"nostalgia": 30, "friendship": 25}),
("Miyuki - your partner in planning the perfect graduation", "miyuki_connection", {"confidence": 20, "friendship": 18}),
("Kazuha - your dance partner and celebration coordinator", "kazuha_connection", {"excitement": 18, "friendship": 15}),
("Andrew - who helped you understand different perspectives", "andrew_connection", {"friendship": 15, "confidence": 12})
]
elif character == "miyuki":
return [
("Haruto - whose music opened your heart to new possibilities", "haruto_connection", {"excitement": 25, "confidence": 20}),
("Hana - your partner in creating perfect graduation memories", "hana_connection", {"friendship": 20, "confidence": 18}),
("Kazuha - who taught you that excellence includes joy", "kazuha_connection", {"nostalgia": 18, "friendship": 15}),
("Andrew - your language exchange partner and cultural bridge", "andrew_connection", {"friendship": 15, "confidence": 12})
]
elif character == "kazuha":
return [
("Haruto - your best friend who found courage through music", "haruto_connection", {"friendship": 25, "nostalgia": 20}),
("Andrew - your sports teammate and cultural exchange buddy", "andrew_connection", {"friendship": 20, "excitement": 18}),
("Miyuki - your friendly rival who learned to have fun", "miyuki_connection", {"friendship": 18, "nostalgia": 15}),
("Yuki - who you welcomed into the sports community", "yuki_connection", {"friendship": 15, "confidence": 12})
]
elif character == "haruto":
return [
("Hana - your twin sister who always believed in your music", "hana_connection", {"nostalgia": 30, "friendship": 25}),
("Kazuha - your best friend who gave you confidence", "kazuha_connection", {"friendship": 25, "confidence": 20}),
("Miyuki - who listened to your music with genuine appreciation", "miyuki_connection", {"excitement": 20, "friendship": 18}),
("Rei - who captured your musical journey through photography", "rei_connection", {"nostalgia": 18, "friendship": 15})
]
elif character == "yuki":
return [
("Andrew - your fellow outsider who became family", "andrew_connection", {"friendship": 25, "nostalgia": 20}),
("Hina - who included you in her artistic world", "hina_connection", {"friendship": 20, "confidence": 18}),
("Kazuha - who welcomed you into the sports community", "kazuha_connection", {"friendship": 18, "confidence": 15}),
("Miyuki - your study partner and dream-sharing friend", "miyuki_connection", {"friendship": 15, "confidence": 12})
]
elif character == "rei":
return [
("Hina - your artistic collaborator and creative inspiration", "hina_connection", {"excitement": 25, "friendship": 20}),
("Andrew - who you documented throughout his cultural journey", "andrew_connection", {"nostalgia": 20, "friendship": 18}),
("Haruto - whose musical awakening you captured beautifully", "haruto_connection", {"nostalgia": 18, "friendship": 15}),
("Sato - whose comedic spirit you learned to appreciate", "sato_connection", {"friendship": 15, "excitement": 12})
]
elif character == "sato":
return [
("Haruto - your creative collaborator in music and comedy", "haruto_connection", {"excitement": 20, "friendship": 18}),
("Andrew - who appreciated your humor across cultural barriers", "andrew_connection", {"friendship": 18, "confidence": 15}),
("Hiroyuki - who quietly supported your entertainment dreams", "hiroyuki_connection", {"friendship": 20, "confidence": 15}),
("Rei - who captured your best moments and genuine spirit", "rei_connection", {"nostalgia": 15, "friendship": 12})
]
elif character == "andrew":
return [
("Yuki - your partner in navigating outsider experiences", "yuki_connection", {"friendship": 25, "nostalgia": 20}),
("Kazuha - who welcomed you through sports and genuine friendship", "kazuha_connection", {"friendship": 20, "excitement": 18}),
("Rei - who documented your cultural discovery journey", "rei_connection", {"nostalgia": 22, "friendship": 15}),
("Miyuki - your language exchange partner and academic ally", "miyuki_connection", {"friendship": 18, "confidence": 12})
]
else:
return [("A significant person in your high school journey", "default_person", {"friendship": 10, "nostalgia": 5})]
@staticmethod
def get_optional_scenes(character: str) -> List[Dict[str, Any]]:
"""Get character-specific optional scenes with probability outcomes"""
if character == "hiroyuki":
return [
{
"scene_id": "confess_to_hina",
"title": "Confess your feelings to Hina",
"description": "You've supported her art for so long. Do you tell her your feelings before graduation?",
"trigger_condition": {"confidence": 25, "friendship": 30},
"outcomes": {
"accepted": {
"probability": 0.35,
"description": "Hina smiles and admits she's always hoped you'd say something",
"effects": {"excitement": 40, "confidence": 30, "friendship": 25},
"unlocks": "romance_ending"
},
"gentle_rejection": {
"probability": 0.40,
"description": "She values your friendship too much to risk changing it",
"effects": {"nostalgia": 20, "friendship": 15, "confidence": -5},
"unlocks": "friendship_ending"
},
"grateful_friendship": {
"probability": 0.25,
"description": "She's touched but focused on her manga career dreams",
"effects": {"friendship": 20, "confidence": 10, "nostalgia": 15},
"unlocks": "supportive_friend_memory"
}
}
},
{
"scene_id": "organize_class_reunion",
"title": "Propose organizing future class reunions",
"description": "You want to keep everyone connected. Do you take responsibility for future reunions?",
"trigger_condition": {"friendship": 40, "confidence": 25},
"outcomes": {
"enthusiastic_support": {
"probability": 0.45,
"description": "Everyone loves the idea and asks you to be the coordinator",
"effects": {"confidence": 25, "friendship": 30, "excitement": 20},
"unlocks": "class_coordinator_ending"
},
"moderate_interest": {
"probability": 0.35,