JavaScript is required. Please enable it to continue.
Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
Loading…
{ "name": "Two Weeks", "ifid": "097b51c9-87f4-4960-9464-0dbe392e7d00", "format": "SugarCube", "format-version": "2.36.1", "start": "Start" }
<<set $player = { "name": "You", "current_location": "", "core_traits": {"energy": 100, "boldness": 20}, "flags": {"game_started": false, "arrival_complete": false, "welcome_dinner_complete": false, "old_photos_complete": false, "sleepless_night_complete": false, "madison_calls_complete": false, "the_couch_complete": false, "confession_complete": false, "almost_kiss_complete": false, "real_talk_complete": false, "first_kiss": false, "what_are_we_doing_done": false, "first_night_complete": false, "morning_after_complete": false, "cant_stay_away_complete": false, "madison_arrived": false, "stolen_moment_complete": false, "night_before_complete": false, "wedding_morning_done": false} }>><<set $npcs = {"3dd42a70-8ac5-41f3-9288-5477929466eb": {"name": "Ethan", "core_traits": {"guilt": 10, "affection": 15}, "flags": {"comfortable": false, "interested": false, "vulnerable": false, "intimate": false}, "schedule": [{"activity": "Sleeping peacefully", "end_time": "07:00", "location": "loc_ethan_room", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "01:00"}, {"activity": "Making breakfast, coffee routine", "end_time": "09:00", "location": "loc_kitchen", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "07:00"}, {"activity": "Working from home, handling chores", "end_time": "12:00", "location": "loc_living", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "09:00"}, {"activity": "Lunch break, light meal prep", "end_time": "14:00", "location": "loc_kitchen", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "12:00"}, {"activity": "Exercise, swimming, outdoor projects", "end_time": "17:00", "location": "loc_backyard", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "14:00"}, {"activity": "Cooking dinner", "end_time": "19:00", "location": "loc_kitchen", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "17:00"}, {"activity": "Relaxing, watching TV", "end_time": "22:00", "location": "loc_living", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "19:00"}, {"activity": "Winding down, late night relaxation", "end_time": "01:00", "location": "loc_living", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "22:00"}]}, "52477dfa-5999-4087-b562-f77e4c5443b6": {"name": "Madison", "core_traits": {"presence": 0}, "flags": {}, "schedule": [{"activity": "Sleeping", "end_time": "08:00", "location": "loc_ethan_room", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "01:00"}, {"activity": "Wedding preparations", "end_time": "12:00", "location": "loc_kitchen", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "08:00"}, {"activity": "Finalizing wedding details", "end_time": "22:00", "location": "loc_living", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "12:00"}, {"activity": "Getting ready for bed", "end_time": "01:00", "location": "loc_ethan_room", "weekdays": [0, 1, 2, 3, 4, 5, 6], "start_time": "22:00"}]}}>><<set $npc_slug_map = {"npc_ethan": "3dd42a70-8ac5-41f3-9288-5477929466eb", "npc_madison": "52477dfa-5999-4087-b562-f77e4c5443b6"}>><<set $locations = {"loc_hallway": {"name": "Upstairs Hallway", "id": "6b717a40-88fc-45ef-bfd3-c58c0438052c"}, "loc_player_room": {"name": "Your Old Room", "id": "3eac7d4e-f70f-4744-bba2-01059c0b59c5"}, "loc_bathroom": {"name": "Upstairs Bathroom", "id": "c05d22eb-3a00-4972-a9ed-717ff4b1be73"}, "loc_ethan_room": {"name": "Ethan's Bedroom", "id": "6215c1db-cb47-4391-b2e7-dac657d835e2"}, "loc_living": {"name": "Living Room", "id": "025944f1-16b0-4b03-a1ab-935d9ddc076f"}, "loc_kitchen": {"name": "Kitchen", "id": "1cc5ebd9-1cdb-4202-a589-03322cb79f83"}, "loc_backyard": {"name": "Backyard & Pool", "id": "b062fb4f-2615-4e88-a350-c048096f2782"}, "loc_garage": {"name": "Garage", "id": "4dc5f240-c5a8-40d1-8997-41309fc625de"}}>><<set $flags = { "game_started": true, "debug_mode": false }>><<set $game_state = { "current_canvas": "", "visited_locations": [], "trigger_history": {}, "time_state": { "current_hour": 7, "current_minute": 0, "current_day": "Saturday", "current_week": 1 } }>><<set $story_arc = {"hints": {"templates": [], "hint_style": "observation", "stuck_threshold_minutes": 30}, "nodes": [{"id": "node_arrival", "npc": "npc_ethan", "name": "The Homecoming", "group": null, "chapter": "chapter_1", "linked_flag": "arrival_complete", "is_milestone": true, "journal_entry": "You're home. He's waiting at the door...", "linked_canvas": "scene_arrival", "requires_group": null, "requires_nodes": [], "trait_requirements": []}, {"id": "node_welcome_dinner", "npc": "npc_ethan", "name": "Welcome Home Dinner", "group": null, "chapter": "chapter_1", "linked_flag": "welcome_dinner_complete", "is_milestone": true, "journal_entry": "He cooked your favorite meal. Just like old times...", "linked_canvas": "scene_welcome_dinner", "requires_group": null, "requires_nodes": ["node_arrival"], "trait_requirements": []}, {"id": "node_memories", "npc": "npc_ethan", "name": "Old Photos", "group": null, "chapter": "chapter_1", "linked_flag": "old_photos_complete", "is_milestone": true, "journal_entry": "Old photos bring back feelings you buried...", "linked_canvas": "scene_old_photos", "requires_group": null, "requires_nodes": ["node_welcome_dinner"], "trait_requirements": []}, {"id": "node_sleepless_night", "npc": "npc_ethan", "name": "Sleepless Night", "group": null, "chapter": "chapter_1", "linked_flag": "sleepless_night_complete", "is_milestone": true, "journal_entry": "Neither of you can sleep. Late night confessions...", "linked_canvas": "scene_sleepless_night", "requires_group": null, "requires_nodes": ["node_memories"], "trait_requirements": []}, {"id": "node_madison_calls", "npc": "npc_ethan", "name": "Reality Intrudes", "group": null, "chapter": "chapter_1", "linked_flag": "madison_calls_complete", "is_milestone": true, "journal_entry": "Her voice on the phone. A reminder of what's coming...", "linked_canvas": "scene_madison_calls", "requires_group": null, "requires_nodes": ["node_sleepless_night"], "trait_requirements": []}, {"id": "node_the_couch", "npc": "npc_ethan", "name": "Movie Night", "group": null, "chapter": "chapter_2", "linked_flag": "the_couch_complete", "is_milestone": true, "journal_entry": "Under the blanket, boundaries blur...", "linked_canvas": "scene_the_couch", "requires_group": null, "requires_nodes": ["node_madison_calls"], "trait_requirements": []}, {"id": "node_confession", "npc": "npc_ethan", "name": "The Confession", "group": null, "chapter": "chapter_2", "linked_flag": "confession_complete", "is_milestone": true, "journal_entry": "You finally said what you've been hiding...", "linked_canvas": "scene_confession", "requires_group": null, "requires_nodes": ["node_the_couch"], "trait_requirements": []}, {"id": "node_almost_kiss", "npc": "npc_ethan", "name": "Almost Kiss", "group": null, "chapter": "chapter_2", "linked_flag": "almost_kiss_complete", "is_milestone": true, "journal_entry": "So close. Then interrupted...", "linked_canvas": "scene_almost_kiss", "requires_group": null, "requires_nodes": ["node_confession"], "trait_requirements": []}, {"id": "node_real_talk", "npc": "npc_ethan", "name": "The Real Talk", "group": null, "chapter": "chapter_2", "linked_flag": "real_talk_complete", "is_milestone": true, "journal_entry": "Raw honesty in the dark. He admits what he's been hiding...", "linked_canvas": "scene_real_talk", "requires_group": null, "requires_nodes": ["node_almost_kiss"], "trait_requirements": []}, {"id": "node_first_kiss", "npc": "npc_ethan", "name": "First Kiss", "group": null, "chapter": "chapter_3", "linked_flag": "first_kiss", "is_milestone": true, "journal_entry": "The first kiss. No going back now...", "linked_canvas": "scene_first_kiss", "requires_group": null, "requires_nodes": ["node_real_talk"], "trait_requirements": []}, {"id": "node_what_are_we_doing", "npc": "npc_ethan", "name": "What Are We Doing", "group": null, "chapter": "chapter_3", "linked_flag": "what_are_we_doing_done", "is_milestone": true, "journal_entry": "The morning after. Reality sets in...", "linked_canvas": "scene_what_are_we_doing", "requires_group": null, "requires_nodes": ["node_first_kiss"], "trait_requirements": []}, {"id": "node_first_night", "npc": "npc_ethan", "name": "First Night", "group": null, "chapter": "chapter_3", "linked_flag": "first_night_complete", "is_milestone": true, "journal_entry": "You gave yourselves to each other...", "linked_canvas": "scene_first_night", "requires_group": null, "requires_nodes": ["node_what_are_we_doing"], "trait_requirements": []}, {"id": "node_morning_after", "npc": "npc_ethan", "name": "Morning After", "group": null, "chapter": "chapter_3", "linked_flag": "morning_after_complete", "is_milestone": true, "journal_entry": "Waking up together. No regrets...", "linked_canvas": "scene_morning_after", "requires_group": null, "requires_nodes": ["node_first_night"], "trait_requirements": []}, {"id": "node_cant_stay_away", "npc": "npc_ethan", "name": "Can't Stay Away", "group": null, "chapter": "chapter_3", "linked_flag": "cant_stay_away_complete", "is_milestone": true, "journal_entry": "The addiction sets in. You can't resist...", "linked_canvas": "scene_cant_stay_away", "requires_group": null, "requires_nodes": ["node_morning_after"], "trait_requirements": []}, {"id": "node_madison_arrives", "npc": "npc_ethan", "name": "Madison Arrives", "group": null, "chapter": "chapter_4", "linked_flag": "madison_arrived", "is_milestone": true, "journal_entry": "She's here. The fianc\u00e9e is real...", "linked_canvas": "scene_madison_arrives", "requires_group": null, "requires_nodes": ["node_cant_stay_away"], "trait_requirements": []}, {"id": "node_stolen_moment", "npc": "npc_ethan", "name": "Stolen Moment", "group": null, "chapter": "chapter_4", "linked_flag": "stolen_moment_complete", "is_milestone": true, "journal_entry": "Desperate with Madison in the house...", "linked_canvas": "scene_stolen_moment", "requires_group": null, "requires_nodes": ["node_madison_arrives"], "trait_requirements": []}, {"id": "node_night_before_wedding", "npc": "npc_ethan", "name": "Night Before Wedding", "group": null, "chapter": "chapter_4", "linked_flag": "night_before_complete", "is_milestone": true, "journal_entry": "Tomorrow changes everything. One last night...", "linked_canvas": "scene_night_before_wedding", "requires_group": null, "requires_nodes": ["node_stolen_moment"], "trait_requirements": []}, {"id": "node_finale", "npc": "npc_ethan", "name": "Wedding Morning", "group": null, "chapter": "chapter_5", "linked_flag": "wedding_morning_done", "is_milestone": true, "journal_entry": "The day has come. Everything leads here...", "linked_canvas": "scene_wedding_morning", "requires_group": null, "requires_nodes": ["node_night_before_wedding"], "trait_requirements": []}], "groups": [], "version": "1.0", "chapters": [{"id": "chapter_1", "mood": "hopeful", "name": "The Homecoming", "order": 1, "description": "After two years away, you've returned home for Ethan's wedding. Old feelings stir as you settle back into the house where you grew up together..."}, {"id": "chapter_2", "mood": "romantic", "name": "Rekindled Flames", "order": 2, "description": "The careful distance you've maintained is crumbling. Every shared moment, every lingering look, pulls you closer to something forbidden..."}, {"id": "chapter_3", "mood": "passionate", "name": "Crossing Lines", "order": 3, "description": "You've crossed a line that can't be uncrossed. The question now isn't whether you want this\u2014it's what you're willing to risk for it..."}, {"id": "chapter_4", "mood": "tense", "name": "Point of No Return", "order": 4, "description": "Madison has arrived. In just hours, he'll stand at an altar. Time is running out to decide what your story will become..."}, {"id": "chapter_5", "mood": "peaceful", "name": "The Wedding", "order": 5, "description": "The wedding day has come. Everything you've shared leads to this moment. Some choices change everything..."}], "emotion_mappings": {"affection": {"trait_owner": "npc", "ranges": [{"min": 0, "max": 25, "label": "distant", "description": "There's still a barrier between you"}, {"min": 26, "max": 50, "label": "warming", "description": "Something is slowly growing between you"}, {"min": 51, "max": 75, "label": "connected", "description": "She feels genuinely close to you now"}, {"min": 76, "max": 100, "label": "devoted", "description": "Her feelings for you run deep"}]}, "arousal": {"trait_owner": "npc", "ranges": [{"min": 0, "max": 20, "label": "calm", "description": "Composed and relaxed"}, {"min": 21, "max": 50, "label": "aware", "description": "There's a subtle tension in her gaze"}, {"min": 51, "max": 75, "label": "yearning", "description": "Her body language speaks of desire"}, {"min": 76, "max": 100, "label": "burning", "description": "The passion is barely contained"}]}, "appreciation": {"trait_owner": "npc", "ranges": [{"min": 0, "max": 25, "label": "indifferent", "description": "Your efforts go unnoticed"}, {"min": 26, "max": 50, "label": "noticing", "description": "She's starting to notice your care"}, {"min": 51, "max": 75, "label": "grateful", "description": "She deeply appreciates what you do"}, {"min": 76, "max": 100, "label": "cherishing", "description": "She treasures every moment with you"}]}, "trust": {"trait_owner": "npc", "ranges": [{"min": 0, "max": 25, "label": "wary", "description": "She keeps her guard up"}, {"min": 26, "max": 50, "label": "opening", "description": "Walls are slowly coming down"}, {"min": 51, "max": 75, "label": "trusting", "description": "There's real trust between you"}, {"min": 76, "max": 100, "label": "complete", "description": "Complete faith in each other"}]}}}>><<set $help_data = {"npcs": {"3dd42a70-8ac5-41f3-9288-5477929466eb": {"name": "Ethan", "activities": [{"node_id": "node_arrival", "name": "The Homecoming", "linked_flag": "arrival_complete", "canvas_id": "3ae0a423-d98e-4659-900c-f6a43bd6a3e5", "requires_nodes": [], "requires_group": null, "location": null, "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 2}], "canvas_conditions": null}, {"node_id": "node_welcome_dinner", "name": "Welcome Home Dinner", "linked_flag": "welcome_dinner_complete", "canvas_id": "9da03758-d6d0-4cea-ab7f-c86473348579", "requires_nodes": ["node_arrival"], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 1}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_memories", "name": "Old Photos", "linked_flag": "old_photos_complete", "canvas_id": "b133cce8-dae7-4c11-a1db-d75552e256c8", "requires_nodes": ["node_welcome_dinner"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "welcome_dinner_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_sleepless_night", "name": "Sleepless Night", "linked_flag": "sleepless_night_complete", "canvas_id": "e2bfbeb9-ebc9-458e-96f5-1a854ad75be7", "requires_nodes": ["node_memories"], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "old_photos_complete", "operator": "is_true"}, {"type": "trait", "value": 25, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_madison_calls", "name": "Reality Intrudes", "linked_flag": "madison_calls_complete", "canvas_id": "22cc3189-8f9f-4016-837c-3014248a4bff", "requires_nodes": ["node_sleepless_night"], "requires_group": null, "location": "Living Room", "schedule": "between 12 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}, {"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_the_couch", "name": "Movie Night", "linked_flag": "the_couch_complete", "canvas_id": "586e0e77-efb7-4334-80eb-23411951bdb4", "requires_nodes": ["node_madison_calls"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_confession", "name": "The Confession", "linked_flag": "confession_complete", "canvas_id": "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff", "requires_nodes": ["node_the_couch"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 8, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 10, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "the_couch_complete", "operator": "is_true"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 40, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_almost_kiss", "name": "Almost Kiss", "linked_flag": "almost_kiss_complete", "canvas_id": "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5", "requires_nodes": ["node_confession"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "confession_complete", "operator": "is_true"}, {"type": "trait", "value": 55, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_real_talk", "name": "The Real Talk", "linked_flag": "real_talk_complete", "canvas_id": "721b6515-4264-4630-b9c4-8eafcf6e5120", "requires_nodes": ["node_almost_kiss"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 8}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_kiss", "name": "First Kiss", "linked_flag": "first_kiss", "canvas_id": "9c442310-64b4-4b5d-8d04-e1705e8aa45e", "requires_nodes": ["node_real_talk"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_what_are_we_doing", "name": "What Are We Doing", "linked_flag": "what_are_we_doing_done", "canvas_id": "be2226c6-ae16-4fe1-b960-e037361a6c5f", "requires_nodes": ["node_first_kiss"], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_night", "name": "First Night", "linked_flag": "first_night_complete", "canvas_id": "3c251c46-2604-493f-95ad-488ff4e13af0", "requires_nodes": ["node_what_are_we_doing"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_morning_after", "name": "Morning After", "linked_flag": "morning_after_complete", "canvas_id": "94751735-6f29-4dd2-b5f8-871202ec0ed5", "requires_nodes": ["node_first_night"], "requires_group": null, "location": "Your Old Room", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_cant_stay_away", "name": "Can't Stay Away", "linked_flag": "cant_stay_away_complete", "canvas_id": "7f5880ef-b71d-47d3-9506-aa2caaefe382", "requires_nodes": ["node_morning_after"], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "morning_after_complete", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_madison_arrives", "name": "Madison Arrives", "linked_flag": "madison_arrived", "canvas_id": "7ab8806f-3582-4c37-a50f-93abbaf872e0", "requires_nodes": ["node_cant_stay_away"], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "cant_stay_away_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_stolen_moment", "name": "Stolen Moment", "linked_flag": "stolen_moment_complete", "canvas_id": "fc57410a-9ac2-40d5-a14f-f94845cc34ce", "requires_nodes": ["node_madison_arrives"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 10}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_arrived", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_night_before_wedding", "name": "Night Before Wedding", "linked_flag": "night_before_complete", "canvas_id": "4840b621-e25f-411f-b937-28acadc2f012", "requires_nodes": ["node_stolen_moment"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 10}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "stolen_moment_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_finale", "name": "Wedding Morning", "linked_flag": "wedding_morning_done", "canvas_id": "285a83a5-320e-4969-a558-e0fbb69d1827", "requires_nodes": ["node_night_before_wedding"], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "night_before_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "38d240e2-e18b-4cf4-b77c-a6b85a3a6765", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "a39d2179-f7e6-4ba6-b1e3-f146bb812b71", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "8041f658-eee5-434f-a24f-95533104b894", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "aee10b91-48f4-4f2c-b8b4-b4ff83d8616f", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "09b332a6-eab6-4d97-99a3-6561abc42d6c", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "73cbe973-6aea-457e-99e9-ea46f429d150", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "4429251c-f1ed-4dcd-a04d-975f344d695e", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "7073455c-e506-42c3-9640-040428d6d7b8", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "21935a2f-f38a-48e6-9f7e-ae7c779d0174", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "b23c38a0-f8da-46f6-8907-4b3e9864cf01", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "bb21f5b3-2da9-492e-868d-420e0410a1b3", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "ed02ae76-4628-4e21-81ca-68034f18ff4d", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "8b2415a0-6e95-4b6a-9b98-a03d2687f9f2", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "6d3be5b5-228d-49b4-b2de-0e660517e128", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "2989df0a-81ef-4b23-b710-bd989edd0907", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "ad75137d-989d-4249-b993-1e7b17fadeb5", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "3557832c-8856-4f2f-a4d2-585a1c75efaa", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "bce73abd-d2c3-4e33-be56-72c5e7c47fc8", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "3aeb65fd-0961-4fcd-97ea-08e20d628f59", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "71a09dc8-ff6d-49d1-8f7f-9503785208a3", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "059b39cb-a627-4c0e-98fc-4a30f3bff6f1", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "7d3d56ea-bb73-449b-b1d8-8bfd29007d58", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "72b91eee-7c46-48ab-ae97-06db9a2fd794", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "e9207826-c6d9-4a09-a5f3-e4130c5ad2bc", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "477d5c97-650d-49bf-9a00-0b93222611e2", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "02360f7c-2c25-41cd-a4ae-d9e938447c08", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "37348391-17a3-4e3d-9b44-0ca228158524", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "539a7f90-0877-4a6d-85b8-e11f4f8991e9", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "824f28ea-3a40-4dbc-8d26-4baf91102db0", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "8bdd9b31-acf8-405d-a14a-30b1212398a3", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "409aa9e5-c940-4640-8408-91041d4e7811", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "2ab37e92-9d1b-4438-a17a-59b8b5a6cba3", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "b8f87c2e-e5f3-40eb-940e-7a8dda96b944", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "769fa786-16b6-4d36-b3af-2b61e2a22f19", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "a08fa545-9646-4033-b22a-2a6b94bec46c", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "c421f29f-4582-43e4-acba-3499ad09aefa", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "774fd167-ddd5-46f9-9f2e-88bc59f6315f", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "2ac679db-bf7e-48ca-9fd3-5f9a0cdc33ef", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "73621d16-03fe-437c-b2e9-a206a140b7bf", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "3a457bc9-99be-45f6-bfd9-fb6b7643ddf4", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "a300e4b5-1773-4d05-9617-c98ca9199611", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "5fc3e920-273f-45ac-ba92-9317ceeae930", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "b153b9e7-3d1b-47fc-80f8-c20786cdf0be", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "d2f3b351-39c2-4ae2-be8e-a45aab258739", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "e20039b6-7886-4214-aeb2-34e96f4aa6fa", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "71bafae7-a820-43df-ae90-d0cf20306c01", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "52b8fa8c-bdec-441f-a02b-38678ad6d3d1", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "64e060ee-617f-4eab-b2ff-105075f0e437", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "3a9eea3d-5353-4f8d-b721-8ad04ddafb3a", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "18dd23b7-00c0-4faf-8e6a-6a10910bbac7", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "33ddf963-458e-404e-abe9-95a64c3ce300", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "e89e834e-1adc-49d2-b6fa-0d456cf957d7", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "621821ba-98ae-4ae7-84b0-fbeee182593f", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "055ec2e8-6a21-41b5-b399-18efb7745eda", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "3ab52809-3b7c-4a0c-8dc0-cd2022f0e8dc", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "2b22e43e-794e-43ea-a800-6837d324dc0d", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "41bc2a64-cec7-47d0-9f45-b1fa206d237b", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "f8c84bf8-0eb5-40d0-9b34-efd914063f3d", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "ef8853bf-9a29-4b7a-8bbd-f9a1856656c2", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "dba6552a-a82f-4f32-a5af-0b378681db25", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}]}}, "trait_activities": {"affection": [{"node_id": "node_arrival", "name": "The Homecoming", "linked_flag": "arrival_complete", "canvas_id": "3ae0a423-d98e-4659-900c-f6a43bd6a3e5", "requires_nodes": [], "requires_group": null, "location": null, "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 2}], "canvas_conditions": null}, {"node_id": "node_arrival", "name": "The Homecoming", "linked_flag": "arrival_complete", "canvas_id": "3ae0a423-d98e-4659-900c-f6a43bd6a3e5", "requires_nodes": [], "requires_group": null, "location": null, "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 2}], "canvas_conditions": null}, {"node_id": "node_welcome_dinner", "name": "Welcome Home Dinner", "linked_flag": "welcome_dinner_complete", "canvas_id": "9da03758-d6d0-4cea-ab7f-c86473348579", "requires_nodes": ["node_arrival"], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 1}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_welcome_dinner", "name": "Welcome Home Dinner", "linked_flag": "welcome_dinner_complete", "canvas_id": "9da03758-d6d0-4cea-ab7f-c86473348579", "requires_nodes": ["node_arrival"], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 1}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_memories", "name": "Old Photos", "linked_flag": "old_photos_complete", "canvas_id": "b133cce8-dae7-4c11-a1db-d75552e256c8", "requires_nodes": ["node_welcome_dinner"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "welcome_dinner_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_memories", "name": "Old Photos", "linked_flag": "old_photos_complete", "canvas_id": "b133cce8-dae7-4c11-a1db-d75552e256c8", "requires_nodes": ["node_welcome_dinner"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "welcome_dinner_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_sleepless_night", "name": "Sleepless Night", "linked_flag": "sleepless_night_complete", "canvas_id": "e2bfbeb9-ebc9-458e-96f5-1a854ad75be7", "requires_nodes": ["node_memories"], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "old_photos_complete", "operator": "is_true"}, {"type": "trait", "value": 25, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_sleepless_night", "name": "Sleepless Night", "linked_flag": "sleepless_night_complete", "canvas_id": "e2bfbeb9-ebc9-458e-96f5-1a854ad75be7", "requires_nodes": ["node_memories"], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "old_photos_complete", "operator": "is_true"}, {"type": "trait", "value": 25, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_madison_calls", "name": "Reality Intrudes", "linked_flag": "madison_calls_complete", "canvas_id": "22cc3189-8f9f-4016-837c-3014248a4bff", "requires_nodes": ["node_sleepless_night"], "requires_group": null, "location": "Living Room", "schedule": "between 12 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}, {"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_the_couch", "name": "Movie Night", "linked_flag": "the_couch_complete", "canvas_id": "586e0e77-efb7-4334-80eb-23411951bdb4", "requires_nodes": ["node_madison_calls"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_the_couch", "name": "Movie Night", "linked_flag": "the_couch_complete", "canvas_id": "586e0e77-efb7-4334-80eb-23411951bdb4", "requires_nodes": ["node_madison_calls"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_the_couch", "name": "Movie Night", "linked_flag": "the_couch_complete", "canvas_id": "586e0e77-efb7-4334-80eb-23411951bdb4", "requires_nodes": ["node_madison_calls"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_confession", "name": "The Confession", "linked_flag": "confession_complete", "canvas_id": "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff", "requires_nodes": ["node_the_couch"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 8, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 10, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "the_couch_complete", "operator": "is_true"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 40, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_confession", "name": "The Confession", "linked_flag": "confession_complete", "canvas_id": "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff", "requires_nodes": ["node_the_couch"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 8, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 10, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "the_couch_complete", "operator": "is_true"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 40, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_almost_kiss", "name": "Almost Kiss", "linked_flag": "almost_kiss_complete", "canvas_id": "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5", "requires_nodes": ["node_confession"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "confession_complete", "operator": "is_true"}, {"type": "trait", "value": 55, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_real_talk", "name": "The Real Talk", "linked_flag": "real_talk_complete", "canvas_id": "721b6515-4264-4630-b9c4-8eafcf6e5120", "requires_nodes": ["node_almost_kiss"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 8}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_real_talk", "name": "The Real Talk", "linked_flag": "real_talk_complete", "canvas_id": "721b6515-4264-4630-b9c4-8eafcf6e5120", "requires_nodes": ["node_almost_kiss"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 8}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_kiss", "name": "First Kiss", "linked_flag": "first_kiss", "canvas_id": "9c442310-64b4-4b5d-8d04-e1705e8aa45e", "requires_nodes": ["node_real_talk"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_kiss", "name": "First Kiss", "linked_flag": "first_kiss", "canvas_id": "9c442310-64b4-4b5d-8d04-e1705e8aa45e", "requires_nodes": ["node_real_talk"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_kiss", "name": "First Kiss", "linked_flag": "first_kiss", "canvas_id": "9c442310-64b4-4b5d-8d04-e1705e8aa45e", "requires_nodes": ["node_real_talk"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_what_are_we_doing", "name": "What Are We Doing", "linked_flag": "what_are_we_doing_done", "canvas_id": "be2226c6-ae16-4fe1-b960-e037361a6c5f", "requires_nodes": ["node_first_kiss"], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_what_are_we_doing", "name": "What Are We Doing", "linked_flag": "what_are_we_doing_done", "canvas_id": "be2226c6-ae16-4fe1-b960-e037361a6c5f", "requires_nodes": ["node_first_kiss"], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_night", "name": "First Night", "linked_flag": "first_night_complete", "canvas_id": "3c251c46-2604-493f-95ad-488ff4e13af0", "requires_nodes": ["node_what_are_we_doing"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_night", "name": "First Night", "linked_flag": "first_night_complete", "canvas_id": "3c251c46-2604-493f-95ad-488ff4e13af0", "requires_nodes": ["node_what_are_we_doing"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_morning_after", "name": "Morning After", "linked_flag": "morning_after_complete", "canvas_id": "94751735-6f29-4dd2-b5f8-871202ec0ed5", "requires_nodes": ["node_first_night"], "requires_group": null, "location": "Your Old Room", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_morning_after", "name": "Morning After", "linked_flag": "morning_after_complete", "canvas_id": "94751735-6f29-4dd2-b5f8-871202ec0ed5", "requires_nodes": ["node_first_night"], "requires_group": null, "location": "Your Old Room", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_stolen_moment", "name": "Stolen Moment", "linked_flag": "stolen_moment_complete", "canvas_id": "fc57410a-9ac2-40d5-a14f-f94845cc34ce", "requires_nodes": ["node_madison_arrives"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 10}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_arrived", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_night_before_wedding", "name": "Night Before Wedding", "linked_flag": "night_before_complete", "canvas_id": "4840b621-e25f-411f-b937-28acadc2f012", "requires_nodes": ["node_stolen_moment"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 10}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "stolen_moment_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "38d240e2-e18b-4cf4-b77c-a6b85a3a6765", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "a39d2179-f7e6-4ba6-b1e3-f146bb812b71", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "8041f658-eee5-434f-a24f-95533104b894", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "aee10b91-48f4-4f2c-b8b4-b4ff83d8616f", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Saying Goodnight", "linked_flag": null, "canvas_id": "09b332a6-eab6-4d97-99a3-6561abc42d6c", "requires_nodes": [], "requires_group": null, "location": "Upstairs Hallway", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "73cbe973-6aea-457e-99e9-ea46f429d150", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "4429251c-f1ed-4dcd-a04d-975f344d695e", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "7073455c-e506-42c3-9640-040428d6d7b8", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "21935a2f-f38a-48e6-9f7e-ae7c779d0174", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Late Night Kitchen", "linked_flag": null, "canvas_id": "b23c38a0-f8da-46f6-8907-4b3e9864cf01", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "bb21f5b3-2da9-492e-868d-420e0410a1b3", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "ed02ae76-4628-4e21-81ca-68034f18ff4d", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "8b2415a0-6e95-4b6a-9b98-a03d2687f9f2", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "6d3be5b5-228d-49b4-b2de-0e660517e128", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "2989df0a-81ef-4b23-b710-bd989edd0907", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "ad75137d-989d-4249-b993-1e7b17fadeb5", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "3557832c-8856-4f2f-a4d2-585a1c75efaa", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "bce73abd-d2c3-4e33-be56-72c5e7c47fc8", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "3aeb65fd-0961-4fcd-97ea-08e20d628f59", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Movie Night", "linked_flag": null, "canvas_id": "71a09dc8-ff6d-49d1-8f7f-9503785208a3", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "059b39cb-a627-4c0e-98fc-4a30f3bff6f1", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "7d3d56ea-bb73-449b-b1d8-8bfd29007d58", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "72b91eee-7c46-48ab-ae97-06db9a2fd794", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "e9207826-c6d9-4a09-a5f3-e4130c5ad2bc", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Dinner with Ethan", "linked_flag": null, "canvas_id": "477d5c97-650d-49bf-9a00-0b93222611e2", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "02360f7c-2c25-41cd-a4ae-d9e938447c08", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "37348391-17a3-4e3d-9b44-0ca228158524", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "539a7f90-0877-4a6d-85b8-e11f4f8991e9", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "824f28ea-3a40-4dbc-8d26-4baf91102db0", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Cooking Together", "linked_flag": null, "canvas_id": "8bdd9b31-acf8-405d-a14a-30b1212398a3", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "409aa9e5-c940-4640-8408-91041d4e7811", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "2ab37e92-9d1b-4438-a17a-59b8b5a6cba3", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "b8f87c2e-e5f3-40eb-940e-7a8dda96b944", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "769fa786-16b6-4d36-b3af-2b61e2a22f19", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "a08fa545-9646-4033-b22a-2a6b94bec46c", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "c421f29f-4582-43e4-acba-3499ad09aefa", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "774fd167-ddd5-46f9-9f2e-88bc59f6315f", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "2ac679db-bf7e-48ca-9fd3-5f9a0cdc33ef", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "73621d16-03fe-437c-b2e9-a206a140b7bf", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Pool Time", "linked_flag": null, "canvas_id": "3a457bc9-99be-45f6-bfd9-fb6b7643ddf4", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "a300e4b5-1773-4d05-9617-c98ca9199611", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "5fc3e920-273f-45ac-ba92-9317ceeae930", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "b153b9e7-3d1b-47fc-80f8-c20786cdf0be", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "d2f3b351-39c2-4ae2-be8e-a45aab258739", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Lunch Together", "linked_flag": null, "canvas_id": "e20039b6-7886-4214-aeb2-34e96f4aa6fa", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 12 PM - 2 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "71bafae7-a820-43df-ae90-d0cf20306c01", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "52b8fa8c-bdec-441f-a02b-38678ad6d3d1", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "64e060ee-617f-4eab-b2ff-105075f0e437", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "3a9eea3d-5353-4f8d-b721-8ad04ddafb3a", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Helping with Chores", "linked_flag": null, "canvas_id": "18dd23b7-00c0-4faf-8e6a-6a10910bbac7", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 9 AM - 12 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "33ddf963-458e-404e-abe9-95a64c3ce300", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "e89e834e-1adc-49d2-b6fa-0d456cf957d7", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "621821ba-98ae-4ae7-84b0-fbeee182593f", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "055ec2e8-6a21-41b5-b399-18efb7745eda", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Morning Coffee", "linked_flag": null, "canvas_id": "3ab52809-3b7c-4a0c-8dc0-cd2022f0e8dc", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "2b22e43e-794e-43ea-a800-6837d324dc0d", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "41bc2a64-cec7-47d0-9f45-b1fa206d237b", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "f8c84bf8-0eb5-40d0-9b34-efd914063f3d", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "ef8853bf-9a29-4b7a-8bbd-f9a1856656c2", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Breakfast with Ethan", "linked_flag": null, "canvas_id": "dba6552a-a82f-4f32-a5af-0b378681db25", "requires_nodes": [], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}], "boldness": [{"node_id": "node_arrival", "name": "The Homecoming", "linked_flag": "arrival_complete", "canvas_id": "3ae0a423-d98e-4659-900c-f6a43bd6a3e5", "requires_nodes": [], "requires_group": null, "location": null, "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 2}], "canvas_conditions": null}, {"node_id": "node_welcome_dinner", "name": "Welcome Home Dinner", "linked_flag": "welcome_dinner_complete", "canvas_id": "9da03758-d6d0-4cea-ab7f-c86473348579", "requires_nodes": ["node_arrival"], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 1}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_memories", "name": "Old Photos", "linked_flag": "old_photos_complete", "canvas_id": "b133cce8-dae7-4c11-a1db-d75552e256c8", "requires_nodes": ["node_welcome_dinner"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "welcome_dinner_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_madison_calls", "name": "Reality Intrudes", "linked_flag": "madison_calls_complete", "canvas_id": "22cc3189-8f9f-4016-837c-3014248a4bff", "requires_nodes": ["node_sleepless_night"], "requires_group": null, "location": "Living Room", "schedule": "between 12 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}, {"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_the_couch", "name": "Movie Night", "linked_flag": "the_couch_complete", "canvas_id": "586e0e77-efb7-4334-80eb-23411951bdb4", "requires_nodes": ["node_madison_calls"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_confession", "name": "The Confession", "linked_flag": "confession_complete", "canvas_id": "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff", "requires_nodes": ["node_the_couch"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 8, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 10, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "the_couch_complete", "operator": "is_true"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 40, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_almost_kiss", "name": "Almost Kiss", "linked_flag": "almost_kiss_complete", "canvas_id": "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5", "requires_nodes": ["node_confession"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "confession_complete", "operator": "is_true"}, {"type": "trait", "value": 55, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_real_talk", "name": "The Real Talk", "linked_flag": "real_talk_complete", "canvas_id": "721b6515-4264-4630-b9c4-8eafcf6e5120", "requires_nodes": ["node_almost_kiss"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 8}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_kiss", "name": "First Kiss", "linked_flag": "first_kiss", "canvas_id": "9c442310-64b4-4b5d-8d04-e1705e8aa45e", "requires_nodes": ["node_real_talk"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_what_are_we_doing", "name": "What Are We Doing", "linked_flag": "what_are_we_doing_done", "canvas_id": "be2226c6-ae16-4fe1-b960-e037361a6c5f", "requires_nodes": ["node_first_kiss"], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_stolen_moment", "name": "Stolen Moment", "linked_flag": "stolen_moment_complete", "canvas_id": "fc57410a-9ac2-40d5-a14f-f94845cc34ce", "requires_nodes": ["node_madison_arrives"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 10}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_arrived", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_night_before_wedding", "name": "Night Before Wedding", "linked_flag": "night_before_complete", "canvas_id": "4840b621-e25f-411f-b937-28acadc2f012", "requires_nodes": ["node_stolen_moment"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 10}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "stolen_moment_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": null, "name": "Get Ready", "linked_flag": null, "canvas_id": "40bff3dc-70eb-413f-a93b-9ce360da0481", "requires_nodes": [], "requires_group": null, "location": "Upstairs Bathroom", "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 2}], "canvas_conditions": null, "is_repeatable": true}, {"node_id": null, "name": "Unpack Your Things", "linked_flag": null, "canvas_id": "2545cef7-fb06-4ab4-8d78-cc2fb8b314d2", "requires_nodes": [], "requires_group": null, "location": "Your Old Room", "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "boldness", "value": 2}], "canvas_conditions": null, "is_repeatable": false}], "guilt": [{"node_id": "node_welcome_dinner", "name": "Welcome Home Dinner", "linked_flag": "welcome_dinner_complete", "canvas_id": "9da03758-d6d0-4cea-ab7f-c86473348579", "requires_nodes": ["node_arrival"], "requires_group": null, "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 1}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_madison_calls", "name": "Reality Intrudes", "linked_flag": "madison_calls_complete", "canvas_id": "22cc3189-8f9f-4016-837c-3014248a4bff", "requires_nodes": ["node_sleepless_night"], "requires_group": null, "location": "Living Room", "schedule": "between 12 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}, {"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_the_couch", "name": "Movie Night", "linked_flag": "the_couch_complete", "canvas_id": "586e0e77-efb7-4334-80eb-23411951bdb4", "requires_nodes": ["node_madison_calls"], "requires_group": null, "location": "Living Room", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 3}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_almost_kiss", "name": "Almost Kiss", "linked_flag": "almost_kiss_complete", "canvas_id": "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5", "requires_nodes": ["node_confession"], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "confession_complete", "operator": "is_true"}, {"type": "trait", "value": 55, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_what_are_we_doing", "name": "What Are We Doing", "linked_flag": "what_are_we_doing_done", "canvas_id": "be2226c6-ae16-4fe1-b960-e037361a6c5f", "requires_nodes": ["node_first_kiss"], "requires_group": null, "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 5}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_first_night", "name": "First Night", "linked_flag": "first_night_complete", "canvas_id": "3c251c46-2604-493f-95ad-488ff4e13af0", "requires_nodes": ["node_what_are_we_doing"], "requires_group": null, "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 5, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_morning_after", "name": "Morning After", "linked_flag": "morning_after_complete", "canvas_id": "94751735-6f29-4dd2-b5f8-871202ec0ed5", "requires_nodes": ["node_first_night"], "requires_group": null, "location": "Your Old Room", "schedule": "between 7 AM - 9 AM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "affection", "value": 5, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, {"node_id": "node_stolen_moment", "name": "Stolen Moment", "linked_flag": "stolen_moment_complete", "canvas_id": "fc57410a-9ac2-40d5-a14f-f94845cc34ce", "requires_nodes": ["node_madison_arrives"], "requires_group": null, "location": "Garage", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 3, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 5, "npc_id": "npc_ethan"}, {"trait": "boldness", "value": 10}], "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_arrived", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "bb21f5b3-2da9-492e-868d-420e0410a1b3", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "ed02ae76-4628-4e21-81ca-68034f18ff4d", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "8b2415a0-6e95-4b6a-9b98-a03d2687f9f2", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "6d3be5b5-228d-49b4-b2de-0e660517e128", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wine & Talk", "linked_flag": null, "canvas_id": "2989df0a-81ef-4b23-b710-bd989edd0907", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 4, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 2, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "409aa9e5-c940-4640-8408-91041d4e7811", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "2ab37e92-9d1b-4438-a17a-59b8b5a6cba3", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "b8f87c2e-e5f3-40eb-940e-7a8dda96b944", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "769fa786-16b6-4d36-b3af-2b61e2a22f19", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}, {"node_id": null, "name": "Wedding Planning Help", "linked_flag": null, "canvas_id": "a08fa545-9646-4033-b22a-2a6b94bec46c", "requires_nodes": [], "requires_group": null, "location": "Living Room", "schedule": "between 2 PM - 5 PM", "trait_requirements": [], "trait_effects": [{"trait": "affection", "value": 2, "npc_id": "npc_ethan"}, {"trait": "guilt", "value": 3, "npc_id": "npc_ethan"}], "canvas_conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "is_repeatable": true}], "energy": [{"node_id": null, "name": "Swim Alone", "linked_flag": null, "canvas_id": "5e176181-e161-43e7-8dda-fcacf805e90b", "requires_nodes": [], "requires_group": null, "location": "Backyard & Pool", "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "energy", "value": 10}], "canvas_conditions": null, "is_repeatable": true}, {"node_id": null, "name": "Get Some Rest", "linked_flag": null, "canvas_id": "e4501f93-13d9-4faf-8701-ca5e05f2c148", "requires_nodes": [], "requires_group": null, "location": "Your Old Room", "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "energy", "value": 20}, {"trait": "energy", "value": 100}], "canvas_conditions": null, "is_repeatable": true}, {"node_id": null, "name": "Get Some Rest", "linked_flag": null, "canvas_id": "e4501f93-13d9-4faf-8701-ca5e05f2c148", "requires_nodes": [], "requires_group": null, "location": "Your Old Room", "schedule": null, "trait_requirements": [], "trait_effects": [{"trait": "energy", "value": 20}, {"trait": "energy", "value": 100}], "canvas_conditions": null, "is_repeatable": true}]}, "flag_unlock_map": {"wedding_morning_done": {"canvas_name": "Wedding Morning", "canvas_id": "285a83a5-320e-4969-a558-e0fbb69d1827", "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "night_before_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, "stolen_moment_complete": {"canvas_name": "Stolen Moment", "canvas_id": "fc57410a-9ac2-40d5-a14f-f94845cc34ce", "location": "Garage", "schedule": "between 2 PM - 5 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_arrived", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "madison_arrived": {"canvas_name": "Madison Arrives", "canvas_id": "7ab8806f-3582-4c37-a50f-93abbaf872e0", "location": "Upstairs Hallway", "schedule": "between 2 PM - 5 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "cant_stay_away_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, "cant_stay_away_complete": {"canvas_name": "Can't Stay Away", "canvas_id": "7f5880ef-b71d-47d3-9506-aa2caaefe382", "location": "Upstairs Hallway", "schedule": "between 2 PM - 5 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "morning_after_complete", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "morning_after_complete": {"canvas_name": "Morning After", "canvas_id": "94751735-6f29-4dd2-b5f8-871202ec0ed5", "location": "Your Old Room", "schedule": "between 7 AM - 9 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, "first_night_complete": {"canvas_name": "First Night Together", "canvas_id": "3c251c46-2604-493f-95ad-488ff4e13af0", "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "intimate": {"canvas_name": "First Night Together", "canvas_id": "3c251c46-2604-493f-95ad-488ff4e13af0", "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "what_are_we_doing_done": {"canvas_name": "What Are We Doing", "canvas_id": "be2226c6-ae16-4fe1-b960-e037361a6c5f", "location": "Kitchen", "schedule": "between 7 AM - 9 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, "first_kiss": {"canvas_name": "First Kiss", "canvas_id": "9c442310-64b4-4b5d-8d04-e1705e8aa45e", "location": "Living Room", "schedule": "between 7 PM - 10 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "real_talk_complete": {"canvas_name": "The Real Talk", "canvas_id": "721b6515-4264-4630-b9c4-8eafcf6e5120", "location": "Your Old Room", "schedule": "between 10 PM - 1 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}}, "almost_kiss_complete": {"canvas_name": "Almost Kiss", "canvas_id": "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5", "location": "Backyard & Pool", "schedule": "between 7 PM - 10 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "confession_complete", "operator": "is_true"}, {"type": "trait", "value": 55, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "confession_complete": {"canvas_name": "The Confession", "canvas_id": "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff", "location": "Backyard & Pool", "schedule": "between 10 PM - 1 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "the_couch_complete", "operator": "is_true"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 40, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}}, "the_couch_complete": {"canvas_name": "The Couch", "canvas_id": "586e0e77-efb7-4334-80eb-23411951bdb4", "location": "Living Room", "schedule": "between 7 PM - 10 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "madison_calls_complete": {"canvas_name": "Madison Calls", "canvas_id": "22cc3189-8f9f-4016-837c-3014248a4bff", "location": "Living Room", "schedule": "between 12 PM - 5 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}, {"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "sleepless_night_complete": {"canvas_name": "Sleepless Night", "canvas_id": "e2bfbeb9-ebc9-458e-96f5-1a854ad75be7", "location": "Kitchen", "schedule": "between 10 PM - 1 AM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "old_photos_complete", "operator": "is_true"}, {"type": "trait", "value": 25, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "old_photos_complete": {"canvas_name": "Finding Old Photos", "canvas_id": "b133cce8-dae7-4c11-a1db-d75552e256c8", "location": "Garage", "schedule": "between 2 PM - 5 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "welcome_dinner_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}}, "welcome_dinner_complete": {"canvas_name": "Welcome Home Dinner", "canvas_id": "9da03758-d6d0-4cea-ab7f-c86473348579", "location": "Kitchen", "schedule": "between 5 PM - 7 PM", "canvas_conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}}, "arrival_complete": {"canvas_name": "Coming Home", "canvas_id": "3ae0a423-d98e-4659-900c-f6a43bd6a3e5", "location": null, "schedule": null, "canvas_conditions": null}, "game_started": {"canvas_name": "Coming Home", "canvas_id": "3ae0a423-d98e-4659-900c-f6a43bd6a3e5", "location": null, "schedule": null, "canvas_conditions": null}}, "starting_canvas_id": "3ae0a423-d98e-4659-900c-f6a43bd6a3e5", "locationCanvases": {"6b717a40-88fc-45ef-bfd3-c58c0438052c": [{"id": "38d240e2-e18b-4cf4-b77c-a6b85a3a6765", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "a39d2179-f7e6-4ba6-b1e3-f146bb812b71", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "8041f658-eee5-434f-a24f-95533104b894", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "aee10b91-48f4-4f2c-b8b4-b4ff83d8616f", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "09b332a6-eab6-4d97-99a3-6561abc42d6c", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "79d7b9d6-29ee-4962-ae7a-91226ed22ae9", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": true, "maxPerDay": null}, {"id": "7ab8806f-3582-4c37-a50f-93abbaf872e0", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "cant_stay_away_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "7f5880ef-b71d-47d3-9506-aa2caaefe382", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "morning_after_complete", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}], "3eac7d4e-f70f-4744-bba2-01059c0b59c5": [{"id": "463b8f19-3ed7-44e2-a9be-e2b51ae89dee", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": true, "maxPerDay": null}, {"id": "5b66480a-4811-46e5-a515-04d3e9a53bdd", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": true, "maxPerDay": null}, {"id": "2545cef7-fb06-4ab4-8d78-cc2fb8b314d2", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": false, "maxPerDay": null}, {"id": "e4501f93-13d9-4faf-8701-ca5e05f2c148", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": true, "maxPerDay": 2}, {"id": "4840b621-e25f-411f-b937-28acadc2f012", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "stolen_moment_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "94751735-6f29-4dd2-b5f8-871202ec0ed5", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "3c251c46-2604-493f-95ad-488ff4e13af0", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "721b6515-4264-4630-b9c4-8eafcf6e5120", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}], "c05d22eb-3a00-4972-a9ed-717ff4b1be73": [{"id": "40bff3dc-70eb-413f-a93b-9ce360da0481", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": true, "maxPerDay": null}, {"id": "bde40787-6198-478f-acd7-c262f235c484", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": true, "maxPerDay": null}, {"id": "e10d2766-69a4-4519-9306-f4ccbc27981f", "hasSchedules": false, "scheduleParams": null, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": null}, {"id": "c0390255-cd42-46dd-86d7-147e542a473b", "hasSchedules": false, "scheduleParams": null, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 50, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}, "isRepeatable": true, "maxPerDay": null}, {"id": "6fd48df2-2dca-4ab7-a7be-b234e4a7143b", "hasSchedules": false, "scheduleParams": null, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 60, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}, "isRepeatable": true, "maxPerDay": null}, {"id": "0834d14d-55f4-4aa6-b60b-753588944c09", "hasSchedules": false, "scheduleParams": null, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": null}, {"id": "2258aef8-bc4d-4e9e-a766-bacfdd800739", "hasSchedules": false, "scheduleParams": null, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "morning_after_complete", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 80, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}, "isRepeatable": true, "maxPerDay": null}, {"id": "26e1a29a-54d0-4f4b-87de-864e54a0e01e", "hasSchedules": false, "scheduleParams": null, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "cant_stay_away_complete", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 90, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}, "isRepeatable": true, "maxPerDay": null}], "025944f1-16b0-4b03-a1ab-935d9ddc076f": [{"id": "ad75137d-989d-4249-b993-1e7b17fadeb5", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "3557832c-8856-4f2f-a4d2-585a1c75efaa", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "bce73abd-d2c3-4e33-be56-72c5e7c47fc8", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "3aeb65fd-0961-4fcd-97ea-08e20d628f59", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "71a09dc8-ff6d-49d1-8f7f-9503785208a3", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "409aa9e5-c940-4640-8408-91041d4e7811", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "2ab37e92-9d1b-4438-a17a-59b8b5a6cba3", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "b8f87c2e-e5f3-40eb-940e-7a8dda96b944", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "769fa786-16b6-4d36-b3af-2b61e2a22f19", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "a08fa545-9646-4033-b22a-2a6b94bec46c", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "71bafae7-a820-43df-ae90-d0cf20306c01", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "52b8fa8c-bdec-441f-a02b-38678ad6d3d1", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "64e060ee-617f-4eab-b2ff-105075f0e437", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "3a9eea3d-5353-4f8d-b721-8ad04ddafb3a", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "18dd23b7-00c0-4faf-8e6a-6a10910bbac7", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "d7cf66e5-8b92-4a53-b4d7-0dcb734cc401", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "23ea19a2-a13a-4cd0-9e3f-91adefe2de0e", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}, {"type": "trait", "value": 80, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 60, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "0f195b3f-bcfa-44c0-a100-37ad4e325285", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}, {"type": "trait", "value": 60, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "a87c60a5-8a49-4cc3-9a12-faae9080e2f2", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "09:00", "endTime": "12:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}, {"type": "trait", "value": 95, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 70, "subject": "player", "operator": "gte", "trait_key": "boldness"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "lt", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "9c442310-64b4-4b5d-8d04-e1705e8aa45e", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "586e0e77-efb7-4334-80eb-23411951bdb4", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "22cc3189-8f9f-4016-837c-3014248a4bff", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "12:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}, {"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}], "1cc5ebd9-1cdb-4202-a589-03322cb79f83": [{"id": "73cbe973-6aea-457e-99e9-ea46f429d150", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "4429251c-f1ed-4dcd-a04d-975f344d695e", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "7073455c-e506-42c3-9640-040428d6d7b8", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "21935a2f-f38a-48e6-9f7e-ae7c779d0174", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "b23c38a0-f8da-46f6-8907-4b3e9864cf01", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "059b39cb-a627-4c0e-98fc-4a30f3bff6f1", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "7d3d56ea-bb73-449b-b1d8-8bfd29007d58", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "72b91eee-7c46-48ab-ae97-06db9a2fd794", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "e9207826-c6d9-4a09-a5f3-e4130c5ad2bc", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "477d5c97-650d-49bf-9a00-0b93222611e2", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "02360f7c-2c25-41cd-a4ae-d9e938447c08", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "37348391-17a3-4e3d-9b44-0ca228158524", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "539a7f90-0877-4a6d-85b8-e11f4f8991e9", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "824f28ea-3a40-4dbc-8d26-4baf91102db0", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "8bdd9b31-acf8-405d-a14a-30b1212398a3", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "a300e4b5-1773-4d05-9617-c98ca9199611", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "12:00", "endTime": "14:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "5fc3e920-273f-45ac-ba92-9317ceeae930", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "12:00", "endTime": "14:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "b153b9e7-3d1b-47fc-80f8-c20786cdf0be", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "12:00", "endTime": "14:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "d2f3b351-39c2-4ae2-be8e-a45aab258739", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "12:00", "endTime": "14:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "e20039b6-7886-4214-aeb2-34e96f4aa6fa", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "12:00", "endTime": "14:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "33ddf963-458e-404e-abe9-95a64c3ce300", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "e89e834e-1adc-49d2-b6fa-0d456cf957d7", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "621821ba-98ae-4ae7-84b0-fbeee182593f", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "055ec2e8-6a21-41b5-b399-18efb7745eda", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "3ab52809-3b7c-4a0c-8dc0-cd2022f0e8dc", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "2b22e43e-794e-43ea-a800-6837d324dc0d", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "41bc2a64-cec7-47d0-9f45-b1fa206d237b", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "f8c84bf8-0eb5-40d0-9b34-efd914063f3d", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "ef8853bf-9a29-4b7a-8bbd-f9a1856656c2", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "dba6552a-a82f-4f32-a5af-0b378681db25", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "285a83a5-320e-4969-a558-e0fbb69d1827", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "night_before_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "be2226c6-ae16-4fe1-b960-e037361a6c5f", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "07:00", "endTime": "09:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "e2bfbeb9-ebc9-458e-96f5-1a854ad75be7", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "old_photos_complete", "operator": "is_true"}, {"type": "trait", "value": 25, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "9da03758-d6d0-4cea-ab7f-c86473348579", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "17:00", "endTime": "19:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}], "b062fb4f-2615-4e88-a350-c048096f2782": [{"id": "bb21f5b3-2da9-492e-868d-420e0410a1b3", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "ed02ae76-4628-4e21-81ca-68034f18ff4d", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "8b2415a0-6e95-4b6a-9b98-a03d2687f9f2", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "6d3be5b5-228d-49b4-b2de-0e660517e128", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "2989df0a-81ef-4b23-b710-bd989edd0907", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "c421f29f-4582-43e4-acba-3499ad09aefa", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "774fd167-ddd5-46f9-9f2e-88bc59f6315f", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "2ac679db-bf7e-48ca-9fd3-5f9a0cdc33ef", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "73621d16-03fe-437c-b2e9-a206a140b7bf", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "3a457bc9-99be-45f6-bfd9-fb6b7643ddf4", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": true, "maxPerDay": 1}, {"id": "5e176181-e161-43e7-8dda-fcacf805e90b", "hasSchedules": false, "scheduleParams": null, "conditions": null, "isRepeatable": true, "maxPerDay": null}, {"id": "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "19:00", "endTime": "22:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "confession_complete", "operator": "is_true"}, {"type": "trait", "value": 55, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "22:00", "endTime": "01:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "the_couch_complete", "operator": "is_true"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 40, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}], "4dc5f240-c5a8-40d1-8997-41309fc625de": [{"id": "fc57410a-9ac2-40d5-a14f-f94845cc34ce", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "madison_arrived", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}, {"id": "b133cce8-dae7-4c11-a1db-d75552e256c8", "hasSchedules": true, "scheduleParams": {"weekdays": [], "startTime": "14:00", "endTime": "17:00"}, "conditions": {"items": [{"type": "flag", "subject": "player", "flag_key": "welcome_dinner_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}, "isRepeatable": false, "maxPerDay": null}]}}>><<script>> // Initialize setup object and time management functions if (typeof setup === 'undefined') { window.setup = {}; } // NPC ID resolver: converts slugs to UUIDs for $npcs lookups // Conditions from TOML use NPC slugs (e.g., "elena") but $npcs is keyed by UUID setup.resolveNpcId = function(idOrSlug) { if (!idOrSlug) return null; var slugMap = State.variables.npc_slug_map || {}; var key = String(idOrSlug); // If it's a slug, resolve to UUID; otherwise return as-is (already UUID) return slugMap[key] || key; }; // Time period calculation function setup.getTimePeriod = function(hour) { if (hour >= 6 && hour < 12) return "Morning"; if (hour >= 12 && hour < 18) return "Afternoon"; if (hour >= 18 && hour < 22) return "Evening"; return "Night"; }; // Schedule evaluation function for trigger conditionals setup.isScheduleActive = function(weekdays, startTime, endTime) { const timeState = State.variables.game_state.time_state; const dayIndex = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"].indexOf(timeState.current_day); const currentHour = timeState.current_hour; const currentMinute = timeState.current_minute; const currentTotalMinutes = (currentHour * 60) + currentMinute; // Check if current day is in schedule weekdays (empty array = any day allowed) if (weekdays.length > 0 && !weekdays.includes(dayIndex)) { return false; } // Parse start time const startParts = startTime.split(':'); const startHour = parseInt(startParts[0]); const startMin = parseInt(startParts[1]); const startTotalMinutes = (startHour * 60) + startMin; if (endTime) { // Range trigger const endParts = endTime.split(':'); const endHour = parseInt(endParts[0]); const endMin = parseInt(endParts[1]); const endTotalMinutes = (endHour * 60) + endMin; // Handle overnight schedules (e.g., 22:00 to 08:00) if (endTotalMinutes < startTotalMinutes) { return currentTotalMinutes >= startTotalMinutes || currentTotalMinutes < endTotalMinutes; } return currentTotalMinutes >= startTotalMinutes && currentTotalMinutes < endTotalMinutes; } else { // Point trigger - active for 1 hour window return currentTotalMinutes >= startTotalMinutes && currentTotalMinutes < (startTotalMinutes + 60); } }; // ===== NPC Schedule Helper Functions ===== // Get the current location of an NPC based on game time setup.getNpcLocation = function(npcId) { var resolvedId = setup.resolveNpcId(npcId); var npcs = State.variables.npcs || {}; var npc = npcs[resolvedId]; if (!npc || !npc.schedule || npc.schedule.length === 0) return null; var timeState = State.variables.game_state.time_state; var dayIndex = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"].indexOf(timeState.current_day); var currentHour = timeState.current_hour; var currentMinute = timeState.current_minute; var currentTotalMinutes = (currentHour * 60) + currentMinute; for (var i = 0; i < npc.schedule.length; i++) { var sch = npc.schedule[i]; // Check weekdays (empty = all days) if (sch.weekdays && sch.weekdays.length > 0 && !sch.weekdays.includes(dayIndex)) continue; // Parse times var startParts = (sch.start_time || "00:00").split(':'); var startTotal = parseInt(startParts[0]) * 60 + parseInt(startParts[1]); var endTotal; if (sch.end_time) { var endParts = sch.end_time.split(':'); endTotal = parseInt(endParts[0]) * 60 + parseInt(endParts[1]); } else { endTotal = startTotal + 60; // Default 1 hour duration } // Handle overnight schedules (end < start) var isInRange; if (endTotal < startTotal) { isInRange = currentTotalMinutes >= startTotal || currentTotalMinutes < endTotal; } else { isInRange = currentTotalMinutes >= startTotal && currentTotalMinutes < endTotal; } if (isInRange) { return { location: sch.location, activity: sch.activity || "" }; } } return null; }; // Get schedule entries for a specific NPC on a specific day setup.getNpcDaySchedule = function(npcId, dayIndex) { var resolvedId = setup.resolveNpcId(npcId); var npcs = State.variables.npcs || {}; var npc = npcs[resolvedId]; if (!npc || !npc.schedule) return []; var result = []; for (var i = 0; i < npc.schedule.length; i++) { var sch = npc.schedule[i]; // Check if schedule applies to this day (empty weekdays = all days) if (!sch.weekdays || sch.weekdays.length === 0 || sch.weekdays.includes(dayIndex)) { result.push({ location: sch.location, start_time: sch.start_time || "00:00", end_time: sch.end_time || null, activity: sch.activity || "" }); } } return result; }; // Get all NPCs with schedules setup.getNpcsWithSchedules = function() { var npcs = State.variables.npcs || {}; var result = []; for (var npcId in npcs) { if (npcs[npcId].schedule && npcs[npcId].schedule.length > 0) { result.push({ id: npcId, name: npcs[npcId].name }); } } return result; }; // Get today's schedule sorted by start time setup.getTodayScheduleSorted = function(npcId) { var timeState = State.variables.game_state.time_state; var dayIndex = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] .indexOf(timeState.current_day); var schedules = setup.getNpcDaySchedule(npcId, dayIndex); // Sort by start time schedules.sort(function(a, b) { var aParts = a.start_time.split(':'); var bParts = b.start_time.split(':'); var aMinutes = parseInt(aParts[0]) * 60 + parseInt(aParts[1]); var bMinutes = parseInt(bParts[0]) * 60 + parseInt(bParts[1]); return aMinutes - bMinutes; }); return schedules; }; // Check if current game time is within a time slot setup.isCurrentTimeSlot = function(startTime, endTime) { var timeState = State.variables.game_state.time_state; var currentTotal = (timeState.current_hour * 60) + timeState.current_minute; var startParts = startTime.split(':'); var startTotal = parseInt(startParts[0]) * 60 + parseInt(startParts[1]); var endTotal; if (endTime) { var endParts = endTime.split(':'); endTotal = parseInt(endParts[0]) * 60 + parseInt(endParts[1]); } else { endTotal = startTotal + 60; } // Handle overnight (e.g., 22:00-06:00) if (endTotal < startTotal) { return currentTotal >= startTotal || currentTotal < endTotal; } return currentTotal >= startTotal && currentTotal < endTotal; }; // Format hour:minute to readable time (e.g., "10:30 AM") setup.formatTime = function(hour, minute) { var period = hour >= 12 ? 'PM' : 'AM'; var displayHour = hour % 12 || 12; var displayMinute = minute < 10 ? '0' + minute : minute; return displayHour + ':' + displayMinute + ' ' + period; }; // ===== Trigger Conditions Evaluator ===== // Evaluates v1.0 trigger conditions against current game state (flags/traits) setup.triggerConditionsSatisfied = function(conditions) { try { // Treat missing/empty conditions as satisfied if (!conditions || typeof conditions !== 'object') return true; if (!conditions.version || conditions.version !== '1.0') return true; var items = Array.isArray(conditions.items) ? conditions.items : []; if (items.length === 0) return true; var logic = (conditions.logic === 'OR') ? 'OR' : 'AND'; var sv = State.variables || {}; var player = sv.player || {}; var npcs = sv.npcs || {}; function hasKey(obj, key) { if (!obj || typeof obj !== 'object') return false; return Object.prototype.hasOwnProperty.call(obj, String(key)); } function coerceNumber(v) { var n = Number(v); return isNaN(n) ? null : n; } function compare(op, left, right) { if (op === 'eq') return left === right; if (op === 'ne') return left !== right; if (op === 'gt' || op === 'gte' || op === 'lt' || op === 'lte') { var lnum = coerceNumber(left); var rnum = coerceNumber(right); if (lnum === null || rnum === null) return false; if (op === 'gt') return lnum > rnum; if (op === 'gte') return lnum >= rnum; if (op === 'lt') return lnum < rnum; if (op === 'lte') return lnum <= rnum; } if (op === 'in') { if (!Array.isArray(right)) return false; return right.includes(left); } if (op === 'not_in') { if (!Array.isArray(right)) return false; return !right.includes(left); } if (op === 'contains') { if (Array.isArray(left)) return left.includes(right); if (typeof left === 'string') return String(left).includes(String(right)); return false; } if (op === 'not_contains') { if (Array.isArray(left)) return !left.includes(right); if (typeof left === 'string') return !String(left).includes(String(right)); return false; } if (op === 'exists') return (left !== undefined && left !== null); if (op === 'not_exists') return (left === undefined || left === null); return false; } var results = []; for (var i = 0; i < items.length; i++) { var it = items[i]; if (!it || typeof it !== 'object') { results.push(false); continue; } var type = it.type; var subject = it.subject; var satisfied = false; if (type === 'flag') { var key = it.flag_key; var op = it.operator; if (!key || (subject !== 'player' && subject !== 'npc')) { results.push(false); continue; } if (subject === 'player') { // Use global $flags for player flags (sv.flags = State.variables.flags) var flags = (sv.flags || {}); if (op === 'exists') { satisfied = hasKey(flags, key); } else if (op === 'is_true') { satisfied = (flags[String(key)] === true); } else if (op === 'is_false') { // Treat missing or strictly false as false var v = flags[String(key)]; satisfied = (v === false || v === undefined); } else { satisfied = false; } } else if (subject === 'npc') { var rawNpcId = it.npc_id || it.character_id || ''; var npcId = setup.resolveNpcId(rawNpcId); var npc = npcId ? (npcs[npcId] || null) : null; var flagsNpc = npc && npc.flags ? npc.flags : {}; if (op === 'exists') { satisfied = hasKey(flagsNpc, key); } else if (op === 'is_true') { satisfied = (flagsNpc[String(key)] === true); } else if (op === 'is_false') { var v2 = flagsNpc[String(key)]; satisfied = (v2 === false || v2 === undefined); } else { satisfied = false; } } results.push(satisfied); continue; } if (type === 'trait') { var tkey = it.trait_key; var top = it.operator; if (!tkey || (subject !== 'player' && subject !== 'npc')) { results.push(false); continue; } var leftVal = null; if (subject === 'player') { leftVal = (player.core_traits || {})[String(tkey)]; } else if (subject === 'npc') { var rawNpc2Id = it.npc_id || it.character_id || ''; var npc2Id = setup.resolveNpcId(rawNpc2Id); var npc2 = npc2Id ? (npcs[npc2Id] || null) : null; leftVal = npc2 && npc2.core_traits ? npc2.core_traits[String(tkey)] : undefined; } var rightVal = it.value; satisfied = compare(top, leftVal, rightVal); results.push(satisfied); continue; } // Unknown type results.push(false); } if (results.length === 0) return false; if (logic === 'AND') return results.every(function(x) { return !!x; }); return results.some(function(x) { return !!x; }); } catch (e) { // Fail open to avoid breaking gameplay return true; } }; // ===== Trigger Repeatability & Limits ===== // Utility to build a unique day key combining week and day setup.getCurrentDayKey = function() { try { var ts = State.variables.game_state.time_state; return String(ts.current_week) + ':' + String(ts.current_day); } catch (e) { return '0:Monday'; } }; // Check if a canvas can trigger based on repeatability and per-day limit setup.canTriggerCanvas = function(canvasId, isRepeatable, maxPerDay) { try { var sv = State.variables; sv.game_state = sv.game_state || {}; var hist = sv.game_state.trigger_history = sv.game_state.trigger_history || {}; var rec = hist[String(canvasId)] || null; if (!rec) { // Never triggered before; allowed return true; } // Not repeatable and already triggered once if (!isRepeatable && (rec.total || 0) >= 1) { return false; } // Per-day limit check if (maxPerDay !== null && maxPerDay !== undefined) { var currentDayKey = setup.getCurrentDayKey(); var dayKey = rec.dayKey || ''; var dayCount = rec.dayCount || 0; if (dayKey !== currentDayKey) { // New day; reset dayCount logic allows trigger return true; } if (dayCount >= Number(maxPerDay)) { return false; } } return true; } catch (e) { // Fail open return true; } }; // Mark a canvas as triggered: increments total and per-day counters setup.markCanvasTriggered = function(canvasId) { try { var sv = State.variables; sv.game_state = sv.game_state || {}; var hist = sv.game_state.trigger_history = sv.game_state.trigger_history || {}; var key = String(canvasId); var rec = hist[key] || { total: 0, dayKey: '', dayCount: 0 }; var currentDayKey = setup.getCurrentDayKey(); if (rec.dayKey !== currentDayKey) { rec.dayKey = currentDayKey; rec.dayCount = 0; } rec.total = (rec.total || 0) + 1; rec.dayCount = (rec.dayCount || 0) + 1; hist[key] = rec; } catch (e) { // ignore } }; // Check if a canvas has never been completed (for highlighting new content) setup.isCanvasNew = function(canvasId) { try { var sv = State.variables; sv.game_state = sv.game_state || {}; var hist = sv.game_state.trigger_history || {}; var record = hist[String(canvasId)]; return !record || (record.total || 0) === 0; } catch (e) { return true; // Fail open - show as new if error } }; // Check if a location has any unvisited AND available canvases (for navigation indicators) setup.locationHasNewCanvases = function(locationId) { try { var sv = State.variables; var helpData = sv.help_data || {}; var locationCanvases = helpData.locationCanvases || {}; var canvasList = locationCanvases[String(locationId)] || []; for (var i = 0; i < canvasList.length; i++) { var c = canvasList[i]; // Check if canvas is NEW (never visited) if (!setup.isCanvasNew(c.id)) continue; // Check if schedule is active (if canvas has schedules) if (c.hasSchedules && c.scheduleParams) { var sp = c.scheduleParams; if (!setup.isScheduleActive(sp.weekdays, sp.startTime, sp.endTime)) { continue; } } // Check if conditions are satisfied (if canvas has conditions) if (c.conditions && !setup.triggerConditionsSatisfied(c.conditions)) { continue; } // Check if canvas can still be triggered (repeatability/per-day limits) if (!setup.canTriggerCanvas(c.id, c.isRepeatable, c.maxPerDay)) { continue; } // Found a canvas that is NEW and AVAILABLE return true; } return false; } catch (e) { return false; // Fail closed - don't show indicator if error } }; // Time advancement functions window.advanceTime = function(minutes) { // Add minutes to current time State.variables.game_state.time_state.current_minute += minutes; // Handle minute/hour rollover while (State.variables.game_state.time_state.current_minute >= 60) { State.variables.game_state.time_state.current_minute -= 60; State.variables.game_state.time_state.current_hour += 1; } // Handle day rollover while (State.variables.game_state.time_state.current_hour >= 24) { State.variables.game_state.time_state.current_hour -= 24; advanceDay(); } // Update display updateTimeDisplay(); }; window.advanceDay = function() { const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; const currentIndex = days.indexOf(State.variables.game_state.time_state.current_day); const nextIndex = (currentIndex + 1) % 7; State.variables.game_state.time_state.current_day = days[nextIndex]; // New week starts on Monday if (nextIndex === 0) { State.variables.game_state.time_state.current_week += 1; } }; window.updateTimeDisplay = function() { // Format time for 12-hour display const hour = State.variables.game_state.time_state.current_hour; const minute = State.variables.game_state.time_state.current_minute; const displayHour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour; const ampm = hour < 12 ? 'AM' : 'PM'; const formattedTime = displayHour + ':' + (minute < 10 ? '0' : '') + minute + ' ' + ampm; // Update time display const timeElement = document.getElementById('time-display'); if (timeElement) { timeElement.textContent = formattedTime; } // Update current day const currentDayElement = document.getElementById('current-day'); if (currentDayElement) { currentDayElement.textContent = State.variables.game_state.time_state.current_day; } }; // ===== Trait Helpers ===== window._traitClamp = function(v, min, max) { v = Number(v); if (isNaN(v)) { v = 0; } if (min !== undefined && v < min) v = min; if (max !== undefined && v > max) v = max; return v; }; window.applyTraitEffect = function(targetType, npcId, trait, op, val, clampFlag, cap) { try { var sv = State.variables; if (!sv) return; // Resolve NPC slug to UUID if (targetType === 'npc' && npcId) { npcId = setup.resolveNpcId(npcId); } // Resolve target object var traitsObj = null; if (targetType === 'player') { sv.player = sv.player || {}; sv.player.core_traits = sv.player.core_traits || {}; traitsObj = sv.player.core_traits; } else if (targetType === 'npc') { sv.npcs = sv.npcs || {}; var npc = sv.npcs[String(npcId)] || null; if (!npc) return; // Unknown NPC npc.core_traits = npc.core_traits || {}; traitsObj = npc.core_traits; } else { return; // Unknown target type } // Normalize inputs var key = String(trait); var current = Number(traitsObj[key]); if (isNaN(current)) current = 0; var value = Number(val); if (isNaN(value)) value = 0; // Apply operation var next = current; if (op === 'add') { next = current + value; } else if (op === 'set') { next = value; } else { // Unknown op; do nothing return; } // Clamp 0-100 if requested (default true) if (clampFlag === undefined || clampFlag === null) { clampFlag = true; } if (clampFlag) { next = window._traitClamp(next, 0, 100); } // Apply cap if provided if (cap !== undefined && cap !== null) { var capNum = Number(cap); if (!isNaN(capNum)) { if (next > capNum) next = capNum; } } traitsObj[key] = next; } catch (e) { // Ignore to avoid breaking navigation } }; // ===== Flag Helpers ===== window.applyFlagEffect = function(targetType, npcId, flag) { try { var sv = State.variables; if (!sv) return; // Resolve NPC slug to UUID if (targetType === 'npc' && npcId) { npcId = setup.resolveNpcId(npcId); } var key = String(flag); if (targetType === 'player') { // Store in $flags (sv.flags) to match triggerConditionsSatisfied checks sv.flags = sv.flags || {}; sv.flags[key] = true; return; } if (targetType === 'npc') { sv.npcs = sv.npcs || {}; var npc = sv.npcs[String(npcId)]; if (!npc) return; npc.flags = npc.flags || {}; npc.flags[key] = true; return; } } catch (e) { // ignore } }; // ========== EFFECT NOTIFICATION SYSTEM ========== // Pending effects to show setup.pendingEffects = []; // Get current trait value helper setup.getTraitValue = function(targetType, npcId, trait) { var sv = State.variables; // Resolve NPC slug to UUID if (targetType === 'npc' && npcId) { npcId = setup.resolveNpcId(npcId); } if (targetType === 'player') { return (sv.player && sv.player.core_traits) ? (sv.player.core_traits[trait] || 0) : 0; } else if (targetType === 'npc' && npcId) { var npc = sv.npcs ? sv.npcs[String(npcId)] : null; return (npc && npc.core_traits) ? (npc.core_traits[trait] || 0) : 0; } return 0; }; // Apply trait and queue notification setup.applyAndNotifyTrait = function(targetType, npcId, trait, op, val, clampFlag, cap) { var oldVal = setup.getTraitValue(targetType, npcId, trait); applyTraitEffect(targetType, npcId, trait, op, val, clampFlag, cap); var newVal = setup.getTraitValue(targetType, npcId, trait); var delta = newVal - oldVal; if (delta !== 0) { var npcName = ''; if (targetType === 'npc' && npcId) { npcId = setup.resolveNpcId(npcId); var npc = State.variables.npcs ? State.variables.npcs[String(npcId)] : null; npcName = npc ? (npc.name || npcId) : npcId; } setup.pendingEffects.push({ type: 'trait', name: npcName, trait: trait, delta: delta }); } }; // Apply flag and queue notification setup.applyAndNotifyFlag = function(targetType, npcId, flag) { // Resolve NPC slug to UUID if (targetType === 'npc' && npcId) { npcId = setup.resolveNpcId(npcId); } applyFlagEffect(targetType, npcId, flag); var npcName = ''; if (targetType === 'npc' && npcId) { var npc = State.variables.npcs ? State.variables.npcs[String(npcId)] : null; npcName = npc ? (npc.name || npcId) : npcId; } setup.pendingEffects.push({ type: 'flag', name: npcName, flag: flag }); }; // Show notification and clear setup.showEffectNotification = function() { var effects = setup.pendingEffects; if (!effects || effects.length === 0) return; var lines = []; for (var i = 0; i < effects.length; i++) { var eff = effects[i]; if (eff.type === 'trait') { var sign = eff.delta > 0 ? '+' : ''; var traitDisplay = eff.trait.charAt(0).toUpperCase() + eff.trait.slice(1); var prefix = eff.name ? (eff.name + "'s ") : ''; lines.push(sign + eff.delta + ' ' + prefix + traitDisplay); } else if (eff.type === 'flag') { var flagDisplay = eff.flag.replace(/_/g, ' '); flagDisplay = flagDisplay.charAt(0).toUpperCase() + flagDisplay.slice(1); lines.push('🔓 ' + flagDisplay); } } if (lines.length === 0) { setup.pendingEffects = []; return; } var html = '<div class="effect-toast">' + lines.join(' • ') + '</div>'; jQuery('body').append(html); setTimeout(function() { jQuery('.effect-toast').remove(); }, 2000); setup.pendingEffects = []; }; // ========== STORY JOURNAL SYSTEM ========== // Detect current story position based on story arc and game state setup.detectStoryPosition = function() { var arc = State.variables.story_arc || {}; var result = { current_chapter: null, completed_nodes: [], available_nodes: [], locked_nodes: [], active_groups: [], is_stuck: false, progress_percent: 0 }; if (!arc.nodes || arc.nodes.length === 0) { // Use auto-inference if no story arc defined return setup.autoInferStoryPosition(); } var completedIds = []; var availableIds = []; var lockedIds = []; // Check each node's completion status arc.nodes.forEach(function(node) { var isCompleted = false; // Check linked_canvas completion if (node.linked_canvas) { var canvasId = node.linked_canvas; isCompleted = State.variables.game_state.completed_canvases && State.variables.game_state.completed_canvases.indexOf(canvasId) !== -1; } // Check linked_flag (flags is an object, not an array) if (node.linked_flag && !isCompleted) { isCompleted = State.variables.flags && State.variables.flags[node.linked_flag]; } if (isCompleted) { completedIds.push(node.id); result.completed_nodes.push({ id: node.id, name: node.name, chapter: node.chapter, journal_entry: node.journal_entry, is_milestone: node.is_milestone || false }); } }); // Determine available vs locked nodes arc.nodes.forEach(function(node) { if (completedIds.indexOf(node.id) !== -1) return; // Already completed var canUnlock = true; // Check requires_nodes if (node.requires_nodes && node.requires_nodes.length > 0) { for (var i = 0; i < node.requires_nodes.length; i++) { if (completedIds.indexOf(node.requires_nodes[i]) === -1) { canUnlock = false; break; } } } // Check requires_group if (canUnlock && node.requires_group && arc.groups) { var group = arc.groups.find(function(g) { return g.id === node.requires_group; }); if (group) { var groupNodes = arc.nodes.filter(function(n) { return n.group === group.id; }); var completedCount = groupNodes.filter(function(n) { return completedIds.indexOf(n.id) !== -1; }).length; if (completedCount < group.required_count) { canUnlock = false; } } } if (canUnlock) { availableIds.push(node.id); result.available_nodes.push({ id: node.id, name: node.name, chapter: node.chapter, journal_entry: node.journal_entry, group: node.group || null }); } else { lockedIds.push(node.id); result.locked_nodes.push({ id: node.id, name: node.name, chapter: node.chapter, requires_group: node.requires_group || null, requires_nodes: node.requires_nodes || [] }); } }); // Build active groups status if (arc.groups) { arc.groups.forEach(function(group) { var groupNodes = arc.nodes.filter(function(n) { return n.group === group.id; }); var completedCount = groupNodes.filter(function(n) { return completedIds.indexOf(n.id) !== -1; }).length; result.active_groups.push({ id: group.id, name: group.name, description: group.description || "", completed: completedCount, required: group.required_count, total: groupNodes.length, isComplete: completedCount >= group.required_count }); }); } // Determine current chapter based on most recent milestone or available nodes if (arc.chapters && arc.chapters.length > 0) { var currentChapterId = null; // Find the chapter of the most recent milestone var milestones = result.completed_nodes.filter(function(n) { return n.is_milestone; }); if (milestones.length > 0) { currentChapterId = milestones[milestones.length - 1].chapter; } // Or use chapter of first available node if (!currentChapterId && result.available_nodes.length > 0) { currentChapterId = result.available_nodes[0].chapter; } // Or use first chapter if (!currentChapterId) { currentChapterId = arc.chapters[0].id; } result.current_chapter = arc.chapters.find(function(c) { return c.id === currentChapterId; }); } // Calculate progress var totalNodes = arc.nodes.length; if (totalNodes > 0) { result.progress_percent = Math.round((completedIds.length / totalNodes) * 100); } // Check if stuck (no available nodes and not all completed) result.is_stuck = result.available_nodes.length === 0 && result.completed_nodes.length < totalNodes; return result; }; // Get completed activities as "memories" for the journal setup.getCompletedActivities = function() { var position = setup.detectStoryPosition(); return position.completed_nodes.map(function(node) { return { name: node.name, journal_entry: node.journal_entry || "A moment to remember...", is_milestone: node.is_milestone }; }); }; // Interpret NPC state as emotional description instead of numbers setup.interpretNpcState = function(npcId) { var arc = State.variables.story_arc || {}; var mappings = arc.emotion_mappings || {}; var result = { npc_name: "", primary_emotion: "neutral", description: "Your relationship is developing...", relationship_summary: "", trait_interpretations: [] }; // Get NPC data - $npcs is an object keyed by UUID, not an array var npc = null; var npcs = State.variables.npcs || {}; // Try direct lookup first (npcId might already be a UUID) if (npcs[npcId]) { npc = npcs[npcId]; } else { // Try resolving as slug var resolvedId = setup.resolveNpcId(npcId); if (resolvedId && npcs[resolvedId]) { npc = npcs[resolvedId]; } } // Fallback to npc_states if available if (!npc && State.variables.npc_states) { npc = State.variables.npc_states[npcId]; } if (!npc) return result; result.npc_name = npc.name || npcId; var traits = npc.core_traits || {}; // Process each mapped trait var primaryEmotion = null; var highestPriority = -1; var traitOrder = ["affection", "trust", "arousal", "appreciation"]; traitOrder.forEach(function(traitName, priority) { var traitValue = traits[traitName]; if (typeof traitValue !== "number") return; var mapping = mappings[traitName]; if (!mapping || !mapping.ranges) return; // Find matching range var matchedRange = null; for (var i = 0; i < mapping.ranges.length; i++) { var range = mapping.ranges[i]; if (traitValue >= range.min && traitValue <= range.max) { matchedRange = range; break; } } if (matchedRange) { result.trait_interpretations.push({ trait: traitName, value: traitValue, label: matchedRange.label, description: matchedRange.description }); // Track primary emotion (highest value trait) if (traitValue > highestPriority) { highestPriority = traitValue; primaryEmotion = matchedRange.label; result.description = matchedRange.description; } } }); if (primaryEmotion) { result.primary_emotion = primaryEmotion; } // Generate relationship summary based on trait interpretations if (result.trait_interpretations.length > 0) { var summaryParts = result.trait_interpretations.slice(0, 2).map(function(t) { return t.description; }); result.relationship_summary = summaryParts.join(" "); } return result; }; // Generate subtle narrative hint (not mechanical instructions) setup.generateNarrativeHint = function() { var arc = State.variables.story_arc || {}; var hints = arc.hints || {}; var position = setup.detectStoryPosition(); var result = { hint_type: "none", text: "" }; // Only show hints when stuck or making slow progress if (!position.is_stuck && position.available_nodes.length > 0) { return result; } // Check active groups for progress hints var incompleteGroup = position.active_groups.find(function(g) { return !g.isComplete && g.completed < g.required; }); if (incompleteGroup) { result.hint_type = "observation"; var remaining = incompleteGroup.required - incompleteGroup.completed; if (hints.group_incomplete) { result.text = hints.group_incomplete .replace("{group_name}", incompleteGroup.name) .replace("{remaining}", remaining); } else { result.text = "There might be more to explore..."; } return result; } // Check locked nodes for what might be possible if (position.locked_nodes.length > 0) { result.hint_type = "suggestion"; if (hints.progress_needed) { result.text = hints.progress_needed; } else { result.text = "Perhaps spending more time together would reveal new possibilities..."; } return result; } // All done if (position.progress_percent >= 100) { result.hint_type = "completion"; result.text = hints.story_complete || "Your story together has reached a beautiful conclusion."; } return result; }; // ============== QUEST PAGE HELPER FUNCTIONS ============== // Get the next activity for an NPC (first incomplete in node order) setup.getNextActivity = function(npcId) { var helpData = State.variables.help_data || {}; var npcData = helpData.npcs ? helpData.npcs[npcId] : null; if (!npcData) return null; var activities = npcData.activities || []; var flags = State.variables.flags || {}; var hist = (State.variables.game_state && State.variables.game_state.trigger_history) || {}; // Activities are in node order from story_arc for (var i = 0; i < activities.length; i++) { var activity = activities[i]; // Skip non-story-arc activities (repeatable canvases without node_id) if (!activity.node_id) continue; // Skip completed activities (check linked_flag OR canvas visited in trigger_history) var isCompleted = (activity.linked_flag && flags[activity.linked_flag]) || (activity.canvas_id && hist[activity.canvas_id] && hist[activity.canvas_id].total > 0); if (isCompleted) continue; // Skip activities without a location (intro/automatic activities) if (!activity.location) continue; // Check if canvas trigger conditions are met var canvasConditions = activity.canvas_conditions; if (canvasConditions && canvasConditions.items) { var items = canvasConditions.items; var traitItems = []; var flagItems = []; // Separate trait and flag conditions for (var k = 0; k < items.length; k++) { if (items[k].type === 'trait') traitItems.push(items[k]); else if (items[k].type === 'flag') flagItems.push(items[k]); } // Check trait conditions FIRST (priority) var unmetTraits = []; for (var t = 0; t < traitItems.length; t++) { if (!setup.checkSingleCondition(traitItems[t])) { unmetTraits.push(traitItems[t]); } } if (unmetTraits.length > 0) { // Trait not met - show trait requirement return { activity: activity, isLocked: false, conditionsNotMet: true, traitConditionsNotMet: true, canvasConditions: { items: unmetTraits, logic: canvasConditions.logic, version: '1.0' } }; } // Traits met - check flags var unmetFlags = []; for (var f = 0; f < flagItems.length; f++) { if (!setup.checkSingleCondition(flagItems[f])) { unmetFlags.push(flagItems[f]); } } if (unmetFlags.length > 0) { // Flags not met - show actionable hint var flagHint = setup.getBestFlagHint(unmetFlags); return { activity: activity, isLocked: false, conditionsNotMet: true, flagConditionsNotMet: true, flagHint: flagHint }; } } // Found next visitable activity - check if locked by traits var traitReqs = activity.trait_requirements || []; var missingTraits = []; for (var j = 0; j < traitReqs.length; j++) { if (!setup.checkTraitRequirement(traitReqs[j])) { missingTraits.push(traitReqs[j]); } } return { activity: activity, isLocked: missingTraits.length > 0, missingTraits: missingTraits, conditionsNotMet: false }; } return null; // All completed }; // Check if a trait requirement is met setup.checkTraitRequirement = function(req) { var player = State.variables.player || {}; var traits = player.traits || {}; var currentValue = traits[req.trait] || 0; switch (req.operator) { case ">": return currentValue > req.value; case ">=": return currentValue >= req.value; case "<": return currentValue < req.value; case "<=": return currentValue <= req.value; case "==": return currentValue === req.value; default: return currentValue >= req.value; } }; // Check a single condition item (trait or flag) setup.checkSingleCondition = function(item) { var sv = State.variables || {}; if (item.type === 'flag') { var flags = sv.flags || {}; if (item.subject === 'player') { if (item.operator === 'is_true') return flags[item.flag_key] === true; if (item.operator === 'is_false') return !flags[item.flag_key]; } return false; } if (item.type === 'trait') { var leftVal = null; if (item.subject === 'player') { leftVal = ((sv.player || {}).core_traits || {})[item.trait_key]; } else if (item.subject === 'npc') { var npcId = setup.resolveNpcId(item.npc_id || ''); var npc = npcId ? ((sv.npcs || {})[npcId] || null) : null; leftVal = npc && npc.core_traits ? npc.core_traits[item.trait_key] : undefined; } var rightVal = item.value; var op = item.operator; if (op === 'gte') return Number(leftVal) >= Number(rightVal); if (op === 'gt') return Number(leftVal) > Number(rightVal); if (op === 'lte') return Number(leftVal) <= Number(rightVal); if (op === 'lt') return Number(leftVal) < Number(rightVal); if (op === 'eq') return leftVal === rightVal; return false; } return false; }; // Find actionable hint for unmet flag conditions (with recursive chain resolution) setup.getBestFlagHint = function(unmetFlags) { var helpData = State.variables.help_data || {}; var flagUnlockMap = helpData.flag_unlock_map || {}; var startingCanvasId = helpData.starting_canvas_id; // First pass: find directly visitable unlock canvas for (var i = 0; i < unmetFlags.length; i++) { var flagKey = unmetFlags[i].flag_key; var unlockInfo = flagUnlockMap[flagKey]; if (unlockInfo) { // Skip flags set by starting canvas (it plays automatically via "Start Game") if (startingCanvasId && unlockInfo.canvas_id === startingCanvasId) { continue; } var canvasConditions = unlockInfo.canvas_conditions; var isVisitable = !canvasConditions || setup.triggerConditionsSatisfied(canvasConditions); if (isVisitable) { return { location: unlockInfo.location, schedule: unlockInfo.schedule, canvas_name: unlockInfo.canvas_name }; } } } // Second pass: recursive chain resolution // If unlock canvas has flag conditions, find what unlocks THOSE flags var visited = {}; for (var i = 0; i < unmetFlags.length; i++) { var flagKey = unmetFlags[i].flag_key; var chainHint = setup.resolveUnlockChain(flagKey, flagUnlockMap, visited, 0); if (chainHint) { return chainHint; } } // Final fallback: generic message (no specific hint available) return null; }; // Recursively resolve the unlock chain to find a visitable canvas setup.resolveUnlockChain = function(flagKey, flagUnlockMap, visited, depth) { // Prevent infinite loops and excessive depth if (depth > 10 || visited[flagKey]) return null; visited[flagKey] = true; var unlockInfo = flagUnlockMap[flagKey]; if (!unlockInfo) return null; var canvasConditions = unlockInfo.canvas_conditions; // Check if this canvas is visitable if (!canvasConditions || setup.triggerConditionsSatisfied(canvasConditions)) { return { location: unlockInfo.location, schedule: unlockInfo.schedule, canvas_name: unlockInfo.canvas_name }; } // Canvas has conditions - check what's blocking it var items = canvasConditions.items || []; var helpData = State.variables.help_data || {}; var startingCanvasId = helpData.starting_canvas_id; var hasUnresolvableCondition = false; for (var i = 0; i < items.length; i++) { var item = items[i]; // If it's a flag condition that's not met if (item.type === 'flag' && !setup.checkSingleCondition(item)) { // Check if this flag is set by starting canvas (will be auto-met) var nestedUnlockInfo = flagUnlockMap[item.flag_key]; if (startingCanvasId && nestedUnlockInfo && nestedUnlockInfo.canvas_id === startingCanvasId) { continue; // Auto-met by starting canvas, skip this condition } // Recurse to find hint for this blocking flag var nestedHint = setup.resolveUnlockChain(item.flag_key, flagUnlockMap, visited, depth + 1); if (nestedHint) { return nestedHint; } hasUnresolvableCondition = true; } } // If all blocking conditions were auto-met (skipped), this canvas IS visitable if (!hasUnresolvableCondition) { return { location: unlockInfo.location, schedule: unlockInfo.schedule, canvas_name: unlockInfo.canvas_name }; } return null; }; // Format flag hint as "Visit X between Y" setup.formatFlagHint = function(hint) { if (!hint) return "Complete a prerequisite activity"; if (hint.location && hint.schedule) { return "Visit " + hint.location + " " + hint.schedule; } else if (hint.location) { return "Visit " + hint.location; } return "Complete: " + (hint.canvas_name || "a prerequisite activity"); }; // Format trait requirements as "Love > 30 and Trust > 20 required" setup.formatTraitRequirements = function(missingTraits) { if (!missingTraits || missingTraits.length === 0) return ""; var parts = missingTraits.map(function(req) { var traitName = req.trait.charAt(0).toUpperCase() + req.trait.slice(1); return traitName + " " + (req.operator || ">") + " " + req.value; }); return parts.join(" and ") + " required"; }; // Format canvas trigger conditions as clickable links "Required: Elena Affection ≥ 50" setup.formatCanvasConditions = function(conditions) { if (!conditions || !conditions.items) return "Conditions not met"; var parts = []; var items = conditions.items; for (var i = 0; i < items.length; i++) { var item = items[i]; if (item.type === "trait") { // Format as clickable link: "Elena Affection ≥ 50" or "Your Boldness ≥ 40" var npcId = item.npc_id || ""; var isPlayerTrait = item.subject === "player" || !npcId; var trait = item.trait_key; var value = item.value; var op = item.operator === "gte" ? "≥" : item.operator === "gt" ? ">" : item.operator === "lte" ? "≤" : item.operator === "lt" ? "<" : item.operator === "eq" ? "=" : "≥"; // Capitalize for display - use "Your" for player traits var displayNpc = isPlayerTrait ? "Your" : (npcId.charAt(0).toUpperCase() + npcId.slice(1)); var displayTrait = trait.charAt(0).toUpperCase() + trait.slice(1); // Wrap in clickable span with data attributes var link = '<span class="trait-requirement-link" ' + 'data-npc="' + npcId + '" ' + 'data-trait="' + trait + '" ' + 'data-value="' + value + '">' + displayNpc + ' ' + displayTrait + ' ' + op + ' ' + value + '</span>'; parts.push(link); } // Skip flag conditions - they're internal game mechanics, not player-actionable } if (parts.length === 0) return "Conditions not met"; var logic = conditions.logic === "OR" ? " or " : " and "; return "Required: " + parts.join(logic); }; // Format activity hint as "Visit X between Y" setup.formatActivityHint = function(activity) { if (activity.location && activity.schedule) { return "Visit " + activity.location + " " + activity.schedule; } else if (activity.location) { return "Visit " + activity.location; } return activity.name; }; // Show modal with activities that increase a specific trait for an NPC or player setup.showTraitActivitiesModal = function(npcId, traitKey, requiredValue) { var helpData = State.variables.help_data || {}; var npcs = State.variables.npcs || {}; // Detect if this is a player trait (empty/undefined npcId) var isPlayerTrait = !npcId || npcId === ""; var displayName, currentValue, activities; if (isPlayerTrait) { // Player trait - use player data and trait_activities index displayName = "Your"; var playerData = State.variables.player || {}; currentValue = (playerData.core_traits || {})[traitKey] || 0; // Get activities from trait_activities index that boost this trait for player var allTraitActivities = helpData.trait_activities ? helpData.trait_activities[traitKey] : []; activities = allTraitActivities.filter(function(act) { // Check if any effect targets player (no npc_id) with this trait var effects = act.trait_effects || []; for (var e = 0; e < effects.length; e++) { if (effects[e].trait === traitKey && !effects[e].npc_id && effects[e].value > 0) { return true; } } return false; }); } else { // NPC trait - use NPC data and NPC activities var resolvedId = setup.resolveNpcId(npcId); var npcData = npcs[resolvedId] || {}; displayName = npcData.name || npcId.charAt(0).toUpperCase() + npcId.slice(1); currentValue = (npcData.core_traits || {})[traitKey] || 0; var npcHelpData = helpData.npcs ? helpData.npcs[resolvedId] : null; activities = npcHelpData ? npcHelpData.activities : []; } // Filter to activities that: // 1. Have a location (skip intro activities) // 2. Canvas conditions met (NPC trait requirements) // 3. Activity trait requirements met (player traits) // 4. Increase the requested trait var relevantActivities = []; for (var i = 0; i < activities.length; i++) { var act = activities[i]; if (!act.location) continue; // Skip intro activities // Skip completed non-repeatable activities (story arc OR regular non-repeatable) if (act.is_repeatable === false || act.linked_flag) { var flags = State.variables.flags || {}; var hist = (State.variables.game_state && State.variables.game_state.trigger_history) || {}; var isCompleted = (act.linked_flag && flags[act.linked_flag]) || (act.canvas_id && hist[act.canvas_id] && hist[act.canvas_id].total > 0); if (isCompleted) continue; } // Check canvas conditions (NPC trait requirements like "Elena Affection >= 30") var canvasConditions = act.canvas_conditions; if (canvasConditions && !setup.triggerConditionsSatisfied(canvasConditions)) { continue; // Skip - canvas conditions not met } // Check activity trait requirements (player traits) var traitReqs = act.trait_requirements || []; var isLocked = false; for (var r = 0; r < traitReqs.length; r++) { if (!setup.checkTraitRequirement(traitReqs[r])) { isLocked = true; break; } } if (isLocked) continue; // Skip locked activities // Check if this activity boosts the requested trait // For player traits: match effects without npc_id // For NPC traits: match effects with any npc_id (already filtered to NPC's activities) var effects = act.trait_effects || []; for (var j = 0; j < effects.length; j++) { var eff = effects[j]; var traitMatches = eff.trait === traitKey && eff.value > 0; var targetMatches = isPlayerTrait ? !eff.npc_id : true; if (traitMatches && targetMatches) { relevantActivities.push({ name: act.name, location: act.location, schedule: act.schedule, bonus: eff.value }); break; } } } // Build modal HTML (no inline onclick - use jQuery event delegation) var traitDisplay = traitKey.charAt(0).toUpperCase() + traitKey.slice(1); var html = '<div class="trait-modal-overlay">'; html += '<div class="trait-modal">'; html += '<div class="trait-modal-header">'; var titlePossessive = isPlayerTrait ? (displayName + ' ') : (displayName + "'s "); html += '<h3>How to increase ' + titlePossessive + traitDisplay + '</h3>'; html += '<span class="trait-modal-close">×</span>'; html += '</div>'; html += '<div class="trait-modal-progress">'; html += 'Current: ' + currentValue + ' / Required: ' + requiredValue; html += '</div>'; html += '<div class="trait-modal-body">'; if (relevantActivities.length === 0) { html += '<p>No activities found that increase this trait.</p>'; } else { html += '<ul class="trait-activity-list">'; for (var k = 0; k < relevantActivities.length; k++) { var ra = relevantActivities[k]; html += '<li>'; html += '<span class="activity-name">' + ra.name + '</span>'; html += '<span class="activity-bonus">+' + ra.bonus + ' ' + traitDisplay + '</span>'; html += '<div class="activity-hint">→ Visit ' + ra.location; if (ra.schedule) html += ' ' + ra.schedule; html += '</div>'; html += '</li>'; } html += '</ul>'; } html += '</div></div></div>'; jQuery(html).appendTo('#story'); }; // Close trait activities modal setup.closeTraitModal = function() { jQuery('.trait-modal-overlay').remove(); }; // ============== END QUEST PAGE HELPERS ============== // Auto-inference for games without author-defined story arc setup.autoInferStoryPosition = function() { var result = { current_chapter: { id: "auto_chapter", name: "Your Story", mood: "developing", description: "Your adventure continues..." }, completed_nodes: [], available_nodes: [], locked_nodes: [], active_groups: [], is_stuck: false, progress_percent: 0, is_auto_inferred: true }; // Check completed canvases from game state if (State.variables.game_state && State.variables.game_state.completed_canvases) { State.variables.game_state.completed_canvases.forEach(function(canvasId) { // Avoid duplicates var existing = result.completed_nodes.find(function(n) { return n.id === canvasId; }); if (!existing) { result.completed_nodes.push({ id: canvasId, name: canvasId.replace(/_/g, " "), chapter: "auto_chapter", journal_entry: "A chapter of your story...", is_milestone: true }); } }); } // Calculate progress estimate var total = result.completed_nodes.length + result.available_nodes.length + result.locked_nodes.length; if (total > 0) { result.progress_percent = Math.round((result.completed_nodes.length / total) * 100); } result.is_stuck = result.available_nodes.length === 0 && result.locked_nodes.length > 0; return result; }; // Initialize trait requirement click handlers (event delegation) jQuery(document).on('click', '.trait-requirement-link', function(e) { e.preventDefault(); var npcId = jQuery(this).data('npc'); var trait = jQuery(this).data('trait'); var value = jQuery(this).data('value'); setup.showTraitActivitiesModal(npcId, trait, value); }); // Modal close handlers (event delegation) jQuery(document).on('click', '.trait-modal-overlay', function(e) { // Close when clicking overlay (but not modal content) if (jQuery(e.target).hasClass('trait-modal-overlay')) { setup.closeTraitModal(); } }); jQuery(document).on('click', '.trait-modal-close', function(e) { e.preventDefault(); setup.closeTraitModal(); }); <</script>><<nobr>> <div class="game-intro"> <h1>Two Weeks</h1> <p class="game-description">A young woman returns home for her step-brother's wedding, only to discover that the childhood crush she thought she'd buried still burns—and with only fourteen days until he says "I do," every moment becomes a choice between what's right and what she truly wants. </p> <div class="developer-intro"> <p class="developer-about">We're a small indie studio crafting intimate, story-driven experiences. Every game is made with care, and your support helps us keep creating. If you enjoy our work, consider supporting us!</p> <p class="support-link">👉 <a href="https://www.patreon.com/cw/nutgames844" target="_blank" rel="noopener">Support us on Patreon</a></p> </div> <div class="age-gate"> <p class="age-warning">⚠️ This game contains adult content intended for players 18 years of age or older.</p> <div class="age-buttons"> [[✓ I am 18 or older - Enter Game->StartingCanvas_scene_arrival_Node_1]] [[✗ I am NOT 18 or older->AgeBlocked]] </div> </div> <div class="developer-footer"> <p class="developer-credit">Developed by <strong>NutGames</strong></p> <p class="support-link">👉 <a href="https://www.patreon.com/cw/nutgames844" target="_blank" rel="noopener">Support us on Patreon</a></p> </div> </div> <</nobr>>
<div class="blocked-page"> <h2>Access Denied</h2> <p>This content is not available for you.</p> <p>Please close this page.</p> </div>
<!-- Time Display Widgets --> <<widget "timeFormatted">> <<set _hour to $game_state.time_state.current_hour>> <<set _minute to $game_state.time_state.current_minute>> <<set _displayHour to (_hour is 0 ? 12 : (_hour > 12 ? _hour - 12 : _hour))>> <<set _ampm to (_hour < 12 ? "AM" : "PM")>> <<set _minuteStr to (_minute < 10 ? "0" + _minute : _minute)>> <<print _displayHour + ":" + _minuteStr + " " + _ampm>> <</widget>> <<widget "timeDisplay">> <div id="time-widget" class="time-display"> <div class="time-line"> <span id="time-display"><<timeFormatted>></span> | <span id="current-day"><<print $game_state.time_state.current_day>></span> </div> <div class="control-line"> <button class="time-btn" onclick="advanceTime(10)" title="Advance 10 minutes">></button> | <button class="time-btn" onclick="advanceTime(60)" title="Advance 1 hour">>></button> | <button class="time-btn" onclick="advanceTime(1440)" title="Advance 1 day">>>>>></button> </div> </div> <</widget>> <<widget "playerTraits">> <div id="traits-widget" class="traits-display"> <div class="traits-header">Traits</div> <<if $player and $player.core_traits and Object.keys($player.core_traits).length > 0>> <<set _keys to Object.keys($player.core_traits).sort()>> <ul class="traits-list"> <<for _i to 0; _i lt _keys.length; _i++>> <<set _k to _keys[_i]>> <li class="trait-item"> <span class="trait-name"><<print _k>></span> <span class="trait-value"><<print $player.core_traits[_k]>></span> </li> <</for>> </ul> <<else>> <div class="no-traits">No traits</div> <</if>> <div class="traits-hint">Updates after each choice.</div> </div> <</widget>> <<widget "playerFlags">> <div id="flags-widget" class="traits-display"> <div class="traits-header">Flags</div> <<if $player and $player.flags and Object.keys($player.flags).length > 0>> <<set _fkeys to Object.keys($player.flags).sort()>> <ul class="traits-list"> <<for _j to 0; _j lt _fkeys.length; _j++>> <<set _fk to _fkeys[_j]>> <li class="trait-item"> <span class="trait-name"><<print _fk>></span> <span class="trait-value"><<print $player.flags[_fk] ? '✔' : '✖'>></span> </li> <</for>> </ul> <<else>> <div class="no-traits">No flags</div> <</if>> <div class="traits-hint">Set by choices and story logic.</div> </div> <</widget>> <<widget "questsButton">> <!-- Debug/legacy quest view - shows raw mechanics --> <div id="quests-btn-widget"> <<link "📋 Quests" "QuestsPage">><</link>> </div> <</widget>> <<widget "missingMediaButton">> <<if $flags.debug_mode>> <div id="missing-media-btn-widget" style="margin-bottom:8px;"> <<link "⚠️ Missing Media" "MissingMediaPage">><</link>> </div> <</if>> <</widget>> <<widget "journalButton">> <!-- Guide - simplified what's next help --> <div id="journal-btn-widget"> <<link "📖 Guide" "QuestsPage">><</link>> </div> <</widget>> <<widget "statsButton">> <div id="stats-btn-widget"> <<link "📊 Stats" "StatsPage">><</link>> </div> <</widget>> <<widget "scheduleButton">> <<set _npcsWithSchedules to setup.getNpcsWithSchedules()>> <<if _npcsWithSchedules.length > 0>> <div id="schedule-btn-widget"> <<link "📅 Schedules" "SchedulePage">><</link>> </div> <</if>> <</widget>> <<widget "patreonButton">> <div id="patreon-btn-widget"> <a href="https://www.patreon.com/cw/nutgames844" target="_blank" rel="noopener" class="patreon-link"> <svg class="patreon-icon" viewBox="0 0 24 24" width="16" height="16"> <path fill="currentColor" d="M15.386.524c-4.764 0-8.64 3.876-8.64 8.64 0 4.75 3.876 8.613 8.64 8.613 4.75 0 8.614-3.864 8.614-8.613C24 4.4 20.136.524 15.386.524M.003 23.537h4.22V.524H.003"/> </svg> Support Us </a> </div> <</widget>>
<<missingMediaButton>> <<timeDisplay>> <<journalButton>> <<statsButton>> <<scheduleButton>> <<playerTraits>> <<patreonButton>> <style> #time-widget { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 8px; margin-bottom: 10px; font-family: 'Courier New', monospace; font-size: 14px; line-height: 1.2; color: #212529; } .time-line { text-align: center; margin-bottom: 4px; font-weight: bold; color: #000000; } .control-line { text-align: center; font-size: 12px; } .time-btn { background: #e9ecef; border: 1px solid #ced4da; border-radius: 3px; color: #495057; cursor: pointer; padding: 3px 6px; font-size: 12px; font-family: 'Courier New', monospace; font-weight: bold; } .time-btn:hover { background: #dee2e6; color: #000000; border-color: #adb5bd; } #traits-widget { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 8px; margin-top: 8px; font-family: 'Courier New', monospace; font-size: 13px; color: #212529; } #flags-widget { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 8px; margin-top: 8px; font-family: 'Courier New', monospace; font-size: 13px; color: #212529; } .traits-header { font-weight: bold; margin-bottom: 6px; } .traits-list { list-style: none; padding-left: 0; margin: 0; } .trait-item { display: flex; justify-content: space-between; border-bottom: 1px dashed #e2e3e5; padding: 2px 0; } .trait-name { color: #495057; } .trait-value { color: #0d6efd; font-weight: bold; } .no-traits { font-style: italic; color: #6c757d; } .traits-hint { margin-top: 6px; font-size: 11px; color: #6c757d; } #time-display, #current-day { font-family: 'Courier New', monospace; color: #000000; } #quests-btn-widget { background: #e7f3ff; border: 1px solid #007bff; border-radius: 4px; padding: 6px 8px; margin-bottom: 8px; text-align: center; } #quests-btn-widget a { color: #007bff; text-decoration: none; font-weight: bold; } #quests-btn-widget a:hover { color: #0056b3; text-decoration: underline; } #journal-btn-widget { background: linear-gradient(180deg, #fdf6e3 0%, #f5e6d3 100%); border: 1px solid #c9b896; border-radius: 4px; padding: 6px 8px; margin-bottom: 8px; text-align: center; } #journal-btn-widget a { color: #6d5a40; text-decoration: none; font-weight: bold; font-family: 'Georgia', serif; } #journal-btn-widget a:hover { color: #4a3f30; text-decoration: underline; } #stats-btn-widget { background: #f0f7e6; border: 1px solid #28a745; border-radius: 4px; padding: 6px 8px; margin-bottom: 8px; text-align: center; } #stats-btn-widget a { color: #28a745; text-decoration: none; font-weight: bold; } #stats-btn-widget a:hover { color: #1e7e34; text-decoration: underline; } #schedule-btn-widget { background: #e8f4fc; border: 1px solid #3b82f6; border-radius: 4px; padding: 6px 8px; margin-bottom: 8px; text-align: center; } #schedule-btn-widget a { color: #3b82f6; text-decoration: none; font-weight: bold; } #schedule-btn-widget a:hover { color: #2563eb; text-decoration: underline; } /* Patreon Button in Sidebar */ #patreon-btn-widget { margin: 15px 0 0 0; padding: 15px 0 0 0; border-top: 1px solid #444; text-align: center; } /* Reduce gap between StoryCaption and Save/Restart menu */ #story-caption { margin-bottom: 0 !important; padding-bottom: 0 !important; } #menu-story { margin-top: 8px !important; } .patreon-link { display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; background: #f96854; color: #fff !important; border-radius: 4px; text-decoration: none; font-size: 0.9em; font-weight: bold; } .patreon-link:hover { background: #e85a47; text-decoration: none !important; } .patreon-icon { flex-shrink: 0; } .stats-card { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 6px; padding: 12px; margin-bottom: 12px; } .stats-name { font-weight: bold; font-size: 1.2em; color: #212529; margin-bottom: 8px; border-bottom: 1px solid #dee2e6; padding-bottom: 6px; } .stats-traits { margin-top: 8px; } .stats-trait-item { display: flex; justify-content: space-between; padding: 4px 8px; border-bottom: 1px dashed #e2e3e5; color: #343a40; } .stats-trait-value { font-weight: bold; color: #0d6efd; } /* Story Arc Help Page Styles */ .chapter-context { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); padding: 12px 16px; border-radius: 8px; margin-bottom: 16px; display: flex; justify-content: space-between; align-items: center; } .chapter-name { font-size: 1.1em; color: #e0e0e0; font-weight: bold; } .chapter-mood { font-size: 0.9em; color: #a0a0a0; font-style: italic; } .available-section h3 { font-size: 1em; color: #495057; margin: 0 0 10px 0; border-bottom: 1px solid #dee2e6; padding-bottom: 6px; } .help-card { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 6px; padding: 12px 16px; margin-bottom: 10px; } .node-name { font-weight: bold; color: #212529; } .node-hint { color: #6c757d; font-size: 0.9em; margin-top: 4px; } .narrative-hint { background: #fff3cd; border: 1px solid #ffc107; border-radius: 6px; padding: 12px; margin: 16px 0; } .narrative-hint p { margin: 0; color: #856404; } .progress-summary { text-align: center; color: #6c757d; font-size: 0.9em; margin-top: 16px; padding-top: 12px; border-top: 1px solid #dee2e6; } .no-quests-msg { font-style: italic; color: #6c757d; padding: 10px; } /* Quest Page - Simplified One Activity Per NPC */ .npc-section { margin-bottom: 20px; padding: 16px; background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-radius: 10px; border: 1px solid #dee2e6; } .npc-name { font-size: 1.2em; color: #2c3e50; margin: 0 0 12px 0; border-bottom: 2px solid #3498db; padding-bottom: 8px; font-weight: 600; } .quest-available { color: #155724; font-weight: 500; padding: 10px 14px; background: rgba(40, 167, 69, 0.1); border-radius: 6px; border-left: 4px solid #28a745; } .quest-locked { color: #856404; font-weight: 500; padding: 10px 14px; background: rgba(255, 193, 7, 0.15); border-radius: 6px; border-left: 4px solid #ffc107; } .quest-conditions { color: #721c24; font-weight: 500; padding: 10px 14px; background: rgba(220, 53, 69, 0.1); border-radius: 6px; border-left: 4px solid #dc3545; } .quest-complete { color: #28a745; font-style: italic; padding: 10px 14px; text-align: center; } .no-quests { color: #6c757d; font-style: italic; padding: 12px; text-align: center; } /* Trait Requirement Link */ .trait-requirement-link { color: #721c24; text-decoration: underline; cursor: pointer; } .trait-requirement-link:hover { color: #a71d2a; } /* Trait Activities Modal Overlay */ .trait-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.6); display: flex; align-items: center; justify-content: center; z-index: 10000; } /* Modal Container */ .trait-modal { background: #fff; border-radius: 12px; max-width: 400px; width: 90%; max-height: 80vh; overflow: hidden; box-shadow: 0 10px 40px rgba(0,0,0,0.3); } .trait-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; background: #f8f9fa; border-bottom: 1px solid #dee2e6; } .trait-modal-header h3 { margin: 0; font-size: 1.1em; color: #333; } .trait-modal-close { font-size: 24px; cursor: pointer; color: #666; line-height: 1; } .trait-modal-close:hover { color: #333; } .trait-modal-progress { padding: 12px 20px; background: rgba(220, 53, 69, 0.1); color: #721c24; font-weight: 500; text-align: center; } .trait-modal-body { padding: 16px 20px; max-height: 50vh; overflow-y: auto; } /* Activity List */ .trait-activity-list { list-style: none; padding: 0; margin: 0; } .trait-activity-list li { padding: 12px; border-bottom: 1px solid #eee; } .trait-activity-list li:last-child { border-bottom: none; } .activity-name { font-weight: 600; color: #333; } .activity-bonus { float: right; color: #28a745; font-weight: 500; } .activity-hint { margin-top: 4px; color: #666; font-size: 0.9em; clear: both; } /* Effect Toast Notification */ .effect-toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.85); color: #4ade80; padding: 10px 20px; border-radius: 6px; font-size: 14px; z-index: 9999; white-space: nowrap; } /* Game Intro - Top Left Aligned */ .game-intro { text-align: left; } /* Age Gate Section */ .age-gate { background: #fff3cd; border: 1px solid #ffc107; border-radius: 8px; padding: 20px; margin: 20px 0; text-align: center; } .age-warning { font-weight: bold; color: #856404; margin-bottom: 15px; } .age-buttons { display: flex; flex-direction: column; gap: 10px; align-items: center; } /* Developer Intro Section (above age gate) */ .developer-intro { text-align: left; color: #555; margin: 20px 0; } /* Developer Footer Section (below age gate) */ .developer-footer { margin-top: 30px; padding-top: 20px; border-top: 1px solid #dee2e6; text-align: center; color: #6c757d; font-size: 0.9em; } .developer-intro a, .developer-footer a { color: #f96854; text-decoration: none; } .developer-intro a:hover, .developer-footer a:hover { text-decoration: underline; } .developer-about { line-height: 1.5; margin: 10px 0; } .support-link { margin-top: 8px; } .developer-footer .support-link { font-weight: bold; } /* Age Blocked Page */ .blocked-page { text-align: center; padding: 50px; color: #721c24; background: #f8d7da; border-radius: 8px; margin: 50px auto; max-width: 400px; } /* Override SugarCube default vertical centering */ #story { align-items: flex-start !important; justify-content: flex-start !important; padding-top: 1em !important; } .passage { margin-top: 0 !important; padding-top: 0 !important; } /* New/Unvisited Canvas Highlight */ .new-canvas a { color: #28a745 !important; font-weight: 600; } .new-canvas a::before { content: "✨ "; } /* Navigation New Content Indicator */ .nav-new { color: #ffc107; font-weight: bold; font-size: 1.1em; } /* Dev Mode Controls */ .dev-adj-btn { background: #6c757d; color: white; border: none; border-radius: 3px; width: 20px; height: 20px; font-size: 14px; font-weight: bold; cursor: pointer; padding: 0; line-height: 1; vertical-align: middle; } .dev-adj-btn:hover { background: #5a6268; } .trait-controls { display: flex; align-items: center; gap: 4px; } .trait-controls .trait-value { min-width: 24px; text-align: center; } </style>
<<nobr>> <h2>What's Next</h2> <<set _helpData = State.variables.help_data || {}>> <<set _hasNpcs = _helpData.npcs && Object.keys(_helpData.npcs).length > 0>> <<if _hasNpcs>> <<for _npcId, _npcData range _helpData.npcs>> <div class="npc-section"> <h3 class="npc-name"><<print _npcData.name>></h3> <<set _next = setup.getNextActivity(_npcId)>> <<if _next === null>> <div class="quest-complete">✓ All activities completed!</div> <<elseif _next.traitConditionsNotMet>> <div class="quest-conditions"> 🔒 <<print setup.formatCanvasConditions(_next.canvasConditions)>> </div> <<elseif _next.flagConditionsNotMet>> <div class="quest-available"> → <<print setup.formatFlagHint(_next.flagHint)>> </div> <<elseif _next.conditionsNotMet>> <div class="quest-conditions"> 🔒 <<print setup.formatCanvasConditions(_next.canvasConditions)>> </div> <<elseif _next.isLocked>> <div class="quest-locked"> 🔒 <<print setup.formatTraitRequirements(_next.missingTraits)>> </div> <<else>> <div class="quest-available"> → <<print setup.formatActivityHint(_next.activity)>> </div> <</if>> </div> <</for>> <<else>> <div class="no-quests">No activities available.</div> <</if>> <</nobr>> <<link "← Back">><<run Engine.backward()>><</link>>
<<set _position = setup.detectStoryPosition()>> <<set _hint = setup.generateNarrativeHint()>> <div class="journal-container"> <div class="journal-header"> <<if _position.current_chapter>> <h2 class="journal-chapter-title"><<print _position.current_chapter.name>></h2> <<if _position.current_chapter.mood>> <div class="journal-chapter-mood <<print _position.current_chapter.mood>>"> <<print _position.current_chapter.description || "">> </div> <</if>> <<else>> <h2 class="journal-chapter-title">Your Story</h2> <</if>> <<if _position.progress_percent > 0>> <div class="journal-progress"> <div class="journal-progress-bar"> <div class="journal-progress-fill" style="width: <<print _position.progress_percent>>%;"></div> </div> </div> <</if>> </div> <!-- Memories (completed story moments) --> <<if _position.completed_nodes.length > 0>> <div class="journal-section"> <div class="journal-section-title">Memories</div> <<for _i, _node range _position.completed_nodes>> <div class="journal-memory <<if _node.is_milestone>>milestone<</if>>"> <div class="journal-memory-title"><<print _node.name>></div> <<if _node.journal_entry>> <<print _node.journal_entry>> <</if>> </div> <</for>> </div> <</if>> <!-- Active story threads (groups in progress) --> <<if _position.active_groups.length > 0>> <<set _incompleteGroups = _position.active_groups.filter(function(g) { return !g.isComplete && g.completed > 0; })>> <<if _incompleteGroups.length > 0>> <div class="journal-section"> <div class="journal-section-title">Unfolding</div> <<for _i, _group range _incompleteGroups>> <div class="journal-group"> <div class="journal-group-name"><<print _group.name>></div> <div class="journal-group-progress"> <<print _group.description>> </div> </div> <</for>> </div> <</if>> <</if>> <!-- Relationship states (NPC emotions) --> <<if Object.keys($npcs).length > 0>> <div class="journal-section"> <div class="journal-section-title">Connections</div> <<for _npcId range Object.keys($npcs)>> <<set _state = setup.interpretNpcState(_npcId)>> <<if _state.npc_name>> <div class="journal-npc"> <div class="journal-npc-name"><<print _state.npc_name>></div> <div class="journal-npc-emotion"><<print _state.description>></div> <<if _state.relationship_summary && _state.relationship_summary !== _state.description>> <div class="journal-npc-summary"><<print _state.relationship_summary>></div> <</if>> </div> <</if>> <</for>> </div> <</if>> <!-- Subtle narrative hint (only when needed) --> <<if _hint.hint_type !== "none" && _hint.text>> <div class="journal-hint <<print _hint.hint_type>>"> <<print _hint.text>> </div> <</if>> <!-- Empty state --> <<if _position.completed_nodes.length === 0 && Object.keys($npcs).length === 0>> <div class="journal-empty"> Your story is just beginning... </div> <</if>> <div class="journal-back-link"> [[Return to your story->Navigation]] </div> </div>
<<nobr>> <h2>All Stats</h2> <!-- Player Stats --> <div class="stats-card"> <div class="stats-name">You (<<print $player.name>>)</div> <div class="stats-traits"> <<if $player && $player.core_traits && Object.keys($player.core_traits).length > 0>> <<for _tk, _tv range $player.core_traits>> <div class="stats-trait-item"> <span><<print _tk>></span> <span class="stats-trait-value"><<print _tv>></span> </div> <</for>> <<else>> <em>No traits</em> <</if>> </div> </div> <!-- NPC Stats --> <<if Object.keys($npcs).length > 0>> <<for _npcId, _npc range $npcs>> <div class="stats-card"> <div class="stats-name"><<print _npc.name>></div> <div class="stats-traits"> <<if _npc.core_traits && Object.keys(_npc.core_traits).length > 0>> <<for _tk, _tv range _npc.core_traits>> <div class="stats-trait-item"> <span><<print _tk>></span> <span class="stats-trait-value"><<print _tv>></span> </div> <</for>> <<else>> <em>No traits</em> <</if>> </div> </div> <</for>> <<else>> <p><em>No NPCs found.</em></p> <</if>> <</nobr>> <<link "← Back">><<run Engine.backward()>><</link>>
<<nobr>> <<set _currentDay to $game_state.time_state.current_day>> <h2>📅 <<print _currentDay>>'s Schedules</h2> <p class="current-time">Current Time: <<print setup.formatTime($game_state.time_state.current_hour, $game_state.time_state.current_minute)>></p> <<set _npcsWithSchedules to setup.getNpcsWithSchedules()>> <<if _npcsWithSchedules.length === 0>> <p><em>No NPCs have schedules defined.</em></p> <<else>> <<for _npcInfo range _npcsWithSchedules>> <<set _npcId to _npcInfo.id>> <<set _npcName to _npcInfo.name>> <<set _currentLoc to setup.getNpcLocation(_npcId)>> <<set _todaySchedule to setup.getTodayScheduleSorted(_npcId)>> <<set _dayIndex to ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"].indexOf(_currentDay)>> <div class="schedule-card"> <div class="schedule-header"> <span class="npc-name"><<print _npcName>></span> <<if _currentLoc>> <<set _locName to ($locations[_currentLoc.location] && $locations[_currentLoc.location].name) || _currentLoc.location>> <span class="now-badge">NOW: <<print _locName>></span> <</if>> </div> <<if _currentLoc && _currentLoc.activity>> <div class="current-activity">"<<print _currentLoc.activity>>"</div> <</if>> <<if _todaySchedule.length === 0>> <p><em>No schedule entries for <<print _currentDay>>.</em></p> <<else>> <p class="schedule-day-info"><<print _todaySchedule.length>> schedule entries for <<print _currentDay>></p> <table class="schedule-table"> <thead><tr><th>Time</th><th>Location</th><th>Activity</th></tr></thead> <tbody> <<for _sch range _todaySchedule>> <<set _isCurrent to setup.isCurrentTimeSlot(_sch.start_time, _sch.end_time)>> <<set _rowClass to _isCurrent ? "current-slot" : "">> <<set _schLocName to ($locations[_sch.location] && $locations[_sch.location].name) || _sch.location>> <tr class="<<print _rowClass>>"> <td><<if _isCurrent>>▶ <</if>><<print _sch.start_time>>-<<print _sch.end_time || "?">></td> <td><<print _schLocName>></td> <td><<print _sch.activity>></td> </tr> <</for>> </tbody> </table> <</if>> </div> <</for>> <</if>> <<return "← Back">> <</nobr>> <style> .current-time { color: #334155; font-size: 0.9em; margin: 0 0 10px 0; } .schedule-card { background: #ffffff; border: 1px solid #e2e8f0; border-radius: 8px; padding: 12px; margin-bottom: 12px; } .schedule-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } .npc-name { font-size: 1.1em; font-weight: bold; color: #1e293b; } .now-badge { background: #22c55e; color: white; padding: 3px 8px; border-radius: 10px; font-size: 0.8em; font-weight: bold; } .current-activity { color: #475569; font-style: italic; margin-bottom: 6px; font-size: 0.85em; } .schedule-day-info { color: #64748b; font-size: 0.8em; margin: 0 0 6px 0; padding: 2px 6px; background: #f1f5f9; border-radius: 3px; display: inline-block; } .schedule-table { width: 100%; border-collapse: collapse; font-size: 0.85em; color: #1e293b; } .schedule-table th { text-align: left; padding: 4px 8px; background: #f1f5f9; border-bottom: 2px solid #e2e8f0; color: #334155; font-weight: 600; } .schedule-table td { padding: 4px 8px; border-bottom: 1px solid #e2e8f0; color: #334155; } .schedule-table tr.current-slot { background: #fef3c7; font-weight: 500; } .schedule-table tr.current-slot td:first-child { color: #d97706; } </style>
<h1>Two Weeks</h1><p>You haven't been home in two years. Two years of putting distance between yourself and everything you left behind. Two years of convincing yourself you were over it.</p><p>The taxi pulls away, leaving you standing on the familiar sidewalk with your suitcase. You're here for your step-brother's wedding—that's what you tell yourself. That's the only reason your heart is pounding.</p><p>You grew up in this house. Eight years of shared dinners, stolen glances, feelings you buried so deep you almost forgot they existed. Almost.</p><p>Ethan. Your step-brother. The boy who became a man while you were away. The man who's getting married in fourteen days.</p><p>You take a breath. Compose yourself. You're just here for the wedding. Nothing more.</p><img src="./media/images/scene_arrival_house.jpg" alt="The familiar house where you grew up" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "3ae0a423-d98e-4659-900c-f6a43bd6a3e5">> <<set $game_state.current_node = "c8ebfd61-e452-4549-9f8f-78d37aa18e85">> <<script>>setup.markCanvasTriggered("3ae0a423-d98e-4659-900c-f6a43bd6a3e5");<</script>> <<link "Ring the doorbell" "StartingCanvas_scene_arrival_Node_2">><<script>>advanceTime(3);<</script>><</link>><br>
<p>The door swings open, and there he is.</p><p>Ethan. Taller than you remembered—or maybe you just forgot. His athletic build has filled out since college, shoulders broad beneath a worn gray t-shirt. Those warm brown eyes that always seemed to see right through you. Hair still perpetually disheveled, like he just ran his fingers through it. And that smile—the one that makes his eyes crinkle at the corners. The one that used to make you forget how to breathe.</p><p>It still does.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Hey, stranger.</div><p>Before you can respond, he's pulling you into a hug. A proper embrace—his arms wrapping around you, solid and warm. You breathe him in without meaning to. Same soap. Same warmth. Same Ethan.</p><p>His arms tighten for just a moment longer than they should. Then he releases you, stepping back with that smile still on his face.</p><img src="./media/scenes/scene_arrival.gif" alt="First embrace - a proper hug that lingers just a moment too long" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> It's really good to see you.</div><p>Two years of careful distance collapse in an instant. Every feeling you buried comes rushing back, and you're standing there trying to remember how to speak.</p> <<set $game_state.current_canvas = "3ae0a423-d98e-4659-900c-f6a43bd6a3e5">> <<set $game_state.current_node = "2ba33b89-d6e4-4708-aa85-56db4357e202">> <<link "\"I missed you.\"" "StartingCanvas_scene_arrival_Node_3">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"You look good. Really good.\"" "StartingCanvas_scene_arrival_Node_3">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 2.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"So this is where the big day happens, huh?\"" "StartingCanvas_scene_arrival_Node_3">><<script>>advanceTime(3);<</script>><</link>><br>
<p>He grabs your suitcase before you can protest, leading you inside. The house smells the same—coffee and cedar and something uniquely home. Family photos line the hallway walls. You spot one of the two of you as teenagers, standing too close at someone's birthday party.</p><p>He leads you upstairs to your old room. The guest room now, technically, but some of your old things are still here. Posters on the wall. Books on the shelf. Memories you left behind.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Madison's away with her family right now, finalizing some wedding stuff. Venue details, family drama, you know how it is.</div><p>Madison. His fiancée. The woman he's marrying in two weeks. You've seen photos—she's beautiful, polished, everything you're not. She's not a villain. She's just... the person standing between you and something you can never have.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> So it's just us for the next couple weeks. Until she gets back for the final stretch.</div><p>Just us. The words hang in the air between you, heavy with meaning neither of you will acknowledge.</p><p>Two weeks. Alone together. In the house where you grew up side by side, pretending you didn't feel what you felt.</p><p>This is going to be harder than you thought.</p> <<set $game_state.current_canvas = "3ae0a423-d98e-4659-900c-f6a43bd6a3e5">> <<set $game_state.current_node = "207b8bf0-b087-4fe9-bb9e-ed7b8c20fe10">> <<script>>advanceTime(60);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "arrival_complete");setup.applyAndNotifyFlag("player", null, "game_started");<</script>> [[Get settled in->Location_Upstairs_Hallway]]
<h2>Navigation</h2> <p>Where would you like to go?</p> <div class="location-list"> [[Upstairs Hallway->Location_Upstairs_Hallway]]<br> [[Your Old Room->Location_Your_Old_Room]]<br> [[Upstairs Bathroom->Location_Upstairs_Bathroom]]<br> [[Ethan's Bedroom->Location_Ethan's_Bedroom]]<br> [[Living Room->Location_Living_Room]]<br> [[Kitchen->Location_Kitchen]]<br> [[Backyard & Pool->Location_Backyard_&_Pool]]<br> [[Garage->Location_Garage]]<br> </div> <!-- LOCATION PASSAGES -->
<h2>Upstairs Hallway</h2> <p>The central artery of the house. Family photos line the walls—including several of you and Ethan as teenagers. Doors lead to bedrooms and bathroom. A window overlooks the backyard.</p> <<set $player.current_location = "6b717a40-88fc-45ef-bfd3-c58c0438052c">> <<if not $game_state.visited_locations.includes("6b717a40-88fc-45ef-bfd3-c58c0438052c")>> <<set $game_state.visited_locations.push("6b717a40-88fc-45ef-bfd3-c58c0438052c")>> <</if>> <<nobr>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("38d240e2-e18b-4cf4-b77c-a6b85a3a6765", true, 1)>> <<if setup.isCanvasNew("38d240e2-e18b-4cf4-b77c-a6b85a3a6765")>><span class="new-canvas">[[Saying Goodnight->Canvas_activity_goodnight_t5_Node_1]]</span><<else>>[[Saying Goodnight->Canvas_activity_goodnight_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("a39d2179-f7e6-4ba6-b1e3-f146bb812b71", true, 1)>> <<if setup.isCanvasNew("a39d2179-f7e6-4ba6-b1e3-f146bb812b71")>><span class="new-canvas">[[Saying Goodnight->Canvas_activity_goodnight_t4_Node_1]]</span><<else>>[[Saying Goodnight->Canvas_activity_goodnight_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("8041f658-eee5-434f-a24f-95533104b894", true, 1)>> <<if setup.isCanvasNew("8041f658-eee5-434f-a24f-95533104b894")>><span class="new-canvas">[[Saying Goodnight->Canvas_activity_goodnight_t3_Node_1]]</span><<else>>[[Saying Goodnight->Canvas_activity_goodnight_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("aee10b91-48f4-4f2c-b8b4-b4ff83d8616f", true, 1)>> <<if setup.isCanvasNew("aee10b91-48f4-4f2c-b8b4-b4ff83d8616f")>><span class="new-canvas">[[Saying Goodnight->Canvas_activity_goodnight_t2_Node_1]]</span><<else>>[[Saying Goodnight->Canvas_activity_goodnight_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("09b332a6-eab6-4d97-99a3-6561abc42d6c", true, 1)>> <<if setup.isCanvasNew("09b332a6-eab6-4d97-99a3-6561abc42d6c")>><span class="new-canvas">[[Saying Goodnight->Canvas_activity_goodnight_t1_Node_1]]</span><<else>>[[Saying Goodnight->Canvas_activity_goodnight_t1_Node_1]]<</if>><br> <</if>> <<if setup.canTriggerCanvas("79d7b9d6-29ee-4962-ae7a-91226ed22ae9", true, null)>> <<if setup.isCanvasNew("79d7b9d6-29ee-4962-ae7a-91226ed22ae9")>><span class="new-canvas">[[Wander the House->Canvas_solo_wander_Node_1]]</span><<else>>[[Wander the House->Canvas_solo_wander_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "cant_stay_away_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("7ab8806f-3582-4c37-a50f-93abbaf872e0", false, null)>> <<if setup.isCanvasNew("7ab8806f-3582-4c37-a50f-93abbaf872e0")>><span class="new-canvas">[[Madison Arrives->Canvas_scene_madison_arrives_Node_1]]</span><<else>>[[Madison Arrives->Canvas_scene_madison_arrives_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "morning_after_complete", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("7f5880ef-b71d-47d3-9506-aa2caaefe382", false, null)>> <<if setup.isCanvasNew("7f5880ef-b71d-47d3-9506-aa2caaefe382")>><span class="new-canvas">[[Can't Stay Away->Canvas_scene_cant_stay_away_Node_1]]</span><<else>>[[Can't Stay Away->Canvas_scene_cant_stay_away_Node_1]]<</if>><br> <</if>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> <strong>Available destinations:</strong><br> [[Your Old Room->Location_Your_Old_Room]]<<if setup.locationHasNewCanvases("3eac7d4e-f70f-4744-bba2-01059c0b59c5")>> <span class="nav-new">!</span><</if>><br> [[Upstairs Bathroom->Location_Upstairs_Bathroom]]<<if setup.locationHasNewCanvases("c05d22eb-3a00-4972-a9ed-717ff4b1be73")>> <span class="nav-new">!</span><</if>><br> [[Ethan's Bedroom->Location_Ethan's_Bedroom]]<<if setup.locationHasNewCanvases("6215c1db-cb47-4391-b2e7-dac657d835e2")>> <span class="nav-new">!</span><</if>><br> [[Living Room->Location_Living_Room]]<<if setup.locationHasNewCanvases("025944f1-16b0-4b03-a1ab-935d9ddc076f")>> <span class="nav-new">!</span><</if>><br> </div>
<h2>Your Old Room</h2> <p>The guest room that was once yours. Some of your old things are still here—posters you left behind, books on the shelf. The bed is smaller than you remembered. Window overlooks the backyard pool.</p> <<set $player.current_location = "3eac7d4e-f70f-4744-bba2-01059c0b59c5">> <<if not $game_state.visited_locations.includes("3eac7d4e-f70f-4744-bba2-01059c0b59c5")>> <<set $game_state.visited_locations.push("3eac7d4e-f70f-4744-bba2-01059c0b59c5")>> <</if>> <<nobr>> <<if setup.canTriggerCanvas("463b8f19-3ed7-44e2-a9be-e2b51ae89dee", true, null)>> <<if setup.isCanvasNew("463b8f19-3ed7-44e2-a9be-e2b51ae89dee")>><span class="new-canvas">[[Write in Your Journal->Canvas_solo_journal_Node_1]]</span><<else>>[[Write in Your Journal->Canvas_solo_journal_Node_1]]<</if>><br> <</if>> <<if setup.canTriggerCanvas("5b66480a-4811-46e5-a515-04d3e9a53bdd", true, null)>> <<if setup.isCanvasNew("5b66480a-4811-46e5-a515-04d3e9a53bdd")>><span class="new-canvas">[[Check Your Phone->Canvas_solo_phone_Node_1]]</span><<else>>[[Check Your Phone->Canvas_solo_phone_Node_1]]<</if>><br> <</if>> <<if setup.canTriggerCanvas("2545cef7-fb06-4ab4-8d78-cc2fb8b314d2", false, null)>> <<if setup.isCanvasNew("2545cef7-fb06-4ab4-8d78-cc2fb8b314d2")>><span class="new-canvas">[[Unpack Your Things->Canvas_solo_unpack_Node_1]]</span><<else>>[[Unpack Your Things->Canvas_solo_unpack_Node_1]]<</if>><br> <</if>> <<if setup.canTriggerCanvas("e4501f93-13d9-4faf-8701-ca5e05f2c148", true, 2)>> <<if setup.isCanvasNew("e4501f93-13d9-4faf-8701-ca5e05f2c148")>><span class="new-canvas">[[Get Some Rest->Canvas_solo_sleep_Node_1]]</span><<else>>[[Get Some Rest->Canvas_solo_sleep_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "stolen_moment_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("4840b621-e25f-411f-b937-28acadc2f012", false, null)>> <<if setup.isCanvasNew("4840b621-e25f-411f-b937-28acadc2f012")>><span class="new-canvas">[[Night Before Wedding->Canvas_scene_night_before_wedding_Node_1]]</span><<else>>[[Night Before Wedding->Canvas_scene_night_before_wedding_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("94751735-6f29-4dd2-b5f8-871202ec0ed5", false, null)>> <<if setup.isCanvasNew("94751735-6f29-4dd2-b5f8-871202ec0ed5")>><span class="new-canvas">[[Morning After->Canvas_scene_morning_after_Node_1]]</span><<else>>[[Morning After->Canvas_scene_morning_after_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "what_are_we_doing_done", "operator": "is_true"}, {"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("3c251c46-2604-493f-95ad-488ff4e13af0", false, null)>> <<if setup.isCanvasNew("3c251c46-2604-493f-95ad-488ff4e13af0")>><span class="new-canvas">[[First Night Together->Canvas_scene_first_night_Node_1]]</span><<else>>[[First Night Together->Canvas_scene_first_night_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("721b6515-4264-4630-b9c4-8eafcf6e5120", false, null)>> <<if setup.isCanvasNew("721b6515-4264-4630-b9c4-8eafcf6e5120")>><span class="new-canvas">[[The Real Talk->Canvas_scene_real_talk_Node_1]]</span><<else>>[[The Real Talk->Canvas_scene_real_talk_Node_1]]<</if>><br> <</if>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> [[Leave Your Old Room->Location_Upstairs_Hallway]]<br> </div>
<h2>Upstairs Bathroom</h2> <p>Shared bathroom with a large mirror, walk-in shower with glass door. Acoustics carry—you can hear when someone's in here.</p> <<set $player.current_location = "c05d22eb-3a00-4972-a9ed-717ff4b1be73">> <<if not $game_state.visited_locations.includes("c05d22eb-3a00-4972-a9ed-717ff4b1be73")>> <<set $game_state.visited_locations.push("c05d22eb-3a00-4972-a9ed-717ff4b1be73")>> <</if>> <<nobr>> <<if setup.canTriggerCanvas("40bff3dc-70eb-413f-a93b-9ce360da0481", true, null)>> <<if setup.isCanvasNew("40bff3dc-70eb-413f-a93b-9ce360da0481")>><span class="new-canvas">[[Get Ready->Canvas_solo_get_ready_Node_1]]</span><<else>>[[Get Ready->Canvas_solo_get_ready_Node_1]]<</if>><br> <</if>> <<if setup.canTriggerCanvas("bde40787-6198-478f-acd7-c262f235c484", true, null)>> <<if setup.isCanvasNew("bde40787-6198-478f-acd7-c262f235c484")>><span class="new-canvas">[[Take a Shower->Canvas_solo_shower_t1_Node_1]]</span><<else>>[[Take a Shower->Canvas_solo_shower_t1_Node_1]]<</if>><br> <</if>> <<if setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("e10d2766-69a4-4519-9306-f4ccbc27981f", true, null)>> <<if setup.isCanvasNew("e10d2766-69a4-4519-9306-f4ccbc27981f")>><span class="new-canvas">[[Take a Shower->Canvas_solo_shower_t2_Node_1]]</span><<else>>[[Take a Shower->Canvas_solo_shower_t2_Node_1]]<</if>><br> <</if>> <<if setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "almost_kiss_complete", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 50, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}) and setup.canTriggerCanvas("c0390255-cd42-46dd-86d7-147e542a473b", true, null)>> <<if setup.isCanvasNew("c0390255-cd42-46dd-86d7-147e542a473b")>><span class="new-canvas">[[Take a Shower->Canvas_solo_shower_t3_Node_1]]</span><<else>>[[Take a Shower->Canvas_solo_shower_t3_Node_1]]<</if>><br> <</if>> <<if setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 60, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}) and setup.canTriggerCanvas("6fd48df2-2dca-4ab7-a7be-b234e4a7143b", true, null)>> <<if setup.isCanvasNew("6fd48df2-2dca-4ab7-a7be-b234e4a7143b")>><span class="new-canvas">[[Take a Shower->Canvas_solo_shower_t4_Node_1]]</span><<else>>[[Take a Shower->Canvas_solo_shower_t4_Node_1]]<</if>><br> <</if>> <<if setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "first_night_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("0834d14d-55f4-4aa6-b60b-753588944c09", true, null)>> <<if setup.isCanvasNew("0834d14d-55f4-4aa6-b60b-753588944c09")>><span class="new-canvas">[[Take a Shower->Canvas_solo_shower_t5_Node_1]]</span><<else>>[[Take a Shower->Canvas_solo_shower_t5_Node_1]]<</if>><br> <</if>> <<if setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "morning_after_complete", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 80, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}) and setup.canTriggerCanvas("2258aef8-bc4d-4e9e-a766-bacfdd800739", true, null)>> <<if setup.isCanvasNew("2258aef8-bc4d-4e9e-a766-bacfdd800739")>><span class="new-canvas">[[Take a Shower->Canvas_solo_shower_t6_Node_1]]</span><<else>>[[Take a Shower->Canvas_solo_shower_t6_Node_1]]<</if>><br> <</if>> <<if setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "cant_stay_away_complete", "operator": "is_true"}, {"type": "affection", "npcId": "npc_ethan", "value": 90, "subject": "npc", "operator": ">="}], "logic": "OR", "version": "1.0"}) and setup.canTriggerCanvas("26e1a29a-54d0-4f4b-87de-864e54a0e01e", true, null)>> <<if setup.isCanvasNew("26e1a29a-54d0-4f4b-87de-864e54a0e01e")>><span class="new-canvas">[[Take a Shower->Canvas_solo_shower_t7_Node_1]]</span><<else>>[[Take a Shower->Canvas_solo_shower_t7_Node_1]]<</if>><br> <</if>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> [[Leave Upstairs Bathroom->Location_Upstairs_Hallway]]<br> </div>
<h2>Ethan's Bedroom</h2> <p>Master bedroom with a king bed. Madison's presence is visible—her things on the dresser, their engagement photo on the nightstand. Entering feels like crossing a line.</p> <<set $player.current_location = "6215c1db-cb47-4391-b2e7-dac657d835e2">> <<if not $game_state.visited_locations.includes("6215c1db-cb47-4391-b2e7-dac657d835e2")>> <<set $game_state.visited_locations.push("6215c1db-cb47-4391-b2e7-dac657d835e2")>> <</if>> <<nobr>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> [[Leave Ethan's Bedroom->Location_Upstairs_Hallway]]<br> </div>
<h2>Living Room</h2> <p>Comfortable space with a large sectional couch, flatscreen TV, and soft lighting. The couch is notably oversized—easy to end up sitting close. Wedding planning materials scattered on coffee table.</p> <<set $player.current_location = "025944f1-16b0-4b03-a1ab-935d9ddc076f">> <<if not $game_state.visited_locations.includes("025944f1-16b0-4b03-a1ab-935d9ddc076f")>> <<set $game_state.visited_locations.push("025944f1-16b0-4b03-a1ab-935d9ddc076f")>> <</if>> <<nobr>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("ad75137d-989d-4249-b993-1e7b17fadeb5", true, 1)>> <<if setup.isCanvasNew("ad75137d-989d-4249-b993-1e7b17fadeb5")>><span class="new-canvas">[[Movie Night->Canvas_activity_movie_night_t5_Node_1]]</span><<else>>[[Movie Night->Canvas_activity_movie_night_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("3557832c-8856-4f2f-a4d2-585a1c75efaa", true, 1)>> <<if setup.isCanvasNew("3557832c-8856-4f2f-a4d2-585a1c75efaa")>><span class="new-canvas">[[Movie Night->Canvas_activity_movie_night_t4_Node_1]]</span><<else>>[[Movie Night->Canvas_activity_movie_night_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("bce73abd-d2c3-4e33-be56-72c5e7c47fc8", true, 1)>> <<if setup.isCanvasNew("bce73abd-d2c3-4e33-be56-72c5e7c47fc8")>><span class="new-canvas">[[Movie Night->Canvas_activity_movie_night_t3_Node_1]]</span><<else>>[[Movie Night->Canvas_activity_movie_night_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("3aeb65fd-0961-4fcd-97ea-08e20d628f59", true, 1)>> <<if setup.isCanvasNew("3aeb65fd-0961-4fcd-97ea-08e20d628f59")>><span class="new-canvas">[[Movie Night->Canvas_activity_movie_night_t2_Node_1]]</span><<else>>[[Movie Night->Canvas_activity_movie_night_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("71a09dc8-ff6d-49d1-8f7f-9503785208a3", true, 1)>> <<if setup.isCanvasNew("71a09dc8-ff6d-49d1-8f7f-9503785208a3")>><span class="new-canvas">[[Movie Night->Canvas_activity_movie_night_t1_Node_1]]</span><<else>>[[Movie Night->Canvas_activity_movie_night_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("409aa9e5-c940-4640-8408-91041d4e7811", true, 1)>> <<if setup.isCanvasNew("409aa9e5-c940-4640-8408-91041d4e7811")>><span class="new-canvas">[[Wedding Planning Help->Canvas_activity_wedding_planning_t5_Node_1]]</span><<else>>[[Wedding Planning Help->Canvas_activity_wedding_planning_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("2ab37e92-9d1b-4438-a17a-59b8b5a6cba3", true, 1)>> <<if setup.isCanvasNew("2ab37e92-9d1b-4438-a17a-59b8b5a6cba3")>><span class="new-canvas">[[Wedding Planning Help->Canvas_activity_wedding_planning_t4_Node_1]]</span><<else>>[[Wedding Planning Help->Canvas_activity_wedding_planning_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("b8f87c2e-e5f3-40eb-940e-7a8dda96b944", true, 1)>> <<if setup.isCanvasNew("b8f87c2e-e5f3-40eb-940e-7a8dda96b944")>><span class="new-canvas">[[Wedding Planning Help->Canvas_activity_wedding_planning_t3_Node_1]]</span><<else>>[[Wedding Planning Help->Canvas_activity_wedding_planning_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("769fa786-16b6-4d36-b3af-2b61e2a22f19", true, 1)>> <<if setup.isCanvasNew("769fa786-16b6-4d36-b3af-2b61e2a22f19")>><span class="new-canvas">[[Wedding Planning Help->Canvas_activity_wedding_planning_t2_Node_1]]</span><<else>>[[Wedding Planning Help->Canvas_activity_wedding_planning_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("a08fa545-9646-4033-b22a-2a6b94bec46c", true, 1)>> <<if setup.isCanvasNew("a08fa545-9646-4033-b22a-2a6b94bec46c")>><span class="new-canvas">[[Wedding Planning Help->Canvas_activity_wedding_planning_t1_Node_1]]</span><<else>>[[Wedding Planning Help->Canvas_activity_wedding_planning_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("71bafae7-a820-43df-ae90-d0cf20306c01", true, 1)>> <<if setup.isCanvasNew("71bafae7-a820-43df-ae90-d0cf20306c01")>><span class="new-canvas">[[Helping with Chores->Canvas_activity_helping_chores_t5_Node_1]]</span><<else>>[[Helping with Chores->Canvas_activity_helping_chores_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("52b8fa8c-bdec-441f-a02b-38678ad6d3d1", true, 1)>> <<if setup.isCanvasNew("52b8fa8c-bdec-441f-a02b-38678ad6d3d1")>><span class="new-canvas">[[Helping with Chores->Canvas_activity_helping_chores_t4_Node_1]]</span><<else>>[[Helping with Chores->Canvas_activity_helping_chores_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("64e060ee-617f-4eab-b2ff-105075f0e437", true, 1)>> <<if setup.isCanvasNew("64e060ee-617f-4eab-b2ff-105075f0e437")>><span class="new-canvas">[[Helping with Chores->Canvas_activity_helping_chores_t3_Node_1]]</span><<else>>[[Helping with Chores->Canvas_activity_helping_chores_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("3a9eea3d-5353-4f8d-b721-8ad04ddafb3a", true, 1)>> <<if setup.isCanvasNew("3a9eea3d-5353-4f8d-b721-8ad04ddafb3a")>><span class="new-canvas">[[Helping with Chores->Canvas_activity_helping_chores_t2_Node_1]]</span><<else>>[[Helping with Chores->Canvas_activity_helping_chores_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("18dd23b7-00c0-4faf-8e6a-6a10910bbac7", true, 1)>> <<if setup.isCanvasNew("18dd23b7-00c0-4faf-8e6a-6a10910bbac7")>><span class="new-canvas">[[Helping with Chores->Canvas_activity_helping_chores_t1_Node_1]]</span><<else>>[[Helping with Chores->Canvas_activity_helping_chores_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("d7cf66e5-8b92-4a53-b4d7-0dcb734cc401", false, null)>> <<if setup.isCanvasNew("d7cf66e5-8b92-4a53-b4d7-0dcb734cc401")>><span class="new-canvas">[[What Could Have Been->Canvas_ending_what_could_have_been_Node_1]]</span><<else>>[[What Could Have Been->Canvas_ending_what_could_have_been_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}, {"type": "trait", "value": 80, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 60, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("23ea19a2-a13a-4cd0-9e3f-91adefe2de0e", false, null)>> <<if setup.isCanvasNew("23ea19a2-a13a-4cd0-9e3f-91adefe2de0e")>><span class="new-canvas">[[One Last Night->Canvas_ending_one_last_night_Node_1]]</span><<else>>[[One Last Night->Canvas_ending_one_last_night_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "guilt"}, {"type": "trait", "value": 60, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("0f195b3f-bcfa-44c0-a100-37ad4e325285", false, null)>> <<if setup.isCanvasNew("0f195b3f-bcfa-44c0-a100-37ad4e325285")>><span class="new-canvas">[[The Arrangement->Canvas_ending_the_arrangement_Node_1]]</span><<else>>[[The Arrangement->Canvas_ending_the_arrangement_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "09:00", "12:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "wedding_morning_done", "operator": "is_true"}, {"type": "trait", "value": 95, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 70, "subject": "player", "operator": "gte", "trait_key": "boldness"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "lt", "trait_key": "guilt"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("a87c60a5-8a49-4cc3-9a12-faae9080e2f2", false, null)>> <<if setup.isCanvasNew("a87c60a5-8a49-4cc3-9a12-faae9080e2f2")>><span class="new-canvas">[[He Chooses You->Canvas_ending_he_chooses_you_Node_1]]</span><<else>>[[He Chooses You->Canvas_ending_he_chooses_you_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "real_talk_complete", "operator": "is_true"}, {"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("9c442310-64b4-4b5d-8d04-e1705e8aa45e", false, null)>> <<if setup.isCanvasNew("9c442310-64b4-4b5d-8d04-e1705e8aa45e")>><span class="new-canvas">[[First Kiss->Canvas_scene_first_kiss_Node_1]]</span><<else>>[[First Kiss->Canvas_scene_first_kiss_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "madison_calls_complete", "operator": "is_true"}, {"type": "trait", "value": 40, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("586e0e77-efb7-4334-80eb-23411951bdb4", false, null)>> <<if setup.isCanvasNew("586e0e77-efb7-4334-80eb-23411951bdb4")>><span class="new-canvas">[[The Couch->Canvas_scene_the_couch_Node_1]]</span><<else>>[[The Couch->Canvas_scene_the_couch_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "12:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "sleepless_night_complete", "operator": "is_true"}, {"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("22cc3189-8f9f-4016-837c-3014248a4bff", false, null)>> <<if setup.isCanvasNew("22cc3189-8f9f-4016-837c-3014248a4bff")>><span class="new-canvas">[[Madison Calls->Canvas_scene_madison_calls_Node_1]]</span><<else>>[[Madison Calls->Canvas_scene_madison_calls_Node_1]]<</if>><br> <</if>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> <strong>Available destinations:</strong><br> [[Kitchen->Location_Kitchen]]<<if setup.locationHasNewCanvases("1cc5ebd9-1cdb-4202-a589-03322cb79f83")>> <span class="nav-new">!</span><</if>><br> [[Leave Living Room->Location_Upstairs_Hallway]]<br> </div>
<h2>Kitchen</h2> <p>Open-plan modern kitchen with a large island and breakfast bar. Morning light floods through windows. Coffee maker prominently featured. Connected to living area.</p> <<set $player.current_location = "1cc5ebd9-1cdb-4202-a589-03322cb79f83">> <<if not $game_state.visited_locations.includes("1cc5ebd9-1cdb-4202-a589-03322cb79f83")>> <<set $game_state.visited_locations.push("1cc5ebd9-1cdb-4202-a589-03322cb79f83")>> <</if>> <<nobr>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("73cbe973-6aea-457e-99e9-ea46f429d150", true, 1)>> <<if setup.isCanvasNew("73cbe973-6aea-457e-99e9-ea46f429d150")>><span class="new-canvas">[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t5_Node_1]]</span><<else>>[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("4429251c-f1ed-4dcd-a04d-975f344d695e", true, 1)>> <<if setup.isCanvasNew("4429251c-f1ed-4dcd-a04d-975f344d695e")>><span class="new-canvas">[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t4_Node_1]]</span><<else>>[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("7073455c-e506-42c3-9640-040428d6d7b8", true, 1)>> <<if setup.isCanvasNew("7073455c-e506-42c3-9640-040428d6d7b8")>><span class="new-canvas">[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t3_Node_1]]</span><<else>>[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("21935a2f-f38a-48e6-9f7e-ae7c779d0174", true, 1)>> <<if setup.isCanvasNew("21935a2f-f38a-48e6-9f7e-ae7c779d0174")>><span class="new-canvas">[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t2_Node_1]]</span><<else>>[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("b23c38a0-f8da-46f6-8907-4b3e9864cf01", true, 1)>> <<if setup.isCanvasNew("b23c38a0-f8da-46f6-8907-4b3e9864cf01")>><span class="new-canvas">[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t1_Node_1]]</span><<else>>[[Late Night Kitchen->Canvas_activity_late_night_kitchen_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("059b39cb-a627-4c0e-98fc-4a30f3bff6f1", true, 1)>> <<if setup.isCanvasNew("059b39cb-a627-4c0e-98fc-4a30f3bff6f1")>><span class="new-canvas">[[Dinner with Ethan->Canvas_activity_dinner_ethan_t5_Node_1]]</span><<else>>[[Dinner with Ethan->Canvas_activity_dinner_ethan_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("7d3d56ea-bb73-449b-b1d8-8bfd29007d58", true, 1)>> <<if setup.isCanvasNew("7d3d56ea-bb73-449b-b1d8-8bfd29007d58")>><span class="new-canvas">[[Dinner with Ethan->Canvas_activity_dinner_ethan_t4_Node_1]]</span><<else>>[[Dinner with Ethan->Canvas_activity_dinner_ethan_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("72b91eee-7c46-48ab-ae97-06db9a2fd794", true, 1)>> <<if setup.isCanvasNew("72b91eee-7c46-48ab-ae97-06db9a2fd794")>><span class="new-canvas">[[Dinner with Ethan->Canvas_activity_dinner_ethan_t3_Node_1]]</span><<else>>[[Dinner with Ethan->Canvas_activity_dinner_ethan_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("e9207826-c6d9-4a09-a5f3-e4130c5ad2bc", true, 1)>> <<if setup.isCanvasNew("e9207826-c6d9-4a09-a5f3-e4130c5ad2bc")>><span class="new-canvas">[[Dinner with Ethan->Canvas_activity_dinner_ethan_t2_Node_1]]</span><<else>>[[Dinner with Ethan->Canvas_activity_dinner_ethan_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("477d5c97-650d-49bf-9a00-0b93222611e2", true, 1)>> <<if setup.isCanvasNew("477d5c97-650d-49bf-9a00-0b93222611e2")>><span class="new-canvas">[[Dinner with Ethan->Canvas_activity_dinner_ethan_t1_Node_1]]</span><<else>>[[Dinner with Ethan->Canvas_activity_dinner_ethan_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("02360f7c-2c25-41cd-a4ae-d9e938447c08", true, 1)>> <<if setup.isCanvasNew("02360f7c-2c25-41cd-a4ae-d9e938447c08")>><span class="new-canvas">[[Cooking Together->Canvas_activity_cooking_together_t5_Node_1]]</span><<else>>[[Cooking Together->Canvas_activity_cooking_together_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("37348391-17a3-4e3d-9b44-0ca228158524", true, 1)>> <<if setup.isCanvasNew("37348391-17a3-4e3d-9b44-0ca228158524")>><span class="new-canvas">[[Cooking Together->Canvas_activity_cooking_together_t4_Node_1]]</span><<else>>[[Cooking Together->Canvas_activity_cooking_together_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("539a7f90-0877-4a6d-85b8-e11f4f8991e9", true, 1)>> <<if setup.isCanvasNew("539a7f90-0877-4a6d-85b8-e11f4f8991e9")>><span class="new-canvas">[[Cooking Together->Canvas_activity_cooking_together_t3_Node_1]]</span><<else>>[[Cooking Together->Canvas_activity_cooking_together_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("824f28ea-3a40-4dbc-8d26-4baf91102db0", true, 1)>> <<if setup.isCanvasNew("824f28ea-3a40-4dbc-8d26-4baf91102db0")>><span class="new-canvas">[[Cooking Together->Canvas_activity_cooking_together_t2_Node_1]]</span><<else>>[[Cooking Together->Canvas_activity_cooking_together_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("8bdd9b31-acf8-405d-a14a-30b1212398a3", true, 1)>> <<if setup.isCanvasNew("8bdd9b31-acf8-405d-a14a-30b1212398a3")>><span class="new-canvas">[[Cooking Together->Canvas_activity_cooking_together_t1_Node_1]]</span><<else>>[[Cooking Together->Canvas_activity_cooking_together_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "12:00", "14:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("a300e4b5-1773-4d05-9617-c98ca9199611", true, 1)>> <<if setup.isCanvasNew("a300e4b5-1773-4d05-9617-c98ca9199611")>><span class="new-canvas">[[Lunch Together->Canvas_activity_lunch_together_t5_Node_1]]</span><<else>>[[Lunch Together->Canvas_activity_lunch_together_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "12:00", "14:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("5fc3e920-273f-45ac-ba92-9317ceeae930", true, 1)>> <<if setup.isCanvasNew("5fc3e920-273f-45ac-ba92-9317ceeae930")>><span class="new-canvas">[[Lunch Together->Canvas_activity_lunch_together_t4_Node_1]]</span><<else>>[[Lunch Together->Canvas_activity_lunch_together_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "12:00", "14:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("b153b9e7-3d1b-47fc-80f8-c20786cdf0be", true, 1)>> <<if setup.isCanvasNew("b153b9e7-3d1b-47fc-80f8-c20786cdf0be")>><span class="new-canvas">[[Lunch Together->Canvas_activity_lunch_together_t3_Node_1]]</span><<else>>[[Lunch Together->Canvas_activity_lunch_together_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "12:00", "14:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("d2f3b351-39c2-4ae2-be8e-a45aab258739", true, 1)>> <<if setup.isCanvasNew("d2f3b351-39c2-4ae2-be8e-a45aab258739")>><span class="new-canvas">[[Lunch Together->Canvas_activity_lunch_together_t2_Node_1]]</span><<else>>[[Lunch Together->Canvas_activity_lunch_together_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "12:00", "14:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("e20039b6-7886-4214-aeb2-34e96f4aa6fa", true, 1)>> <<if setup.isCanvasNew("e20039b6-7886-4214-aeb2-34e96f4aa6fa")>><span class="new-canvas">[[Lunch Together->Canvas_activity_lunch_together_t1_Node_1]]</span><<else>>[[Lunch Together->Canvas_activity_lunch_together_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("33ddf963-458e-404e-abe9-95a64c3ce300", true, 1)>> <<if setup.isCanvasNew("33ddf963-458e-404e-abe9-95a64c3ce300")>><span class="new-canvas">[[Morning Coffee->Canvas_activity_morning_coffee_t5_Node_1]]</span><<else>>[[Morning Coffee->Canvas_activity_morning_coffee_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("e89e834e-1adc-49d2-b6fa-0d456cf957d7", true, 1)>> <<if setup.isCanvasNew("e89e834e-1adc-49d2-b6fa-0d456cf957d7")>><span class="new-canvas">[[Morning Coffee->Canvas_activity_morning_coffee_t4_Node_1]]</span><<else>>[[Morning Coffee->Canvas_activity_morning_coffee_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("621821ba-98ae-4ae7-84b0-fbeee182593f", true, 1)>> <<if setup.isCanvasNew("621821ba-98ae-4ae7-84b0-fbeee182593f")>><span class="new-canvas">[[Morning Coffee->Canvas_activity_morning_coffee_t3_Node_1]]</span><<else>>[[Morning Coffee->Canvas_activity_morning_coffee_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("055ec2e8-6a21-41b5-b399-18efb7745eda", true, 1)>> <<if setup.isCanvasNew("055ec2e8-6a21-41b5-b399-18efb7745eda")>><span class="new-canvas">[[Morning Coffee->Canvas_activity_morning_coffee_t2_Node_1]]</span><<else>>[[Morning Coffee->Canvas_activity_morning_coffee_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("3ab52809-3b7c-4a0c-8dc0-cd2022f0e8dc", true, 1)>> <<if setup.isCanvasNew("3ab52809-3b7c-4a0c-8dc0-cd2022f0e8dc")>><span class="new-canvas">[[Morning Coffee->Canvas_activity_morning_coffee_t1_Node_1]]</span><<else>>[[Morning Coffee->Canvas_activity_morning_coffee_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("2b22e43e-794e-43ea-a800-6837d324dc0d", true, 1)>> <<if setup.isCanvasNew("2b22e43e-794e-43ea-a800-6837d324dc0d")>><span class="new-canvas">[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t5_Node_1]]</span><<else>>[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("41bc2a64-cec7-47d0-9f45-b1fa206d237b", true, 1)>> <<if setup.isCanvasNew("41bc2a64-cec7-47d0-9f45-b1fa206d237b")>><span class="new-canvas">[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t4_Node_1]]</span><<else>>[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("f8c84bf8-0eb5-40d0-9b34-efd914063f3d", true, 1)>> <<if setup.isCanvasNew("f8c84bf8-0eb5-40d0-9b34-efd914063f3d")>><span class="new-canvas">[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t3_Node_1]]</span><<else>>[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("ef8853bf-9a29-4b7a-8bbd-f9a1856656c2", true, 1)>> <<if setup.isCanvasNew("ef8853bf-9a29-4b7a-8bbd-f9a1856656c2")>><span class="new-canvas">[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t2_Node_1]]</span><<else>>[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("dba6552a-a82f-4f32-a5af-0b378681db25", true, 1)>> <<if setup.isCanvasNew("dba6552a-a82f-4f32-a5af-0b378681db25")>><span class="new-canvas">[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t1_Node_1]]</span><<else>>[[Breakfast with Ethan->Canvas_activity_breakfast_ethan_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "night_before_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("285a83a5-320e-4969-a558-e0fbb69d1827", false, null)>> <<if setup.isCanvasNew("285a83a5-320e-4969-a558-e0fbb69d1827")>><span class="new-canvas">[[Wedding Morning->Canvas_scene_wedding_morning_Node_1]]</span><<else>>[[Wedding Morning->Canvas_scene_wedding_morning_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "07:00", "09:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "first_kiss", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("be2226c6-ae16-4fe1-b960-e037361a6c5f", false, null)>> <<if setup.isCanvasNew("be2226c6-ae16-4fe1-b960-e037361a6c5f")>><span class="new-canvas">[[What Are We Doing->Canvas_scene_what_are_we_doing_Node_1]]</span><<else>>[[What Are We Doing->Canvas_scene_what_are_we_doing_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "old_photos_complete", "operator": "is_true"}, {"type": "trait", "value": 25, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("e2bfbeb9-ebc9-458e-96f5-1a854ad75be7", false, null)>> <<if setup.isCanvasNew("e2bfbeb9-ebc9-458e-96f5-1a854ad75be7")>><span class="new-canvas">[[Sleepless Night->Canvas_scene_sleepless_night_Node_1]]</span><<else>>[[Sleepless Night->Canvas_scene_sleepless_night_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "17:00", "19:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "arrival_complete", "operator": "is_true"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("9da03758-d6d0-4cea-ab7f-c86473348579", false, null)>> <<if setup.isCanvasNew("9da03758-d6d0-4cea-ab7f-c86473348579")>><span class="new-canvas">[[Welcome Home Dinner->Canvas_scene_welcome_dinner_Node_1]]</span><<else>>[[Welcome Home Dinner->Canvas_scene_welcome_dinner_Node_1]]<</if>><br> <</if>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> <strong>Available destinations:</strong><br> [[Backyard & Pool->Location_Backyard_&_Pool]]<<if setup.locationHasNewCanvases("b062fb4f-2615-4e88-a350-c048096f2782")>> <span class="nav-new">!</span><</if>><br> [[Leave Kitchen->Location_Living_Room]]<br> </div>
<h2>Backyard & Pool</h2> <p>Well-maintained backyard with an in-ground pool, lounge chairs, and a covered patio area. Privacy fence ensures neighbors can't see. The pool has underwater lights for night swimming.</p> <<set $player.current_location = "b062fb4f-2615-4e88-a350-c048096f2782">> <<if not $game_state.visited_locations.includes("b062fb4f-2615-4e88-a350-c048096f2782")>> <<set $game_state.visited_locations.push("b062fb4f-2615-4e88-a350-c048096f2782")>> <</if>> <<nobr>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("bb21f5b3-2da9-492e-868d-420e0410a1b3", true, 1)>> <<if setup.isCanvasNew("bb21f5b3-2da9-492e-868d-420e0410a1b3")>><span class="new-canvas">[[Wine & Talk->Canvas_activity_wine_talk_t5_Node_1]]</span><<else>>[[Wine & Talk->Canvas_activity_wine_talk_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("ed02ae76-4628-4e21-81ca-68034f18ff4d", true, 1)>> <<if setup.isCanvasNew("ed02ae76-4628-4e21-81ca-68034f18ff4d")>><span class="new-canvas">[[Wine & Talk->Canvas_activity_wine_talk_t4_Node_1]]</span><<else>>[[Wine & Talk->Canvas_activity_wine_talk_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("8b2415a0-6e95-4b6a-9b98-a03d2687f9f2", true, 1)>> <<if setup.isCanvasNew("8b2415a0-6e95-4b6a-9b98-a03d2687f9f2")>><span class="new-canvas">[[Wine & Talk->Canvas_activity_wine_talk_t3_Node_1]]</span><<else>>[[Wine & Talk->Canvas_activity_wine_talk_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("6d3be5b5-228d-49b4-b2de-0e660517e128", true, 1)>> <<if setup.isCanvasNew("6d3be5b5-228d-49b4-b2de-0e660517e128")>><span class="new-canvas">[[Wine & Talk->Canvas_activity_wine_talk_t2_Node_1]]</span><<else>>[[Wine & Talk->Canvas_activity_wine_talk_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("2989df0a-81ef-4b23-b710-bd989edd0907", true, 1)>> <<if setup.isCanvasNew("2989df0a-81ef-4b23-b710-bd989edd0907")>><span class="new-canvas">[[Wine & Talk->Canvas_activity_wine_talk_t1_Node_1]]</span><<else>>[[Wine & Talk->Canvas_activity_wine_talk_t1_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 90, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("c421f29f-4582-43e4-acba-3499ad09aefa", true, 1)>> <<if setup.isCanvasNew("c421f29f-4582-43e4-acba-3499ad09aefa")>><span class="new-canvas">[[Pool Time->Canvas_activity_pool_time_t5_Node_1]]</span><<else>>[[Pool Time->Canvas_activity_pool_time_t5_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 70, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 89, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("774fd167-ddd5-46f9-9f2e-88bc59f6315f", true, 1)>> <<if setup.isCanvasNew("774fd167-ddd5-46f9-9f2e-88bc59f6315f")>><span class="new-canvas">[[Pool Time->Canvas_activity_pool_time_t4_Node_1]]</span><<else>>[[Pool Time->Canvas_activity_pool_time_t4_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 69, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("2ac679db-bf7e-48ca-9fd3-5f9a0cdc33ef", true, 1)>> <<if setup.isCanvasNew("2ac679db-bf7e-48ca-9fd3-5f9a0cdc33ef")>><span class="new-canvas">[[Pool Time->Canvas_activity_pool_time_t3_Node_1]]</span><<else>>[[Pool Time->Canvas_activity_pool_time_t3_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 30, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 49, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("73621d16-03fe-437c-b2e9-a206a140b7bf", true, 1)>> <<if setup.isCanvasNew("73621d16-03fe-437c-b2e9-a206a140b7bf")>><span class="new-canvas">[[Pool Time->Canvas_activity_pool_time_t2_Node_1]]</span><<else>>[[Pool Time->Canvas_activity_pool_time_t2_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "trait", "value": 29, "npc_id": "npc_ethan", "subject": "npc", "operator": "lte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("3a457bc9-99be-45f6-bfd9-fb6b7643ddf4", true, 1)>> <<if setup.isCanvasNew("3a457bc9-99be-45f6-bfd9-fb6b7643ddf4")>><span class="new-canvas">[[Pool Time->Canvas_activity_pool_time_t1_Node_1]]</span><<else>>[[Pool Time->Canvas_activity_pool_time_t1_Node_1]]<</if>><br> <</if>> <<if setup.canTriggerCanvas("5e176181-e161-43e7-8dda-fcacf805e90b", true, null)>> <<if setup.isCanvasNew("5e176181-e161-43e7-8dda-fcacf805e90b")>><span class="new-canvas">[[Swim Alone->Canvas_solo_swim_Node_1]]</span><<else>>[[Swim Alone->Canvas_solo_swim_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "19:00", "22:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "confession_complete", "operator": "is_true"}, {"type": "trait", "value": 55, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("fbaa6a2a-dede-4487-ac05-6e9ad00f97c5", false, null)>> <<if setup.isCanvasNew("fbaa6a2a-dede-4487-ac05-6e9ad00f97c5")>><span class="new-canvas">[[Almost Kiss->Canvas_scene_almost_kiss_Node_1]]</span><<else>>[[Almost Kiss->Canvas_scene_almost_kiss_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "22:00", "01:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "the_couch_complete", "operator": "is_true"}, {"type": "trait", "value": 50, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}, {"type": "trait", "value": 40, "subject": "player", "operator": "gte", "trait_key": "boldness"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("f5b8ddd0-5ea4-4f82-af81-15cbe64057ff", false, null)>> <<if setup.isCanvasNew("f5b8ddd0-5ea4-4f82-af81-15cbe64057ff")>><span class="new-canvas">[[The Confession->Canvas_scene_confession_Node_1]]</span><<else>>[[The Confession->Canvas_scene_confession_Node_1]]<</if>><br> <</if>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> <strong>Available destinations:</strong><br> [[Garage->Location_Garage]]<<if setup.locationHasNewCanvases("4dc5f240-c5a8-40d1-8997-41309fc625de")>> <span class="nav-new">!</span><</if>><br> [[Leave Backyard & Pool->Location_Kitchen]]<br> </div>
<h2>Garage</h2> <p>Attached garage used partly for storage. Old boxes contain family memories—photo albums, childhood items, mementos from when you were growing up together.</p> <<set $player.current_location = "4dc5f240-c5a8-40d1-8997-41309fc625de">> <<if not $game_state.visited_locations.includes("4dc5f240-c5a8-40d1-8997-41309fc625de")>> <<set $game_state.visited_locations.push("4dc5f240-c5a8-40d1-8997-41309fc625de")>> <</if>> <<nobr>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "madison_arrived", "operator": "is_true"}, {"type": "trait", "value": 85, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("fc57410a-9ac2-40d5-a14f-f94845cc34ce", false, null)>> <<if setup.isCanvasNew("fc57410a-9ac2-40d5-a14f-f94845cc34ce")>><span class="new-canvas">[[Stolen Moment->Canvas_scene_stolen_moment_Node_1]]</span><<else>>[[Stolen Moment->Canvas_scene_stolen_moment_Node_1]]<</if>><br> <</if>> <<if setup.isScheduleActive([], "14:00", "17:00") and setup.triggerConditionsSatisfied({"items": [{"type": "flag", "subject": "player", "flag_key": "welcome_dinner_complete", "operator": "is_true"}, {"type": "trait", "value": 15, "npc_id": "npc_ethan", "subject": "npc", "operator": "gte", "trait_key": "affection"}], "logic": "AND", "version": "1.0"}) and setup.canTriggerCanvas("b133cce8-dae7-4c11-a1db-d75552e256c8", false, null)>> <<if setup.isCanvasNew("b133cce8-dae7-4c11-a1db-d75552e256c8")>><span class="new-canvas">[[Finding Old Photos->Canvas_scene_old_photos_Node_1]]</span><<else>>[[Finding Old Photos->Canvas_scene_old_photos_Node_1]]<</if>><br> <</if>> <</nobr>> <!-- Hierarchical Navigation --> <div class="location-navigation"> [[Leave Garage->Location_Backyard_&_Pool]]<br> </div> <!-- STORY CANVAS PASSAGES -->
<p>Your door opens behind you. Or his. You don't separate long enough to notice which.</p><video src="./media/activities/goodnight_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "38d240e2-e18b-4cf4-b77c-a6b85a3a6765">> <<set $game_state.current_node = "ef1f3919-541d-4ab0-b005-214cbffd9883">> <<script>>setup.markCanvasTriggered("38d240e2-e18b-4cf4-b77c-a6b85a3a6765");<</script>> <<script>>advanceTime(120);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[No one says goodnight->Location_Upstairs_Hallway]]
<p>He kisses you in the hallway. Presses you against your door.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> We should stop.</div><p>Neither stops.</p><img src="./media/activities/goodnight_t4.gif" alt="Hallway kiss. Against the door. Neither stops." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "a39d2179-f7e6-4ba6-b1e3-f146bb812b71">> <<set $game_state.current_node = "50675d85-c52c-44b1-a5c4-707eee78e359">> <<script>>setup.markCanvasTriggered("a39d2179-f7e6-4ba6-b1e3-f146bb812b71");<</script>> <<script>>advanceTime(20);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Eventually part->Location_Upstairs_Hallway]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> What if I can't sleep?</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Then come find me.</div><p>Dangerous invitation left hanging.</p><img src="./media/activities/goodnight_t3.gif" alt="Can't sleep? Come find me. Dangerous invitation." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "8041f658-eee5-434f-a24f-95533104b894">> <<set $game_state.current_node = "faafa946-aa1f-4d32-bb53-d4a98aa7f307">> <<script>>setup.markCanvasTriggered("8041f658-eee5-434f-a24f-95533104b894");<</script>> <<script>>advanceTime(10);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Go to your room->Location_Upstairs_Hallway]]
<p>The hug lasts too long. He pulls back, looks at you. Moment stretches.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Goodnight.</div><p>Reluctant release.</p><img src="./media/activities/goodnight_t2.gif" alt="Hug too long. Looks at you. Reluctant release." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "aee10b91-48f4-4f2c-b8b4-b4ff83d8616f">> <<set $game_state.current_node = "1dba6c4a-f494-4b47-bcfd-fbc9718ef807">> <<script>>setup.markCanvasTriggered("aee10b91-48f4-4f2c-b8b4-b4ff83d8616f");<</script>> <<script>>advanceTime(10);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Go to your room->Location_Upstairs_Hallway]]
<p>Quick goodnight at bedroom doors. Sibling hug, peck on cheek.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Sleep well.</div><img src="./media/activities/goodnight_t1.jpg" alt="Quick hug. Peck on cheek. Sleep well." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "09b332a6-eab6-4d97-99a3-6561abc42d6c">> <<set $game_state.current_node = "d5ff45c6-70be-4130-bb35-bba3f125fa27">> <<script>>setup.markCanvasTriggered("09b332a6-eab6-4d97-99a3-6561abc42d6c");<</script>> <<script>>advanceTime(10);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Go to your room->Location_Upstairs_Hallway]]
<p>No one else is awake. No one will know. The kitchen counter, the floor, wherever.</p><video src="./media/activities/late_night_kitchen_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "73cbe973-6aea-457e-99e9-ea46f429d150">> <<set $game_state.current_node = "79e13e85-5ce4-4a58-8613-a75aa29eacac">> <<script>>setup.markCanvasTriggered("73cbe973-6aea-457e-99e9-ea46f429d150");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Go to bed together->Location_Kitchen]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I keep thinking about you.</div><p>Whispered confession. You set down your glass. Cross to him.</p><img src="./media/activities/late_night_kitchen_t4.gif" alt="Whispered confession. Crossing to him." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4429251c-f1ed-4dcd-a04d-975f344d695e">> <<set $game_state.current_node = "b72558cf-4127-407e-bfc6-04d84f49191c">> <<script>>setup.markCanvasTriggered("4429251c-f1ed-4dcd-a04d-975f344d695e");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Eventually go to bed->Location_Kitchen]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Can't sleep either?</div><p>Loaded question. Both know why. The kitchen feels electric at 1 AM.</p><img src="./media/activities/late_night_kitchen_t3.gif" alt="Can't sleep. Both know why. Electric." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "7073455c-e506-42c3-9640-040428d6d7b8">> <<set $game_state.current_node = "52dd349c-e659-4abc-b070-6417d199179b">> <<script>>setup.markCanvasTriggered("7073455c-e506-42c3-9640-040428d6d7b8");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Go back to bed->Location_Kitchen]]
<p>He's in just boxers. You're in a thin nightgown. Pretending not to notice each other's state of undress.</p><img src="./media/activities/late_night_kitchen_t2.gif" alt="Boxers. Nightgown. Pretending not to notice." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "21935a2f-f38a-48e6-9f7e-ae7c779d0174">> <<set $game_state.current_node = "d3aad2f1-2e1e-4057-a0d6-6a225f5586ca">> <<script>>setup.markCanvasTriggered("21935a2f-f38a-48e6-9f7e-ae7c779d0174");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Go back to bed->Location_Kitchen]]
<p>Both couldn't sleep. Midnight snack. Comfortable silence of insomniacs.</p><img src="./media/activities/late_night_kitchen_t1.jpg" alt="Midnight snacks. Comfortable silence." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "b23c38a0-f8da-46f6-8907-4b3e9864cf01">> <<set $game_state.current_node = "3b092d94-2384-4d80-87ec-f403e66842a8">> <<script>>setup.markCanvasTriggered("b23c38a0-f8da-46f6-8907-4b3e9864cf01");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Go back to bed->Location_Kitchen]]
<p>The patio furniture is more private than the living room. Under the stars.</p><video src="./media/activities/wine_talk_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "bb21f5b3-2da9-492e-868d-420e0410a1b3">> <<set $game_state.current_node = "dc1418d7-964b-4595-90ee-c55f781d3ea3">> <<script>>setup.markCanvasTriggered("bb21f5b3-2da9-492e-868d-420e0410a1b3");<</script>> <<script>>advanceTime(120);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Eventually go inside->Location_Backyard_&_Pool]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> We shouldn't.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I know.</div><p>But you're already leaning in. Wine-soft lips. First kiss happens here.</p><img src="./media/activities/wine_talk_t4.gif" alt="Patio makeout - straddling him on the chair, grinding in his lap, hands under clothes, about to go further" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "ed02ae76-4628-4e21-81ca-68034f18ff4d">> <<set $game_state.current_node = "b2e55ac5-e45c-46f7-8490-a9c224e53976">> <<script>>setup.markCanvasTriggered("ed02ae76-4628-4e21-81ca-68034f18ff4d");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Head inside together->Location_Backyard_&_Pool]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I need to tell you something.</div><p>Liquid courage. Admissions that can't be taken back.</p><img src="./media/activities/wine_talk_t3.gif" alt="Liquid courage. Confessions." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "8b2415a0-6e95-4b6a-9b98-a03d2687f9f2">> <<set $game_state.current_node = "588b2594-7e28-4e4c-98ce-859ee2cca3cf">> <<script>>setup.markCanvasTriggered("8b2415a0-6e95-4b6a-9b98-a03d2687f9f2");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Head inside->Location_Backyard_&_Pool]]
<p>Second bottle. Conversation turns to relationships.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Do you ever think about...?</div><p>He doesn't finish.</p><img src="./media/activities/wine_talk_t2.gif" alt="Second bottle. Unfinished questions." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "6d3be5b5-228d-49b4-b2de-0e660517e128">> <<set $game_state.current_node = "9dc45811-d969-4f4b-b9d1-e3f6d49222b7">> <<script>>setup.markCanvasTriggered("6d3be5b5-228d-49b4-b2de-0e660517e128");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Head inside->Location_Backyard_&_Pool]]
<p>A glass of wine on the patio. Catching up on years apart. Easy conversation, starlit sky.</p><img src="./media/activities/wine_talk_t1.jpg" alt="Patio wine. Catching up. Stars." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "2989df0a-81ef-4b23-b710-bd989edd0907">> <<set $game_state.current_node = "56194a7a-5215-4042-bac4-0d7b1a0cb0f2">> <<script>>setup.markCanvasTriggered("2989df0a-81ef-4b23-b710-bd989edd0907");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Head inside->Location_Backyard_&_Pool]]
<p>The movie's been on pause for twenty minutes. The blanket hides everything. Then it doesn't need to.</p><img src="./media/activities/movie_night_t5.gif" alt="Couch sex - spooning position, he enters from behind while lying together, slow intimate thrusting under blanket" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "ad75137d-989d-4249-b993-1e7b17fadeb5">> <<set $game_state.current_node = "345a47ab-7724-4d87-bf2b-0410c559a62a">> <<script>>setup.markCanvasTriggered("ad75137d-989d-4249-b993-1e7b17fadeb5");<</script>> <<script>>advanceTime(150);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Eventually turn off the TV->Location_Living_Room]]
<p>Under the blanket, hands find each other. Then wander. The movie becomes background noise.</p><video src="./media/activities/movie_night_t4.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "3557832c-8856-4f2f-a4d2-585a1c75efaa">> <<set $game_state.current_node = "e7233200-2cae-4270-93cd-5dc189d3049c">> <<script>>setup.markCanvasTriggered("3557832c-8856-4f2f-a4d2-585a1c75efaa");<</script>> <<script>>advanceTime(120);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Movie ends eventually->Location_Living_Room]]
<p>Your head on his shoulder. His arm around you.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Just like we used to.</div><p>But it doesn't feel like it used to.</p><img src="./media/activities/movie_night_t3.gif" alt="Head on shoulder. Arm around you. Different now." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "bce73abd-d2c3-4e33-be56-72c5e7c47fc8">> <<set $game_state.current_node = "cdccb75d-7612-4c4a-a422-b37cdc169042">> <<script>>setup.markCanvasTriggered("bce73abd-d2c3-4e33-be56-72c5e7c47fc8");<</script>> <<script>>advanceTime(120);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Movie ends->Location_Living_Room]]
<p>You get 'cold,' need the blanket. Scoot closer. Your thighs touch under the blanket. Neither moves away.</p><img src="./media/activities/movie_night_t2.jpg" alt="Blanket. Scooting closer. Thighs touching." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "3aeb65fd-0961-4fcd-97ea-08e20d628f59">> <<set $game_state.current_node = "ab5e9dd9-e9cb-4f42-ad1b-010dd6e624d5">> <<script>>setup.markCanvasTriggered("3aeb65fd-0961-4fcd-97ea-08e20d628f59");<</script>> <<script>>advanceTime(120);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Movie ends->Location_Living_Room]]
<p>Watching a comedy on the big couch, popcorn between you. Sibling movie night, like old times.</p><img src="./media/activities/movie_night_t1.gif" alt="Sibling movie night. Popcorn. Comfortable." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "71a09dc8-ff6d-49d1-8f7f-9503785208a3">> <<set $game_state.current_node = "ba0be0fa-a0ab-4b6c-aaaf-03ed27bbf2df">> <<script>>setup.markCanvasTriggered("71a09dc8-ff6d-49d1-8f7f-9503785208a3");<</script>> <<script>>advanceTime(120);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Movie ends->Location_Living_Room]]
<p>The table gets cleared in one sweep.</p><video src="./media/activities/dinner_ethan_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "059b39cb-a627-4c0e-98fc-4a30f3bff6f1">> <<set $game_state.current_node = "8818eb41-8b6b-4746-b45f-448b9733036f">> <<script>>setup.markCanvasTriggered("059b39cb-a627-4c0e-98fc-4a30f3bff6f1");<</script>> <<script>>advanceTime(75);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Eat later->Location_Kitchen]]
<p>Under the table, your foot finds his leg. Works its way up. He grips the table edge.</p><img src="./media/activities/dinner_ethan_t4.gif" alt="Under table touching - her hand on his thigh moving higher, his hand between her legs, trying to stay composed" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "7d3d56ea-bb73-449b-b1d8-8bfd29007d58">> <<set $game_state.current_node = "4e3a9f62-b953-4882-978e-1ba4708ebeb1">> <<script>>setup.markCanvasTriggered("7d3d56ea-bb73-449b-b1d8-8bfd29007d58");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish dinner->Location_Kitchen]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> You know why.</div><p>His fork stops midway. The air changes.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> We should talk about it.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Should we?</div><img src="./media/activities/dinner_ethan_t3.jpg" alt="Acknowledgment. The air changes." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "72b91eee-7c46-48ab-ae97-06db9a2fd794">> <<set $game_state.current_node = "5b4c6451-e7fa-4253-b0af-0e5a756abe8b">> <<script>>setup.markCanvasTriggered("72b91eee-7c46-48ab-ae97-06db9a2fd794");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Clear the dishes->Location_Kitchen]]
<p>Wine with dinner. Conversation gets more personal.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Why'd you really stay away so long?</div><p>Loaded silence.</p><img src="./media/activities/dinner_ethan_t2.jpg" alt="Wine. Personal questions. Loaded silence." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "e9207826-c6d9-4a09-a5f3-e4130c5ad2bc">> <<set $game_state.current_node = "50a1f800-81cf-4ddd-8cf8-10d2ba2a6eb9">> <<script>>setup.markCanvasTriggered("e9207826-c6d9-4a09-a5f3-e4130c5ad2bc");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Clear the dishes->Location_Kitchen]]
<p>Pleasant dinner conversation. He asks about your dating life, you deflect. Normal family dinner.</p><img src="./media/activities/dinner_ethan_t1.jpg" alt="Normal family dinner conversation." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "477d5c97-650d-49bf-9a00-0b93222611e2">> <<set $game_state.current_node = "9ea57d29-8197-4534-84c2-dabed5fd797d">> <<script>>setup.markCanvasTriggered("477d5c97-650d-49bf-9a00-0b93222611e2");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Clear the dishes->Location_Kitchen]]
<p>Dinner burns. Neither cares. The kitchen counter has many uses.</p><img src="./media/activities/cooking_together_t5.webp" alt="Kitchen sex from behind - bent over counter, doggy style, still partially clothed, urgent can't-wait energy" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "02360f7c-2c25-41cd-a4ae-d9e938447c08">> <<set $game_state.current_node = "9418cdea-92a5-434b-98c2-92cfb4a79b42">> <<script>>setup.markCanvasTriggered("02360f7c-2c25-41cd-a4ae-d9e938447c08");<</script>> <<script>>advanceTime(75);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Order takeout->Location_Kitchen]]
<p>He wipes sauce from your lip with his thumb. Lingers. You catch his hand, keep it there.</p><video src="./media/activities/cooking_together_t4.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "37348391-17a3-4e3d-9b44-0ca228158524">> <<set $game_state.current_node = "ba199574-fcee-4cee-bed8-36e6101f2947">> <<script>>setup.markCanvasTriggered("37348391-17a3-4e3d-9b44-0ca228158524");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Eventually eat->Location_Kitchen]]
<p>Taste-testing from the same spoon. Feeding each other bites.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> How's that?</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Perfect.</div><p>Not talking about the food.</p><img src="./media/activities/cooking_together_t3.gif" alt="Feeding each other. Not about the food." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "539a7f90-0877-4a6d-85b8-e11f4f8991e9">> <<set $game_state.current_node = "c0f9ddbe-7224-4568-91f2-e8064a115dab">> <<script>>setup.markCanvasTriggered("539a7f90-0877-4a6d-85b8-e11f4f8991e9");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Serve dinner->Location_Kitchen]]
<p>He guides your hands while you chop. Standing too close.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> You're doing it wrong. Show me then.</div><img src="./media/activities/cooking_together_t2.jpg" alt="Guiding hands. Too close." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "824f28ea-3a40-4dbc-8d26-4baf91102db0">> <<set $game_state.current_node = "d6e8ad69-0864-4999-84f0-04a719586203">> <<script>>setup.markCanvasTriggered("824f28ea-3a40-4dbc-8d26-4baf91102db0");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Serve dinner->Location_Kitchen]]
<p>Making mom's old recipe together. Nostalgia, laughter over shared memories. Kitchen teamwork.</p><img src="./media/activities/cooking_together_t1.jpg" alt="Cooking together, sharing memories." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "8bdd9b31-acf8-405d-a14a-30b1212398a3">> <<set $game_state.current_node = "0fb62179-1a7b-465d-b62d-758fadbe3435">> <<script>>setup.markCanvasTriggered("8bdd9b31-acf8-405d-a14a-30b1212398a3");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Serve dinner->Location_Kitchen]]
<p>The wedding planning materials get swept to the floor.</p><video src="./media/activities/wedding_planning_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "409aa9e5-c940-4640-8408-91041d4e7811">> <<set $game_state.current_node = "00c6a697-5dc5-4019-9a34-27c6048daf14">> <<script>>setup.markCanvasTriggered("409aa9e5-c940-4640-8408-91041d4e7811");<</script>> <<script>>advanceTime(75);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Pick up the papers later->Location_Living_Room]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I don't know if I can do this.</div><p>He's not talking about the seating chart. You take his hand.</p><img src="./media/activities/wedding_planning_t4.gif" alt="Emotional makeout - tears and kisses, holding each other tight, his hand up her skirt, her hand down his pants" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "2ab37e92-9d1b-4438-a17a-59b8b5a6cba3">> <<set $game_state.current_node = "61ec370e-fce5-47fc-bd61-c08cca9d4a46">> <<script>>setup.markCanvasTriggered("2ab37e92-9d1b-4438-a17a-59b8b5a6cba3");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Comfort him->Location_Living_Room]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> What would your perfect wedding look like?</div><p>Dangerous question. His eyes meet yours. Long pause.</p><img src="./media/activities/wedding_planning_t3.gif" alt="Dangerous question. Loaded eye contact." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "b8f87c2e-e5f3-40eb-940e-7a8dda96b944">> <<set $game_state.current_node = "7d6da4ec-1a76-4933-bdbf-f888def4f3ca">> <<script>>setup.markCanvasTriggered("b8f87c2e-e5f3-40eb-940e-7a8dda96b944");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Change the subject->Location_Living_Room]]
<p>He vents about wedding stress. You listen. Your hands touch over invitation samples. He doesn't pull away.</p><img src="./media/activities/wedding_planning_t2.jpg" alt="Venting about stress. Hands touching over invitations." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "769fa786-16b6-4d36-b3af-2b61e2a22f19">> <<set $game_state.current_node = "4a11deba-9d1a-4f75-bcc1-ed28f90cb173">> <<script>>setup.markCanvasTriggered("769fa786-16b6-4d36-b3af-2b61e2a22f19");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish helping->Location_Living_Room]]
<p>Looking through seating charts, helping with RSVPs. You're being a good sister. Wedding talk is safe.</p><img src="./media/activities/wedding_planning_t1.jpg" alt="Helpful sister mode. Seating charts and RSVPs." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "a08fa545-9646-4033-b22a-2a6b94bec46c">> <<set $game_state.current_node = "12b19896-2973-44eb-a8be-5a068ef52e7b">> <<script>>setup.markCanvasTriggered("a08fa545-9646-4033-b22a-2a6b94bec46c");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish helping->Location_Living_Room]]
<p>The pool lounger is sturdier than it looks. Or the pool itself—water provides interesting possibilities.</p><video src="./media/activities/pool_time_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "c421f29f-4582-43e4-acba-3499ad09aefa">> <<set $game_state.current_node = "e7a3e649-5f18-4c8c-bbfb-171139404445">> <<script>>setup.markCanvasTriggered("c421f29f-4582-43e4-acba-3499ad09aefa");<</script>> <<script>>advanceTime(120);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Eventually dry off->Location_Backyard_&_Pool]]
<p>Night swimming. Underwater lights. He pulls you close.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Anyone could see us.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> No they can't.</div><img src="./media/activities/pool_time_t4.gif" alt="Night swimming. Underwater lights. Hands exploring beneath the surface." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "774fd167-ddd5-46f9-9f2e-88bc59f6315f">> <<set $game_state.current_node = "71cbac64-7a85-479e-b929-6d58856593b5">> <<script>>setup.markCanvasTriggered("774fd167-ddd5-46f9-9f2e-88bc59f6315f");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Get out of the pool->Location_Backyard_&_Pool]]
<p>Playful chicken fights, dunking each other. Bodies pressed together underwater. Legs wrapped around him for 'balance.'</p><img src="./media/activities/pool_time_t3.gif" alt="Pool wrestling. Bodies pressed together. Wrapped legs." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "2ac679db-bf7e-48ca-9fd3-5f9a0cdc33ef">> <<set $game_state.current_node = "baac5eb8-2536-48e9-a5cb-61ab603cbc5b">> <<script>>setup.markCanvasTriggered("2ac679db-bf7e-48ca-9fd3-5f9a0cdc33ef");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Dry off->Location_Backyard_&_Pool]]
<p>You're in a bikini now. He offers to put sunscreen on your back. His hands linger.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> You missed a spot.</div><img src="./media/activities/pool_time_t2.jpg" alt="Bikini. Sunscreen application. Lingering hands." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "73621d16-03fe-437c-b2e9-a206a140b7bf">> <<set $game_state.current_node = "6a27dc6d-bacd-4b4e-a71a-d108241cb55a">> <<script>>setup.markCanvasTriggered("73621d16-03fe-437c-b2e9-a206a140b7bf");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Dry off->Location_Backyard_&_Pool]]
<p>Swimming laps, lounging on chairs. You're in a modest one-piece. He tries not to look. Sibling pool day.</p><img src="./media/activities/pool_time_t1.jpg" alt="Casual swimming. Normal sibling pool day." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "3a457bc9-99be-45f6-bfd9-fb6b7643ddf4">> <<set $game_state.current_node = "1aae9f89-95ae-4edc-8134-891f77ad34c3">> <<script>>setup.markCanvasTriggered("3a457bc9-99be-45f6-bfd9-fb6b7643ddf4");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 4.0, true, null);setup.showEffectNotification();<</script>> [[Dry off->Location_Backyard_&_Pool]]
<p>The breakfast bar sees more action than breakfast.</p><video src="./media/activities/lunch_together_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "a300e4b5-1773-4d05-9617-c98ca9199611">> <<set $game_state.current_node = "d9387650-7406-4b31-aa0b-cbc745cef2de">> <<script>>setup.markCanvasTriggered("a300e4b5-1773-4d05-9617-c98ca9199611");<</script>> <<script>>advanceTime(75);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Have lunch later->Location_Kitchen]]
<p>Food forgotten. He's standing between your legs as you sit on the counter.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> We shouldn't.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I know.</div><video src="./media/activities/lunch_together_t4.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "5fc3e920-273f-45ac-ba92-9317ceeae930">> <<set $game_state.current_node = "bb848c34-d129-4b47-9c9d-5be2fb20167c">> <<script>>setup.markCanvasTriggered("5fc3e920-273f-45ac-ba92-9317ceeae930");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Eventually eat->Location_Kitchen]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Remember when we used to sneak extra dessert?</div><p>Shared conspiracy. He offers you a bite from his fork. Intimate gesture.</p><img src="./media/activities/lunch_together_t3.jpg" alt="Feeding each other. Shared memories." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "b153b9e7-3d1b-47fc-80f8-c20786cdf0be">> <<set $game_state.current_node = "8c7514fe-0e1a-49b1-be6c-a84902f9ca2f">> <<script>>setup.markCanvasTriggered("b153b9e7-3d1b-47fc-80f8-c20786cdf0be");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish lunch->Location_Kitchen]]
<p>He makes your favorite—remembered after all these years. Your knees touch under the breakfast bar. Neither moves away.</p><img src="./media/activities/lunch_together_t2.gif" alt="He remembered your favorite. Knees touching." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "d2f3b351-39c2-4ae2-be8e-a45aab258739">> <<set $game_state.current_node = "351a9c0e-e5a4-4379-889b-72dd1a9371cd">> <<script>>setup.markCanvasTriggered("d2f3b351-39c2-4ae2-be8e-a45aab258739");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish lunch->Location_Kitchen]]
<p>Making sandwiches together, chatting about your life, his job. Surface-level catch-up.</p><img src="./media/activities/lunch_together_t1.gif" alt="Casual lunch prep, easy conversation." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "e20039b6-7886-4214-aeb2-34e96f4aa6fa">> <<set $game_state.current_node = "5e68c576-92d3-4484-828e-531f326e7180">> <<script>>setup.markCanvasTriggered("e20039b6-7886-4214-aeb2-34e96f4aa6fa");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish lunch->Location_Kitchen]]
<p>The laundry can wait. The couch is right there.</p><video src="./media/activities/helping_chores_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "71bafae7-a820-43df-ae90-d0cf20306c01">> <<set $game_state.current_node = "330ea15c-4ab0-4c5e-824e-773db093b71e">> <<script>>setup.markCanvasTriggered("71bafae7-a820-43df-ae90-d0cf20306c01");<</script>> <<script>>advanceTime(75);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Get back to chores later->Location_Living_Room]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> You missed a spot.</div><p>He reaches around you at the sink. Stays there. Hands sliding to your hips.</p><img src="./media/activities/helping_chores_t4.webp" alt="Couch makeout - lying on top of each other, dry humping through clothes, hands everywhere, breathing hard" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "52b8fa8c-bdec-441f-a02b-38678ad6d3d1">> <<set $game_state.current_node = "38bbd8d6-1f40-47fb-8584-b717374ec6e3">> <<script>>setup.markCanvasTriggered("52b8fa8c-bdec-441f-a02b-38678ad6d3d1");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Eventually finish->Location_Living_Room]]
<p>Playful flicking with dish towels. He chases you around the kitchen island. Catches you. Both breathing hard.</p><img src="./media/activities/helping_chores_t3.gif" alt="Playful chase. Caught. Breathless." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "64e060ee-617f-4eab-b2ff-105075f0e437">> <<set $game_state.current_node = "99e525fc-019c-4a96-a09e-bd8bb52c9a1c">> <<script>>setup.markCanvasTriggered("64e060ee-617f-4eab-b2ff-105075f0e437");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finish chores->Location_Living_Room]]
<p>You hold up one of Madison's items. Awkward moment. Then one of his shirts—you hold it to your nose.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Still use the same detergent.</div><img src="./media/activities/helping_chores_t2.jpg" alt="Intimate moments with laundry. Familiar scents." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "3a9eea3d-5353-4f8d-b721-8ad04ddafb3a">> <<set $game_state.current_node = "5bfa2903-9fe1-4005-b7dc-3631ecac0775">> <<script>>setup.markCanvasTriggered("3a9eea3d-5353-4f8d-b721-8ad04ddafb3a");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finish chores->Location_Living_Room]]
<p>You help fold laundry and clean up. Domestic teamwork, easy conversation about old times.</p><img src="./media/activities/helping_chores_t1.jpg" alt="Folding laundry together, casual conversation." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "18dd23b7-00c0-4faf-8e6a-6a10910bbac7">> <<set $game_state.current_node = "92170198-f0e6-4507-bbec-6be0547ccf92">> <<script>>setup.markCanvasTriggered("18dd23b7-00c0-4faf-8e6a-6a10910bbac7");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finish chores->Location_Living_Room]]
<p>The coffee table works just as well as the breakfast bar.</p><video src="./media/activities/morning_coffee_t5.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "33ddf963-458e-404e-abe9-95a64c3ce300">> <<set $game_state.current_node = "00d418ed-cb3b-4c31-987a-304b198261e7">> <<script>>setup.markCanvasTriggered("33ddf963-458e-404e-abe9-95a64c3ce300");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Eventually have coffee->Location_Kitchen]]
<p>You 'accidentally' spill coffee on your shirt. His eyes follow as you dab at it. He offers to help.</p><video src="./media/activities/morning_coffee_t4.webm" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "e89e834e-1adc-49d2-b6fa-0d456cf957d7">> <<set $game_state.current_node = "cf7c4a72-65ff-4ada-a7c9-9a7782a889ea">> <<script>>setup.markCanvasTriggered("e89e834e-1adc-49d2-b6fa-0d456cf957d7");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Clean up->Location_Kitchen]]
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> You always looked cute in the morning.</div><p>Did he just say that out loud?</p><img src="./media/activities/morning_coffee_t3.gif" alt="Slipped compliment. Charged silence." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "621821ba-98ae-4ae7-84b0-fbeee182593f">> <<set $game_state.current_node = "71148faf-d4cd-485f-a18f-05e24f6e581b">> <<script>>setup.markCanvasTriggered("621821ba-98ae-4ae7-84b0-fbeee182593f");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finish coffee->Location_Kitchen]]
<p>Sleepy morning intimacy. He's shirtless, you're in a thin robe. Eyes wander, quickly corrected.</p><img src="./media/activities/morning_coffee_t2.jpg" alt="State of undress. Lingering looks over coffee." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "055ec2e8-6a21-41b5-b399-18efb7745eda">> <<set $game_state.current_node = "0096f229-aeb4-41ba-a95b-1797f937b2f5">> <<script>>setup.markCanvasTriggered("055ec2e8-6a21-41b5-b399-18efb7745eda");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finish coffee->Location_Kitchen]]
<p>Quiet morning coffee together, both still waking up. Comfortable silence of family.</p><img src="./media/activities/morning_coffee_t1.jpg" alt="Sleepy morning comfort. Easy silence." style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "3ab52809-3b7c-4a0c-8dc0-cd2022f0e8dc">> <<set $game_state.current_node = "111a43a8-b237-436c-a7df-645a9e15da08">> <<script>>setup.markCanvasTriggered("3ab52809-3b7c-4a0c-8dc0-cd2022f0e8dc");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finish coffee->Location_Kitchen]]
<p>Morning hunger isn't for food. He lifts you onto the counter. Breakfast gets cold.</p><img src="./media/activities/breakfast_ethan_t5.webp" alt="Kitchen counter sex - she sits on edge, legs wrapped around him, missionary position, passionate morning energy, both finish" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "2b22e43e-794e-43ea-a800-6837d324dc0d">> <<set $game_state.current_node = "fe66b5d4-f916-4462-b2b1-7770e526fe27">> <<script>>setup.markCanvasTriggered("2b22e43e-794e-43ea-a800-6837d324dc0d");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Eventually get to breakfast->Location_Kitchen]]
<p>He comes up behind you at the counter, reaching past you for something. He doesn't step back immediately.</p><img src="./media/activities/breakfast_ethan_t4.gif" alt="Kitchen makeout - against counter, his hands inside her robe, her hand rubbing his bulge through pants, grinding, heavy breathing" style="max-width:100%;height:auto;border-radius:8px;" /><p>His breath on your neck. Neither of you moves.</p> <<set $game_state.current_canvas = "41bc2a64-cec7-47d0-9f45-b1fa206d237b">> <<set $game_state.current_node = "db16cada-1500-4863-a3d2-1971938a152c">> <<script>>setup.markCanvasTriggered("41bc2a64-cec7-47d0-9f45-b1fa206d237b");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Eventually eat->Location_Kitchen]]
<p>You catch him watching you stretch as you reach for the coffee. He quickly looks away, ears red.</p><img src="./media/activities/breakfast_ethan_t3.gif" alt="He catches himself staring. You take your time getting things from high shelves. The kitchen feels smaller." style="max-width:100%;height:auto;border-radius:8px;" /><p>You take your time getting things from the high shelves. The kitchen feels smaller than it used to.</p> <<set $game_state.current_canvas = "f8c84bf8-0eb5-40d0-9b34-efd914063f3d">> <<set $game_state.current_node = "fee4c760-1a9a-46b3-a9c6-99671a9a790a">> <<script>>setup.markCanvasTriggered("f8c84bf8-0eb5-40d0-9b34-efd914063f3d");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish breakfast->Location_Kitchen]]
<p>Ethan looks up when you enter, his eyes lingering on your sleep clothes just a moment too long.</p><p>He makes you coffee without asking how you take it—he remembers.</p><img src="./media/activities/breakfast_ethan_t2.jpg" alt="Eyes lingering on sleep clothes. Making coffee the way you like it without asking. Fingers brush passing the mug." style="max-width:100%;height:auto;border-radius:8px;" /><p>Your fingers brush as he hands you the mug. Neither of you pulls away quickly.</p> <<set $game_state.current_canvas = "ef8853bf-9a29-4b7a-8bbd-f9a1856656c2">> <<set $game_state.current_node = "9c17b645-a9e3-4974-82b0-c3601a73b3f2">> <<script>>setup.markCanvasTriggered("ef8853bf-9a29-4b7a-8bbd-f9a1856656c2");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish breakfast->Location_Kitchen]]
<p>Ethan is in the kitchen, reading news on his phone while eating cereal. He looks up when you enter.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Morning! Sleep okay?</div><img src="./media/activities/breakfast_ethan_t1.jpg" alt="Casual morning chat over cereal. He makes small talk about your flight, the wedding prep. Sibling energy." style="max-width:100%;height:auto;border-radius:8px;" /><p>It's comfortable. Normal. Like old times.</p> <<set $game_state.current_canvas = "dba6552a-a82f-4f32-a5af-0b378681db25">> <<set $game_state.current_node = "f549cecd-3a35-48ec-b8cb-1f41e723a346">> <<script>>setup.markCanvasTriggered("dba6552a-a82f-4f32-a5af-0b378681db25");<</script>> <<script>>advanceTime(45);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, true, null);setup.showEffectNotification();<</script>> [[Finish breakfast->Location_Kitchen]]
<p>You write down your thoughts. Everything that's happened. Everything you're feeling. It helps to see it on paper, even if it doesn't make things clearer.</p><img src="./media/solo/solo_journal.jpg" alt="Writing in your journal" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "463b8f19-3ed7-44e2-a9be-e2b51ae89dee">> <<set $game_state.current_node = "259744b4-fb7a-4957-bd7c-77aebe9381a9">> <<script>>setup.markCanvasTriggered("463b8f19-3ed7-44e2-a9be-e2b51ae89dee");<</script>> <<script>>advanceTime(30);<</script>> [[Close the journal->Location_Your_Old_Room]]
<p>You take your time getting ready. Hair, makeup, choosing what to wear. You want to look good. You tell yourself it's not specifically for anyone.</p><img src="./media/solo/solo_get_ready.jpg" alt="Getting ready for the day" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "40bff3dc-70eb-413f-a93b-9ce360da0481">> <<set $game_state.current_node = "40e96fb9-30ed-4191-84c3-583c4c973b5b">> <<script>>setup.markCanvasTriggered("40bff3dc-70eb-413f-a93b-9ce360da0481");<</script>> <<script>>advanceTime(30);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("player", null, "boldness", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finished->Location_Upstairs_Bathroom]]
<p>You walk through the house, looking at family photos on the walls. So many memories here. Pictures of you and Ethan as teenagers. Before everything got complicated.</p> <<set $game_state.current_canvas = "79d7b9d6-29ee-4962-ae7a-91226ed22ae9">> <<set $game_state.current_node = "b188066b-026d-4914-8ce8-0b4ab243efe2">> <<script>>setup.markCanvasTriggered("79d7b9d6-29ee-4962-ae7a-91226ed22ae9");<</script>> <<script>>advanceTime(15);<</script>> [[Continue on->Location_Upstairs_Hallway]]
<p>The pool is quiet. You swim a few laps, letting the cool water clear your mind. The privacy fence ensures you're alone with your thoughts.</p><img src="./media/solo/solo_swim_alone.gif" alt="Swimming alone in the pool" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "5e176181-e161-43e7-8dda-fcacf805e90b">> <<set $game_state.current_node = "4faa4ac1-a25f-4724-b5dd-3f40d6a378aa">> <<script>>setup.markCanvasTriggered("5e176181-e161-43e7-8dda-fcacf805e90b");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("player", null, "energy", "add", 10.0, true, null);setup.showEffectNotification();<</script>> [[Dry off->Location_Backyard_&_Pool]]
<p>You scroll through your phone, catching up on messages and social media. Your life back home feels very far away right now.</p> <<set $game_state.current_canvas = "5b66480a-4811-46e5-a515-04d3e9a53bdd">> <<set $game_state.current_node = "bb0ee51f-aac6-43e8-af46-bb7d8470265c">> <<script>>setup.markCanvasTriggered("5b66480a-4811-46e5-a515-04d3e9a53bdd");<</script>> <<script>>advanceTime(30);<</script>> [[Put the phone down->Location_Your_Old_Room]]
<p>You unpack your suitcase slowly, finding places for everything. Some of your old things are still here—books, a few photos. Memories.</p><img src="./media/solo/solo_unpack.jpg" alt="Settling back into your old room" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "2545cef7-fb06-4ab4-8d78-cc2fb8b314d2">> <<set $game_state.current_node = "7149dc69-1d3f-45a6-8758-2a04f8cc43ef">> <<script>>setup.markCanvasTriggered("2545cef7-fb06-4ab4-8d78-cc2fb8b314d2");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.pendingEffects = [];setup.applyAndNotifyTrait("player", null, "boldness", "add", 2.0, true, null);setup.showEffectNotification();<</script>> [[Finish unpacking->Location_Your_Old_Room]]
<p>The hot water helps clear your head. Steam fills the small bathroom as you let the tension wash away.</p><img src="./media/scenes/bathroom/solo_shower_t1_1.GIF" alt="Stepping into the shower" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>You let the water run over you, washing away the travel fatigue.</p><video src="./media/scenes/bathroom/solo_shower_t1_2.mp4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "bde40787-6198-478f-acd7-c262f235c484">> <<set $game_state.current_node = "8a5fa660-f808-4323-b3c5-4d2dc2d28685">> <<script>>setup.markCanvasTriggered("bde40787-6198-478f-acd7-c262f235c484");<</script>> <<script>>advanceTime(30);<</script>> [[Get dressed->Location_Upstairs_Bathroom]]
<p>The hot water cascades over your body. You close your eyes, letting it wash over you.</p><video src="./media/scenes/bathroom/solo_shower_t2_1.MP4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video><p>Your hands move slowly, enjoying the sensation. You're not thinking about anything specific. Or anyone.</p><img src="./media/scenes/bathroom/solo_shower_t2_2.GIF" alt="Eyes closed, savoring the warmth" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>At least that's what you tell yourself.</p><img src="./media/scenes/bathroom/solo_shower_t2_3.GIF" alt="Lingering touches" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "e10d2766-69a4-4519-9306-f4ccbc27981f">> <<set $game_state.current_node = "78821c78-b2a6-49a3-b81e-5910c4479db1">> <<script>>setup.markCanvasTriggered("e10d2766-69a4-4519-9306-f4ccbc27981f");<</script>> <<script>>advanceTime(30);<</script>> [[Get dressed->Location_Upstairs_Bathroom]]
<p>The steam fills the bathroom. Your mind keeps drifting to him. The way he looked at you. The tension you can't escape.</p><video src="./media/scenes/bathroom/solo_shower_t3_1.MP4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video><p>Your hand moves lower, and you stop pretending you're not thinking about Ethan.</p><img src="./media/scenes/bathroom/solo_shower_t3_2.GIF" alt="Lost in pleasure" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "c0390255-cd42-46dd-86d7-147e542a473b">> <<set $game_state.current_node = "1f638b32-033d-4c25-942b-04e3b0cc85d9">> <<script>>setup.markCanvasTriggered("c0390255-cd42-46dd-86d7-147e542a473b");<</script>> <<script>>advanceTime(35);<</script>> [[Compose yourself->Location_Upstairs_Bathroom]]
<p>The steam fills the bathroom. Your hand moves lower, thinking of him. The way he kissed you.</p><p>You're lost in the moment when you notice it—the door, slightly open.</p><img src="./media/scenes/bathroom/solo_shower_t4_1.GIF" alt="The door ajar" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>And through the gap, you see him. Ethan. Watching.</p><img src="./media/scenes/bathroom/solo_shower_t4_2.GIF" alt="Eyes meeting through the steam" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>Your eyes meet through the steam. You should stop. You should say something.</p><img src="./media/scenes/bathroom/solo_shower_t4_3.GIF" alt="You don't stop" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>You don't.</p><video src="./media/scenes/bathroom/solo_shower_t4_4.mp4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "6fd48df2-2dca-4ab7-a7be-b234e4a7143b">> <<set $game_state.current_node = "7a5bed15-3007-46e1-a588-7f43513c11bf">> <<script>>setup.markCanvasTriggered("6fd48df2-2dca-4ab7-a7be-b234e4a7143b");<</script>> <<script>>advanceTime(35);<</script>> [[Finish and step out->Location_Upstairs_Bathroom]]
<p>The door opens fully this time. He doesn't ask. You don't tell him to leave.</p><img src="./media/scenes/bathroom/solo_shower_t5_1.GIF" alt="He steps in" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>He steps in, still in his clothes, the water soaking through as he pulls you to him.</p><img src="./media/scenes/bathroom/solo_shower_t5_2.GIF" alt="Clothes soaking through" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><img src="./media/scenes/bathroom/solo_shower_t5_3.GIF" alt="Pulling you close" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I couldn't wait.</div><p>His hands explore your wet skin. Yours find the hem of his shirt.</p><img src="./media/scenes/bathroom/solo_shower_t5_4.GIF" alt="Undressing him" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><img src="./media/scenes/bathroom/solo_shower_t5_5.GIF" alt="Together under the water" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "0834d14d-55f4-4aa6-b60b-753588944c09">> <<set $game_state.current_node = "86a6e865-ee0b-488d-87f3-5341b03bd72b">> <<script>>setup.markCanvasTriggered("0834d14d-55f4-4aa6-b60b-753588944c09");<</script>> <<script>>advanceTime(45);<</script>> [[Dry off together->Location_Upstairs_Bathroom]]
<p>He slips in behind you, hands on your hips. The water runs over both of you.</p><p>You sink to your knees, the water running down your back. Looking up at him through the steam.</p><img src="./media/scenes/bathroom/solo_shower_t6_1.GIF" alt="On your knees" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>This has become routine now—a secret ritual before anyone else wakes up.</p><img src="./media/scenes/bathroom/solo_shower_t6_2.GIF" alt="Taking him in your mouth" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "2258aef8-bc4d-4e9e-a766-bacfdd800739">> <<set $game_state.current_node = "7101f51d-7818-4b1a-bc38-fe775ee6b9d7">> <<script>>setup.markCanvasTriggered("2258aef8-bc4d-4e9e-a766-bacfdd800739");<</script>> <<script>>advanceTime(40);<</script>> [[Finish up->Location_Upstairs_Bathroom]]
<p>You barely make it into the bathroom before he's there. The door clicks shut behind him.</p><img src="./media/scenes/bathroom/solo_shower_t7_1.GIF" alt="Pushing you against the wall" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>He lifts you against the cold tile. The contrast—hot water, cold wall, his body pressed against yours.</p><img src="./media/scenes/bathroom/solo_shower_t7_2.GIF" alt="Lifting you up" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> We need to stop doing this.</div><p>Neither of you stops.</p><video src="./media/scenes/bathroom/solo_shower_t7_3.MP4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "26e1a29a-54d0-4f4b-87de-864e54a0e01e">> <<set $game_state.current_node = "6c73bc23-8162-4a71-ad33-f82f7490c812">> <<script>>setup.markCanvasTriggered("26e1a29a-54d0-4f4b-87de-864e54a0e01e");<</script>> <<script>>advanceTime(45);<</script>> [[Catch your breath->Location_Upstairs_Bathroom]]
<p>You lie down on the bed. The familiar ceiling, the old posters on the walls. So much has changed, but this room feels like a time capsule.</p> <<set $game_state.current_canvas = "e4501f93-13d9-4faf-8701-ca5e05f2c148">> <<set $game_state.current_node = "cdf099e2-44b3-4247-9263-36cb45697bf3">> <<script>>setup.markCanvasTriggered("e4501f93-13d9-4faf-8701-ca5e05f2c148");<</script>> <<link "Take a short nap (1 hour)" "Location_Your_Old_Room">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "energy", "add", 20.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(60);<</script>><</link>><br> <<link "Sleep until morning" "Location_Your_Old_Room">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "energy", "set", 100.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(480);<</script>><</link>><br>
<h1>What Could Have Been</h1><p>You came close. So close. But neither of you was brave enough to leap.</p><p>The wedding happens. He's distant but committed. You're present but already leaving.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Maybe in another life.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Maybe.</div><img src="./media/endings/ending_what_could_have_been.gif" alt="Distance. Regret. The wedding you watch like a stranger. A final conversation where everything important goes unsaid. Airport departure, looking back once." style="max-width:100%;height:auto;border-radius:8px;" /><p>Some love stories end with what-if.</p><h1>THE END</h1> <<set $game_state.current_canvas = "d7cf66e5-8b92-4a53-b4d7-0dcb734cc401">> <<set $game_state.current_node = "a52a7342-3785-4f91-94fa-c3f8f59e153e">> <<script>>setup.markCanvasTriggered("d7cf66e5-8b92-4a53-b4d7-0dcb734cc401");<</script>> <<script>>advanceTime(60);<</script>> [[Return to your life->Location_Living_Room]]
<h1>One Last Night</h1><p>He goes through with it. Of course he does—the guilt was always too strong.</p><p>But the night before, he came to you one last time.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I love you. I'll always love you. But I can't destroy everything.</div><p>You understand. You hate it, but you understand.</p><img src="./media/endings/ending_one_last_night.gif" alt="The wedding from afar. He's at the altar with Madison. You're in the crowd, tears hidden. A final look between you. Then you're gone, taxi pulling away as cheers rise from the venue." style="max-width:100%;height:auto;border-radius:8px;" /><p>The wedding happens. You watch from the crowd. Your eyes meet once. A lifetime in a glance.</p><p>You leave before the reception. Some goodbyes don't need words.</p><h1>THE END</h1> <<set $game_state.current_canvas = "23ea19a2-a13a-4cd0-9e3f-91adefe2de0e">> <<set $game_state.current_node = "938c9088-8533-4e53-bad4-38e3912acd99">> <<script>>setup.markCanvasTriggered("23ea19a2-a13a-4cd0-9e3f-91adefe2de0e");<</script>> <<script>>advanceTime(60);<</script>> [[Move on->Location_Living_Room]]
<h1>The Arrangement</h1><p>He marries Madison. Of course he does.</p><p>But the story doesn't end.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I can't leave her. But I can't leave you either.</div><p>It's wrong. You both know it's wrong. But when has that stopped you?</p><img src="./media/endings/ending_the_arrangement.gif" alt="The wedding concludes. But later, a message on your phone. Then another visit, months later. Then another. The secret you can't stop keeping." style="max-width:100%;height:auto;border-radius:8px;" /><p>Some love stories don't have clean endings. Some just continue in shadows.</p><h1>THE END</h1> <<set $game_state.current_canvas = "0f195b3f-bcfa-44c0-a100-37ad4e325285">> <<set $game_state.current_node = "709d77f2-06ea-44d1-9bb8-896966e69568">> <<script>>setup.markCanvasTriggered("0f195b3f-bcfa-44c0-a100-37ad4e325285");<</script>> <<script>>advanceTime(60);<</script>> [[Continue your secret->Location_Living_Room]]
<h1>He Chooses You</h1><p>The ceremony begins. Madison walks down the aisle. Everyone is watching.</p><p>Then he says the words no one expected:</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I can't do this.</div><p>What follows is chaos. Madison's tears. Family shock. Scandal.</p><img src="./media/endings/ending_he_chooses_you.gif" alt="Wedding interruption. His eyes finding yours in the crowd. Walking away from the altar. The aftermath: alone together, uncertain but finally honest. A first kiss as something real." style="max-width:100%;height:auto;border-radius:8px;" /><p>But when the dust settles, he's beside you.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I choose you. I choose us.</div><p>It won't be easy. Nothing worth having ever is.</p><h1>THE END</h1> <<set $game_state.current_canvas = "a87c60a5-8a49-4cc3-9a12-faae9080e2f2">> <<set $game_state.current_node = "be45ea22-2c10-4f8b-b44d-19195f0186ea">> <<script>>setup.markCanvasTriggered("a87c60a5-8a49-4cc3-9a12-faae9080e2f2");<</script>> <<script>>advanceTime(60);<</script>> [[Begin your story together->Location_Living_Room]]
<p>The day has arrived. The house is chaos—florists, caterers, Madison's family. In a few hours, he'll stand at an altar.</p><p>He finds a moment alone with you. Maybe the last moment.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Whatever happens today... I need you to know...</div><img src="./media/scenes/scene_wedding_morning.gif" alt="Final moment before ceremony. Stolen conversation amid wedding chaos. His hand finds yours." style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Thank you. For everything.</div><p>You don't know what that means yet.</p> <<set $game_state.current_canvas = "285a83a5-320e-4969-a558-e0fbb69d1827">> <<set $game_state.current_node = "95b31343-fcbf-4f53-94e4-7147eefd91e3">> <<script>>setup.markCanvasTriggered("285a83a5-320e-4969-a558-e0fbb69d1827");<</script>> <<script>>advanceTime(60);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "wedding_morning_done");<</script>> [[Wait for what comes next->Location_Kitchen]]
<p>Tomorrow he marries Madison.</p><p>Tonight... tonight he comes to your room. The door opens in darkness, and you know it's him before he speaks.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I had to see you.</div><p>This is it. The last chance. Tomorrow changes everything.</p><p>You reach for him and he falls into you, his kiss tasting like tears.</p><img src="./media/scenes/scene_nbw_kiss_1.gif" alt="Desperate embrace - your lips find his in the darkness" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>You hold each other like you're drowning.</p><img src="./media/scenes/scene_nbw_kiss_2.gif" alt="Deeper kiss - neither of you can let go" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "35c00eec-e8a6-41a4-a614-237043b4c73c">> <<script>>setup.markCanvasTriggered("4840b621-e25f-411f-b937-28acadc2f012");<</script>> <<link "Pull him inside" "Canvas_scene_night_before_wedding_Node_2">><<script>>advanceTime(3);<</script>><</link>><br>
<p>You undress each other slowly. Memorizing. Savoring.</p><img src="./media/scenes/scene_nbw_undressing_1.gif" alt="His fingers find the buttons of your shirt" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>Every button, every inch of skin revealed feels sacred.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I want to remember everything.</div><img src="./media/scenes/scene_nbw_undressing_2.gif" alt="Bare skin meets bare skin" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "d166dc6b-2cc4-449a-9a9e-9ea26f2895cb">> <<link "Let him lay you down" "Canvas_scene_night_before_wedding_Node_3">><<script>>advanceTime(3);<</script>><</link>><br>
<p>He lays you down and kisses his way down your body. Taking his time. No rush tonight.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I want to remember every part of you.</div><img src="./media/scenes/scene_nbw_oral_1.gif" alt="His mouth finds your center" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>Slow. Devoted. Like a prayer.</p><img src="./media/scenes/scene_nbw_oral_2.gif" alt="Your fingers grip the sheets" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><img src="./media/scenes/scene_nbw_oral_3.gif" alt="Waves of pleasure building" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "5b136f74-9b2b-4362-9120-3131fdd5ed2b">> <<link "Pull him up to you" "Canvas_scene_night_before_wedding_Node_4">><<script>>advanceTime(3);<</script>><</link>><br>
<p>When he finally enters you, you're both crying.</p><p>The weight of everything you can't have crushing down. But right now, in this moment, he's yours.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I love you. I've always loved you.</div><img src="./media/scenes/scene_nbw_missionary_1.gif" alt="Slow and deep - foreheads touching, tears in both your eyes" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "103399ef-ebd3-4283-bf6c-589cddbda9a6">> <<link "Hold him closer" "Canvas_scene_night_before_wedding_Node_5">><<script>>advanceTime(3);<</script>><</link>><br>
<p>He moves inside you slowly at first, each thrust deliberate, like he's trying to make it last forever.</p><p>You pull him closer, deeper. Your nails rake down his back.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Don't hold back. Not tonight.</div><p>He listens. The pace builds. Gentle becomes urgent.</p><img src="./media/scenes/scene_nbw_missionary_2.gif" alt="The pace builds - passionate, gripping each other" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "4a55d91e-0438-441b-a7d8-fb5556065b79">> <<link "Take control" "Canvas_scene_night_before_wedding_Node_6">><<script>>advanceTime(3);<</script>><</link>><br>
<p>You push him onto his back. You need to feel him, control this, make it yours.</p><img src="./media/scenes/scene_nbw_cowgirl_1.gif" alt="You sink down onto him" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>His hands grip your hips as you ride him.</p><img src="./media/scenes/scene_nbw_cowgirl_2.gif" alt="Finding your rhythm" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><img src="./media/scenes/scene_nbw_cowgirl_3.gif" alt="The pace builds" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> God, you're beautiful.</div><img src="./media/scenes/scene_nbw_cowgirl_4.gif" alt="Desperate to feel everything" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><img src="./media/scenes/scene_nbw_cowgirl_5.gif" alt="Both of you lost in sensation" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "145a7e5a-7f2f-4b11-89e7-c4c3d3b6fefa">> <<link "Feel it building" "Canvas_scene_night_before_wedding_Node_7">><<script>>advanceTime(3);<</script>><</link>><br>
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I'm yours. Whatever happens tomorrow, I'm yours tonight.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I'm close—</div><p>You slide off him, kneeling before him as he stands at the edge of the bed.</p><img src="./media/scenes/scene_nbw_facial_1.gif" alt="He finishes on your face" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>You feel the warmth on your skin. His eyes never leave yours.</p><img src="./media/scenes/scene_nbw_facial_2.gif" alt="You savor the moment together" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "716ce4f8-f412-468b-bc4a-0745710386a1">> <<link "Let him clean you up" "Canvas_scene_night_before_wedding_Node_8">><<script>>advanceTime(3);<</script>><</link>><br>
<p>He cleans you gently, tenderly. Then you lie tangled together, neither wanting to move.</p><img src="./media/scenes/scene_nbw_cuddle.webp" alt="Tangled together in the aftermath" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Don't marry her.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Don't ask me that.</div><p>But he's here, isn't he? In your bed instead of hers.</p><p>You stay together until the sky starts to lighten. No more words. Just holding on to what little time you have left.</p> <<set $game_state.current_canvas = "4840b621-e25f-411f-b937-28acadc2f012">> <<set $game_state.current_node = "112065b1-4d57-4331-8997-41471565c598">> <<link "\"Choose me.\"" "Location_Your_Old_Room">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 10.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "", "add", 0.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(300);<</script>><</link>><br> <<link "\"I'll always love you. Whatever you decide.\"" "Location_Your_Old_Room">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "", "add", 0.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(300);<</script>><</link>><br> <<link "\"This was goodbye, wasn't it?\"" "Location_Your_Old_Room">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "", "add", 0.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(300);<</script>><</link>><br>
<p>Madison is on the phone. Or in the shower. Or anywhere else. You don't care where—just that she's not here.</p><p>He finds you in the garage. Grabs your hand. Pulls you behind the shelves where old boxes provide cover.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I need you. I can't—one more time before—</div><p>He doesn't finish the sentence. His hands are already pulling down your pants, bending you over a stack of storage boxes. You hear him unzip.</p><p>When he pushes inside you, his hand clamps over your mouth. Madison is somewhere in the house. Anyone could open that door. The danger makes your pulse race.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Quiet. You have to be quiet.</div><p>He fucks you hard and fast, gripping your hip with his free hand. You bite down on his fingers to muffle your moans. It's hurried, desperate, guilty—and you've never wanted anything more.</p><p>He groans your name as he finishes inside you, pulling you back against him, both of you panting in the dusty silence.</p><video src="./media/scenes/scene_stolen_moment.MP4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "fc57410a-9ac2-40d5-a14f-f94845cc34ce">> <<set $game_state.current_node = "5178b6f3-0011-411a-b252-fdcac86fe372">> <<script>>setup.markCanvasTriggered("fc57410a-9ac2-40d5-a14f-f94845cc34ce");<</script>> <<link "\"We're insane.\" But don't stop" "Canvas_scene_stolen_moment_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"This is the last time.\"" "Canvas_scene_stolen_moment_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Run away with me.\"" "Canvas_scene_stolen_moment_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 10.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>You hear Madison calling his name from inside. The spell breaks.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Coming!</div><p>He looks at you one last time before going. That look says everything.</p> <<set $game_state.current_canvas = "fc57410a-9ac2-40d5-a14f-f94845cc34ce">> <<set $game_state.current_node = "29f19b0c-8a74-40fb-8440-123b7bcbaf3e">> <<script>>advanceTime(30);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "stolen_moment_complete");<</script>> [[Wait before following->Location_Garage]]
<p>The sound of a car in the driveway. Your heart stops.</p><p>Madison.</p><p>The fiancée. The woman he's supposed to marry tomorrow. Real and present and here.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Madison:</strong> Surprise! I finished early!</div><img src="./media/scenes/scene_madison_arrives.gif" alt="Madison's arrival. The hug between engaged couple. Over Madison's shoulder, Ethan's eyes find yours. Apology. Fear. Longing." style="max-width:100%;height:auto;border-radius:8px;" /><p>You watch Ethan's face. The guilt. The panic. The mask that slips on too slowly.</p><p>Madison pulls back, finally notices you.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Madison:</strong> You must be the step-sister! I've heard so much about you.</div> <<set $game_state.current_canvas = "7ab8806f-3582-4c37-a50f-93abbaf872e0">> <<set $game_state.current_node = "358f12f3-cd64-42fe-ace7-d876575ac74e">> <<script>>setup.markCanvasTriggered("7ab8806f-3582-4c37-a50f-93abbaf872e0");<</script>> <<link "\"All good things, I hope.\"" "Canvas_scene_madison_arrives_Node_2">><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Has he mentioned me?\"" "Canvas_scene_madison_arrives_Node_2">><<script>>advanceTime(3);<</script>><</link>><br> <<link "Excuse yourself. You can't do this." "Canvas_scene_madison_arrives_Node_2">><<script>>advanceTime(3);<</script>><</link>><br>
<p>Madison is nice. Genuinely nice. That makes it worse.</p><p>You feel like a ghost in your own body.</p> <<set $game_state.current_canvas = "7ab8806f-3582-4c37-a50f-93abbaf872e0">> <<set $game_state.current_node = "a2096269-b332-4f69-946e-a594051c9576">> <<script>>advanceTime(30);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "madison_arrived");<</script>> [[Find somewhere to be alone->Location_Upstairs_Hallway]]
<p>You tried to be normal today. Failed completely. Every look is loaded. Every accidental touch electric.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I can't stop thinking about last night.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I know. Me neither.</div><p>He glances down the hall—empty—and suddenly his mouth is on yours. You stumble backward, your back hitting the wall. His hands are everywhere, pulling at your clothes.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I need you. Right now.</div><p>He lifts your leg around his hip, his fingers pushing your underwear aside. When he enters you, you gasp, and his hand covers your mouth—anyone could walk by.</p><p>It's fast and desperate, his hips slamming into you against the wall. You bite his palm to keep quiet. The thrill of almost being caught makes everything more intense.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> God, yes. Don't stop.</div><p>You come hard, shaking against him, and he follows seconds later, groaning into your neck as he empties himself inside you.</p><video src="./media/scenes/scene_cant_stay_away.mp4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> My room. Ten minutes. I'm not done with you.</div> <<set $game_state.current_canvas = "7f5880ef-b71d-47d3-9506-aa2caaefe382">> <<set $game_state.current_node = "1e0d1dd5-962e-4ef1-94ce-96ca1109e274">> <<script>>setup.markCanvasTriggered("7f5880ef-b71d-47d3-9506-aa2caaefe382");<</script>> <<script>>advanceTime(90);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "cant_stay_away_complete");<</script>> [[Follow him->Location_Upstairs_Hallway]]
<p>Dawn light through the curtains. His arm around you, his chest against your back. For a moment, you forget everything else—the wedding, Madison, the impossibility. There's just this.</p><p>Then he stirs. You feel him hardening against you, his hips pressing closer.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Morning.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Morning.</div><p>His hand slides down your stomach, between your thighs. You're still sensitive from last night, still wet. He groans against your neck when he feels it.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Don't stop.</div><p>He enters you from behind, slow and lazy, both of you half-asleep and unhurried. His hand stays between your legs, circling your clit as he rocks into you. It builds slowly, gently—a warm wave rather than a crash.</p><p>You come quietly, trembling in his arms. He follows moments later, pulling you closer, staying inside you as you both drift in the aftermath.</p><video src="./media/scenes/scene_morning_after.mp4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video><p>Neither moves to leave.</p> <<set $game_state.current_canvas = "94751735-6f29-4dd2-b5f8-871202ec0ed5">> <<set $game_state.current_node = "03124fa7-79de-40a8-89e2-f0615f79ca23">> <<script>>setup.markCanvasTriggered("94751735-6f29-4dd2-b5f8-871202ec0ed5");<</script>> <<link "\"Stay a little longer.\"" "Canvas_scene_morning_after_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"The wedding is in four days.\"" "Canvas_scene_morning_after_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"I don't regret this. Do you?\"" "Canvas_scene_morning_after_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> We should talk. Later. About everything.</div><p>But for now, you have this moment.</p> <<set $game_state.current_canvas = "94751735-6f29-4dd2-b5f8-871202ec0ed5">> <<set $game_state.current_node = "72d6ce79-e548-493d-af26-0cf3eeee62f0">> <<script>>advanceTime(60);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "morning_after_complete");<</script>> [[Get up->Location_Your_Old_Room]]
<p>There's no more pretending. No more stopping. The goodnight at the door doesn't end with goodnight.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Stay.</div><p>One word. Everything changes. The door clicks shut behind him, and then his mouth is on yours. Weeks of tension crashing into this moment.</p><p>Clothes come off in a trail to the bed. His shirt. Your dress. His hands are shaking as he unclasps your bra, and somehow that makes it more real—he's wanted this as long as you have.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> God, you're beautiful.</div><p>He lays you down, taking a moment just to look at you. Then his mouth begins a slow journey—your neck, your breasts, making you arch into him. When he settles between your thighs, when you feel him at your entrance, time stops.</p><p>He pushes in slowly, eyes locked on yours, watching your face as you stretch around him. You moan his name. He starts slow, savoring it, but need takes over. Harder. Deeper. Your nails rake down his back.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I'm close.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Me too. Together.</div><p>You shatter around him as he spills inside you, both of you crying out, holding each other through the aftershocks.</p><video src="./media/scenes/scene_first_night.MP4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "3c251c46-2604-493f-95ad-488ff4e13af0">> <<set $game_state.current_node = "155646d8-8075-46c7-8b70-c26a44853995">> <<script>>setup.markCanvasTriggered("3c251c46-2604-493f-95ad-488ff4e13af0");<</script>> <<link "\"I've wanted this for so long.\"" "Canvas_scene_first_night_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"What happens tomorrow?\"" "Canvas_scene_first_night_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "Don't speak. Just hold him." "Canvas_scene_first_night_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>In the quiet after, everything feels different. Clearer. More complicated.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> No regrets?</div><p>You answer with a kiss.</p> <<set $game_state.current_canvas = "3c251c46-2604-493f-95ad-488ff4e13af0">> <<set $game_state.current_node = "2b9208e3-e4be-428f-ab19-c5bc41390ea0">> <<script>>advanceTime(360);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "first_night_complete");setup.applyAndNotifyFlag("npc", "npc_ethan", "intimate");<</script>> [[Fall asleep in his arms->Location_Your_Old_Room]]
<p>Morning. Coffee. The weight of last night.</p><p>He's already there when you come down. Neither knows what to say. The kiss changed everything.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> So...</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> So.</div><p>Do you acknowledge it? Ignore it? Define it?</p><img src="./media/scenes/scene_what_are_we_doing.gif" alt="He takes the coffee from your hands and kisses you" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I don't want to pretend that didn't happen.</div> <<set $game_state.current_canvas = "be2226c6-ae16-4fe1-b960-e037361a6c5f">> <<set $game_state.current_node = "69a01e7d-6ad1-46a5-924f-6b59ff223d4e">> <<script>>setup.markCanvasTriggered("be2226c6-ae16-4fe1-b960-e037361a6c5f");<</script>> <<link "\"Neither do I.\"" "Canvas_scene_what_are_we_doing_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"What about Madison?\"" "Canvas_scene_what_are_we_doing_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Then don't.\" Pull him closer" "Canvas_scene_what_are_we_doing_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>Whatever this is, it's real now. And you have days to figure out what to do about it.</p> <<set $game_state.current_canvas = "be2226c6-ae16-4fe1-b960-e037361a6c5f">> <<set $game_state.current_node = "aef02c99-f6a6-480a-a9a7-6f6648474e45">> <<script>>advanceTime(45);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "what_are_we_doing_done");<</script>> [[Start the day->Location_Kitchen]]
<p>No more interruptions. No more excuses. It happens like gravity—inevitable.</p><p>One moment you're talking. The next, silence. Then his mouth is on yours.</p><p>Everything you've been fighting falls away.</p><img src="./media/scenes/scene_first_kiss.gif" alt="The first kiss - tentative then desperate, years of suppression breaking" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /> <<set $game_state.current_canvas = "9c442310-64b4-4b5d-8d04-e1705e8aa45e">> <<set $game_state.current_node = "95278206-a16d-49cf-afc6-5e072557ab68">> <<script>>setup.markCanvasTriggered("9c442310-64b4-4b5d-8d04-e1705e8aa45e");<</script>> <<link "\"Don't stop.\"" "Canvas_scene_first_kiss_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"We're really doing this.\"" "Canvas_scene_first_kiss_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "Pull him toward the bedroom" "Canvas_scene_first_kiss_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>When you finally break apart, the world has shifted. There's no going back to pretending.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I've wanted to do that for years.</div> <<set $game_state.current_canvas = "9c442310-64b4-4b5d-8d04-e1705e8aa45e">> <<set $game_state.current_node = "d92ba778-3b86-4e84-bd37-790bfb133ee3">> <<script>>advanceTime(30);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "first_kiss");<</script>> [[Continue->Location_Living_Room]]
<p>"We need to talk about this."</p><p>You find him sitting in the dark. He's been thinking. The wedding is in a week. Madison. The family. The impossibility of what he's feeling.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I'm supposed to be getting married.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I know.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I don't know if I can.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I know.</div><img src="./media/scenes/scene_real_talk.gif" alt="Raw honesty - you hold him as he breaks down" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> What do you want?</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I want you. I hate that I want you.</div> <<set $game_state.current_canvas = "721b6515-4264-4630-b9c4-8eafcf6e5120">> <<set $game_state.current_node = "f70b579f-6bcf-4468-87dd-c93fc3d0fcbe">> <<script>>setup.markCanvasTriggered("721b6515-4264-4630-b9c4-8eafcf6e5120");<</script>> <<link "\"Then have me.\"" "Canvas_scene_real_talk_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 8.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"We'll figure it out. Together.\"" "Canvas_scene_real_talk_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Maybe you should go through with it. Maybe this is just cold feet.\"" "Canvas_scene_real_talk_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", -5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", -10.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>You sit together in the dark for a long time. Whatever happens next, this moment is yours.</p> <<set $game_state.current_canvas = "721b6515-4264-4630-b9c4-8eafcf6e5120">> <<set $game_state.current_node = "ebd52596-519f-41a8-a418-ffc9581e0e81">> <<script>>advanceTime(60);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "real_talk_complete");<</script>> [[Let him go->Location_Your_Old_Room]]
<p>You're close. Too close. His hand is on your face. You can feel his breath. The moment stretches like taffy.</p><img src="./media/scenes/scene_almost_kiss.gif" alt="Faces inches apart, eyes dropping to lips, the tilt of heads beginning" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>Then a sound. His phone. A door. Something breaks the spell.</p><p>You spring apart like guilty teenagers.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I should...</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Yeah.</div><p>But you both know. There's no going back now.</p> <<set $game_state.current_canvas = "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5">> <<set $game_state.current_node = "db14b60f-ea6a-4914-8eae-f650867db109">> <<script>>setup.markCanvasTriggered("fbaa6a2a-dede-4487-ac05-6e9ad00f97c5");<</script>> <<link "\"What were we doing?\"" "Canvas_scene_almost_kiss_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Next time, lock the door.\"" "Canvas_scene_almost_kiss_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"This can't happen.\" But your eyes say otherwise" "Canvas_scene_almost_kiss_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", -3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>You go your separate ways. But the taste of what almost happened lingers.</p> <<set $game_state.current_canvas = "fbaa6a2a-dede-4487-ac05-6e9ad00f97c5">> <<set $game_state.current_node = "ec92939c-e1eb-4cc4-81fa-b5b329454cad">> <<script>>advanceTime(30);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "almost_kiss_complete");<</script>> [[Go inside->Location_Backyard_&_Pool]]
<p>You're drinking on the patio. Third glass. The stars are out. The pool lights shimmer.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Can I tell you something? Something I've never told anyone?</div><p>This is it. The thing you've been circling.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I used to stay awake at night listening for your footsteps. Hoping you'd knock on my door. Terrified you would.</div><img src="./media/scenes/scene_confession.gif" alt="Wine-loosened truth - he looks at you like you're the answer" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I thought I was the only one.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> You weren't.</div><p>Long pause.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> What do we do now?</div> <<set $game_state.current_canvas = "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff">> <<set $game_state.current_node = "2f6bcc29-c4be-4d8c-8a39-f92068bb033b">> <<script>>setup.markCanvasTriggered("f5b8ddd0-5ea4-4f82-af81-15cbe64057ff");<</script>> <<link "\"We forget I said that.\"" "Canvas_scene_confession_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", -5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"We have nine days to figure that out.\"" "Canvas_scene_confession_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 8.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "Kiss him. No more words." "Canvas_scene_confession_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 10.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>The night air feels different now. Charged. Whatever walls were left between you have started to crumble.</p> <<set $game_state.current_canvas = "f5b8ddd0-5ea4-4f82-af81-15cbe64057ff">> <<set $game_state.current_node = "a793c1d4-657a-4533-91fb-9c8fb6621f49">> <<script>>advanceTime(45);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "confession_complete");<</script>> [[Head inside->Location_Backyard_&_Pool]]
<p>Movie night. The couch is big but somehow you've migrated to the middle. The blanket covers both of you. On screen, a couple is doing what you're pretending not to think about.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Maybe we should watch something else.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> Maybe we should.</div><p>Neither of you reaches for the remote.</p><video src="./media/scenes/scene_the_couch.mp4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video> <<set $game_state.current_canvas = "586e0e77-efb7-4334-80eb-23411951bdb4">> <<set $game_state.current_node = "929274b5-2821-495c-91af-4c5729692cad">> <<script>>setup.markCanvasTriggered("586e0e77-efb7-4334-80eb-23411951bdb4");<</script>> <<link "\"Ethan...\" (warning tone)" "Canvas_scene_the_couch_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "Move closer" "Canvas_scene_the_couch_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"We can't.\" But don't move away" "Canvas_scene_the_couch_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>Something shifts. Or almost shifts. The movie ends. Credits roll. Neither of you has any idea what happened in it.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> It's late. We should...</div><p>He doesn't finish the sentence. Doesn't need to.</p> <<set $game_state.current_canvas = "586e0e77-efb7-4334-80eb-23411951bdb4">> <<set $game_state.current_node = "8f7c042e-ea4c-465a-b7d3-71e8d49945d1">> <<script>>advanceTime(60);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "the_couch_complete");<</script>> [[Say goodnight->Location_Living_Room]]
<p>His phone rings. Madison. His fiancée. The woman he's marrying in ten days.</p><p>You watch his face as he talks. Loving words that sound rehearsed.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Yes, everything's fine. She just got here. We're just catching up.</div><p>Just catching up.</p><video src="./media/scenes/scene_madison_calls.mp4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video><p>When he hangs up, neither of you speaks for a moment.</p> <<set $game_state.current_canvas = "22cc3189-8f9f-4016-837c-3014248a4bff">> <<set $game_state.current_node = "6b2d1eb7-51f0-425b-9429-0bfebd843696">> <<script>>setup.markCanvasTriggered("22cc3189-8f9f-4016-837c-3014248a4bff");<</script>> <<link "\"She seems nice.\"" "Canvas_scene_madison_calls_Node_2">><<script>>advanceTime(3);<</script>><</link>><br> <<link "Say nothing, just look at him" "Canvas_scene_madison_calls_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Do you love her?\"" "Canvas_scene_madison_calls_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>He sets his phone down. The name 'Madison ❤️' fades from the screen.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> She's... she's great. Really.</div><p>He doesn't sound convinced.</p> <<set $game_state.current_canvas = "22cc3189-8f9f-4016-837c-3014248a4bff">> <<set $game_state.current_node = "c0b20c9b-85df-423d-a377-80edcbd4fe4d">> <<script>>advanceTime(30);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "madison_calls_complete");<</script>> [[Give him space->Location_Living_Room]]
<p>3 AM. You can't sleep. Too many thoughts, too much proximity. You go downstairs for water and find him there.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> You too?</div><p>Both in sleep clothes. Both vulnerable. The darkness makes it easier to say things that daylight forbids.</p><img src="./media/images/scene_sleepless_night_kitchen.jpg" alt="The kitchen at 3AM - moonlit and quiet" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><img src="./media/scenes/scene_sleepless_night.gif" alt="He reaches out and tucks a strand of hair behind your ear" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I should go back to bed.</div> <<set $game_state.current_canvas = "e2bfbeb9-ebc9-458e-96f5-1a854ad75be7">> <<set $game_state.current_node = "96d5e781-845d-4e01-9ba6-9928e16d296f">> <<script>>setup.markCanvasTriggered("e2bfbeb9-ebc9-458e-96f5-1a854ad75be7");<</script>> <<link "\"Yeah. We should.\"" "Canvas_scene_sleepless_night_Node_2">><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Stay. Just for a bit.\"" "Canvas_scene_sleepless_night_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Ethan... why can't you sleep?\"" "Canvas_scene_sleepless_night_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>The moment stretches. Then breaks. You both retreat to your separate rooms, but sleep doesn't come any easier.</p> <<set $game_state.current_canvas = "e2bfbeb9-ebc9-458e-96f5-1a854ad75be7">> <<set $game_state.current_node = "b2de65d9-7abb-4fa6-9a6d-8e390036b088">> <<script>>advanceTime(30);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "sleepless_night_complete");<</script>> [[Go back to bed->Location_Kitchen]]
<p>You find the boxes while looking for something else. Photo albums from high school. There you are—two teenagers who didn't know what to do with their feelings. Prom photos. Beach trips. That summer you got too close.</p><p>You thought you'd buried this.</p><video src="./media/scenes/scene_old_photos.mp4" controls preload="metadata" style="max-width:100%;height:auto;border-radius:8px;"></video><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I remember that night.</div> <<set $game_state.current_canvas = "b133cce8-dae7-4c11-a1db-d75552e256c8">> <<set $game_state.current_node = "d3dac6f9-ea62-4590-a5d4-881ee32f686d">> <<script>>setup.markCanvasTriggered("b133cce8-dae7-4c11-a1db-d75552e256c8");<</script>> <<link "\"We were just kids.\"" "Canvas_scene_old_photos_Node_2">><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Some things haven't changed.\"" "Canvas_scene_old_photos_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 5.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Why did you keep these?\"" "Canvas_scene_old_photos_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>He doesn't answer right away. Just looks at the photo, then at you. The silence stretches, filled with everything neither of you is saying.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> We should probably put these away.</div><p>But neither of you moves.</p> <<set $game_state.current_canvas = "b133cce8-dae7-4c11-a1db-d75552e256c8">> <<set $game_state.current_node = "6ca88c69-124c-42cd-9024-ca5e852c1f44">> <<script>>advanceTime(45);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "old_photos_complete");<</script>> [[Head back inside->Location_Garage]]
<p>He's cooked your favorite. You didn't expect him to remember. The kitchen smells like your parents' house used to—before the divorce, before the remarriage, before everything got complicated.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #007bff; background: #e7f3ff; color: #212529;"><strong style="color: #0056b3;">You:</strong> I can't believe you remembered.</div><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> Some things you don't forget.</div><img src="./media/scenes/scene_welcome_dinner.gif" alt="Dinner table intimacy - hands touching as you both reach for the bread" loading="lazy" decoding="async" style="max-width:100%;height:auto;border-radius:8px;" /><p>You eat and talk about safe things. Your job, his job. Not Madison. Not the wedding. Not the way you're noticing how his shoulders have broadened.</p> <<set $game_state.current_canvas = "9da03758-d6d0-4cea-ab7f-c86473348579">> <<set $game_state.current_node = "61b11c94-740e-4e88-848a-efbd6b40893d">> <<script>>setup.markCanvasTriggered("9da03758-d6d0-4cea-ab7f-c86473348579");<</script>> <<link "\"So... two weeks until the big day. Nervous?\"" "Canvas_scene_welcome_dinner_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "guilt", "add", 2.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"Remember when we used to have dinner parties here? Just us, pretending to be fancy?\"" "Canvas_scene_welcome_dinner_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 3.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br> <<link "\"You've really grown up.\"" "Canvas_scene_welcome_dinner_Node_2">><<script>>setup.pendingEffects = [];<</script>><<script>>setup.applyAndNotifyTrait("npc", "npc_ethan", "affection", "add", 2.0, false, null);<</script>><<script>>setup.applyAndNotifyTrait("player", null, "boldness", "add", 1.0, false, null);<</script>><<script>>setup.showEffectNotification();<</script>><<script>>advanceTime(3);<</script>><</link>><br>
<p>The evening winds down. He clears the dishes while you watch, noticing the easy way he moves through the kitchen. This is his life now. A life you're not part of.</p><div style="margin: 10px 0; padding: 10px; border-left: 4px solid #6c757d; background: #f8f9fa; color: #212529;"><strong style="color: #495057;">Ethan:</strong> I'm glad you're here. Really.</div> <<set $game_state.current_canvas = "9da03758-d6d0-4cea-ab7f-c86473348579">> <<set $game_state.current_node = "3fa3d85a-7e0a-4e78-bec7-d201187f5beb">> <<script>>advanceTime(90);<</script>> <<script>>setup.applyAndNotifyFlag("player", null, "welcome_dinner_complete");<</script>> [[Head to your room->Location_Kitchen]]
<h2>Missing Media Files</h2> <p>No missing media files found.</p> <<link "← Back" "previous()">><</link>>