| WORLD = { |
| "id": "maple_street", |
| "name": "Maple Street", |
| "theme": "cozy modern suburb", |
| "diorama": "assets/worlds/maple_street.png", |
| "palette": { |
| "bg": "#0b0f1a", |
| "grass": "#1a4a2a", |
| "road": "#1e2235", |
| "house": "#c45b5b", |
| "park": "#0a3a2a", |
| "tree": "#0a2a1a", |
| "sky": "#0a0f1a", |
| "tint_day": "#fff3d6", |
| "tint_night": "#1a2342", |
| }, |
| "hotspots": { |
| "marta_home": [17, 63], |
| "cafe": [72, 58], |
| "park": [58, 50], |
| "square": [48, 73], |
| "jay_home": [89, 87], |
| "school": [37, 56], |
| "nia_clinic": [13, 81], |
| "priya_office": [82, 78], |
| }, |
| "scenery": { |
| "buildings": [ |
| {"left": 5, "top": 40, "w": 15, "h": 15, "front": "#3a2b4d", "roof": "#ff5fa2", "side": "#241a33", "label": "π°οΈ"}, |
| {"left": 27, "top": 33, "w": 20, "h": 14, "front": "#23314f", "roof": "#38e8ff", "side": "#16213a", "label": "π«"}, |
| {"left": 63, "top": 36, "w": 17, "h": 14, "front": "#4a3b2b", "roof": "#ffd76a", "side": "#33291d", "label": "β"}, |
| {"left": 3, "top": 61, "w": 14, "h": 14, "front": "#1f3d3a", "roof": "#7CFFB2", "side": "#142826", "label": "π"}, |
| {"left": 71, "top": 53, "w": 16, "h": 17, "front": "#2c2b4d", "roof": "#9b6bff", "side": "#1d1c33", "label": "π’"}, |
| {"left": 82, "top": 69, "w": 14, "h": 12, "front": "#3a2030", "roof": "#ff8a5f", "side": "#281622", "label": "πͺ"}, |
| ], |
| "roads": [ |
| {"left": -5, "top": 66, "w": 120, "h": 9, "rot": -8}, |
| {"left": 40, "top": 30, "w": 9, "h": 70, "rot": 6}, |
| ], |
| "trees": [ |
| {"left": 21, "top": 52, "s": 1.0}, |
| {"left": 52, "top": 46, "s": 0.8}, |
| {"left": 62, "top": 66, "s": 1.1}, |
| {"left": 33, "top": 80, "s": 0.9}, |
| {"left": 94, "top": 52, "s": 0.8}, |
| ], |
| "props": [ |
| {"left": 49, "top": 64, "emoji": "β²"}, |
| {"left": 30, "top": 67, "emoji": "πͺ§"}, |
| ], |
| }, |
| "cast": [ |
| { |
| "name": "Marta Voss", |
| "age": 68, |
| "job": "retired watchmaker", |
| "traits": ["blunt", "observant", "nostalgic"], |
| "backstory": "She ran the neighborhood clock shop for four decades and still notices every tiny change on the street.", |
| "relationships": { |
| "Jay Park": "rival", |
| "Nia Okafor": "friend", |
| "Luca Bell": "family", |
| "Priya Raman": "friend", |
| }, |
| "voice_description": "(a grumpy elderly woman, deep measured low-pitched voice)", |
| "model": "nvidia/Nemotron-Mini-4B-Instruct", |
| "emoji": "π§", |
| "home": "marta_home", |
| "catchphrase_hint": "always compares things to the past", |
| }, |
| { |
| "name": "Jay Park", |
| "age": 24, |
| "job": "food delivery cyclist", |
| "traits": ["restless", "funny", "impulsive"], |
| "backstory": "He knows every shortcut in the district and treats ordinary afternoons like they might become legends.", |
| "relationships": { |
| "Marta Voss": "rival", |
| "Nia Okafor": "crush", |
| "Luca Bell": "friend", |
| "Priya Raman": "friend", |
| }, |
| "voice_description": "(an energetic young man, quick bright mid-pitched voice)", |
| "model": "nvidia/Nemotron-Mini-4B-Instruct", |
| "emoji": "π΄", |
| "home": "jay_home", |
| "catchphrase_hint": "turns everything into an adventure", |
| }, |
| { |
| "name": "Nia Okafor", |
| "age": 35, |
| "job": "paramedic", |
| "traits": ["calm", "protective", "dry-witted"], |
| "backstory": "After years on emergency shifts, she reads chaos quickly and trusts people more than they expect.", |
| "relationships": { |
| "Marta Voss": "friend", |
| "Jay Park": "crush", |
| "Luca Bell": "friend", |
| "Priya Raman": "family", |
| }, |
| "voice_description": "(a steady adult woman, warm confident medium-low voice)", |
| "model": "nvidia/Nemotron-Mini-4B-Instruct", |
| "emoji": "π", |
| "home": "nia_clinic", |
| "catchphrase_hint": "downplays danger but always steps up", |
| }, |
| { |
| "name": "Luca Bell", |
| "age": 15, |
| "job": "student and arcade regular", |
| "traits": ["curious", "dramatic", "inventive"], |
| "backstory": "He documents neighborhood rumors in a battered notebook and is convinced something world-changing will happen here first.", |
| "relationships": { |
| "Marta Voss": "family", |
| "Jay Park": "friend", |
| "Nia Okafor": "friend", |
| "Priya Raman": "rival", |
| }, |
| "voice_description": "(a teenage boy, eager expressive slightly high-pitched voice)", |
| "model": "nvidia/Nemotron-Mini-4B-Instruct", |
| "emoji": "π§", |
| "home": "school", |
| "catchphrase_hint": "treats everything like breaking news", |
| }, |
| { |
| "name": "Priya Raman", |
| "age": 42, |
| "job": "city planner", |
| "traits": ["organized", "skeptical", "secretly romantic"], |
| "backstory": "She came to fix the block's chronic little problems and keeps getting pulled into everyone else's dramas.", |
| "relationships": { |
| "Marta Voss": "friend", |
| "Jay Park": "friend", |
| "Nia Okafor": "family", |
| "Luca Bell": "rival", |
| }, |
| "voice_description": "(a precise middle-aged woman, crisp thoughtful medium voice)", |
| "model": "nvidia/Nemotron-Mini-4B-Instruct", |
| "emoji": "π©βπΌ", |
| "home": "priya_office", |
| "catchphrase_hint": "tries to stay logical but feelings leak through", |
| }, |
| ], |
| "board": { |
| |
| |
| "cols": 22, |
| "rows": 18, |
| "ambient": 6, |
| "roads": {"cols": [5, 11, 17], "rows": [6, 13]}, |
| "plaza": [[12, 9], [13, 9], [12, 10], [13, 10]], |
| "plaza_center": [12.5, 9.5], |
| "buildings": [ |
| |
| {"gx": 1, "gy": 1, "w": 2, "d": 2, "h": 24, "kind": "house", "wall": "#caa074", "roof": "#8a3b2e", "label": "MARTA"}, |
| {"gx": 8, "gy": 1, "w": 2, "d": 2, "h": 24, "kind": "house", "wall": "#b6c081", "roof": "#4a6b32", "label": "THE PARKS"}, |
| {"gx": 19, "gy": 1, "w": 2, "d": 2, "h": 26, "kind": "house", "wall": "#b79ec0", "roof": "#5a3b6b", "label": "RAMAN"}, |
| {"gx": 1, "gy": 15, "w": 2, "d": 2, "h": 24, "kind": "house", "wall": "#c79a78", "roof": "#7a4a2e", "label": "No. 12"}, |
| {"gx": 15, "gy": 15, "w": 2, "d": 2, "h": 24, "kind": "house", "wall": "#9ab0c0", "roof": "#3b5a6b", "label": "No. 9"}, |
| {"gx": 19, "gy": 9, "w": 2, "d": 2, "h": 24, "kind": "house", "wall": "#c0a86a", "roof": "#6b5a2e", "label": "No. 7"}, |
| |
| {"gx": 14, "gy": 1, "w": 2, "d": 2, "h": 30, "kind": "shop", "wall": "#8a6f3f", "roof": "#ff8a5f", "label": "CAFΓ"}, |
| {"gx": 1, "gy": 8, "w": 2, "d": 2, "h": 28, "kind": "shop", "wall": "#6f5a8a", "roof": "#38e8ff", "label": "CORNER STORE"}, |
| |
| {"gx": 8, "gy": 15, "w": 3, "d": 2, "h": 34, "kind": "block", "wall": "#6a6f8a", "roof": "#ffd76a", "label": "SCHOOL"}, |
| {"gx": 19, "gy": 15, "w": 2, "d": 2, "h": 30, "kind": "block", "wall": "#4f8576", "roof": "#7CFFB2", "label": "CLINIC"}, |
| ], |
| "trees": [ |
| [9, 11], [10, 12], [7, 4], [16, 4], [4, 10], [20, 12], [7, 16], [12, 16], [18, 6], [6, 7], |
| ], |
| "props": [ |
| {"type": "fountain", "gx": 12, "gy": 12}, |
| {"type": "pond", "gx": 15, "gy": 11, "w": 2, "d": 2}, |
| {"type": "bench", "gx": 10, "gy": 11}, |
| {"type": "bench", "gx": 14, "gy": 12}, |
| |
| {"type": "table", "gx": 13, "gy": 3}, |
| {"type": "table", "gx": 16, "gy": 3}, |
| |
| {"type": "stall", "gx": 3, "gy": 9, "color": "#caa23f"}, |
| |
| {"type": "planter", "gx": 7, "gy": 12}, |
| {"type": "planter", "gx": 12, "gy": 7}, |
| {"type": "lamp", "gx": 11, "gy": 8}, |
| {"type": "lamp", "gx": 14, "gy": 8}, |
| {"type": "lamp", "gx": 5, "gy": 12}, |
| ], |
| "hotspots_tile": { |
| "marta_home": [3, 2], |
| "jay_home": [8, 3], |
| "priya_office": [18, 2], |
| "school": [10, 14], |
| "nia_clinic": [18, 15], |
| "cafe": [14, 4], |
| "shop": [3, 8], |
| "park": [10, 11], |
| "fountain": [11, 12], |
| "square": [13, 10], |
| }, |
| |
| |
| "activities": { |
| "Marta Voss": {"tile": [10, 11], "label": "πͺ watches from the park bench"}, |
| "Jay Park": {"tile": [14, 4], "label": "π΄ races to the cafΓ©", "vehicle": "bike"}, |
| "Nia Okafor": {"tile": [18, 15], "label": "π heads to the clinic"}, |
| "Luca Bell": {"tile": [11, 12], "label": "π investigates the fountain"}, |
| "Priya Raman": {"tile": [18, 2], "label": "π hurries home to plan"}, |
| }, |
| }, |
| "scenarios": [ |
| { |
| "id": "school_closing", |
| "title": "The school will be closed by the city", |
| "event": "The city announces Maple Street Elementary will be shut down at the end of the semester due to budget cuts.", |
| "focus": "How do different generations react to losing a community institution?", |
| }, |
| { |
| "id": "new_neighbor", |
| "title": "A new family moves in next door", |
| "event": "A young family with two kids moves into the empty house on Maple Street. They seem nice but awfully quiet.", |
| "focus": "How does the neighborhood welcome (or distrust) newcomers?", |
| }, |
| { |
| "id": "park_renovation", |
| "title": "The park gets a makeover", |
| "event": "The city approves a full renovation of the tiny park on Maple Street. Construction starts Monday.", |
| "focus": "Who benefits from change and who loses something familiar?", |
| }, |
| { |
| "id": "power_outage", |
| "title": "A summer power outage hits the block", |
| "event": "A heatwave knocks out power to the entire block for an estimated six hours. No AC, no lights, no screens.", |
| "focus": "How do people cope when their routines are stripped away?", |
| }, |
| ], |
| "events": [ |
| "A mysterious glowing object lands in the park", |
| "The power goes out across the entire neighborhood", |
| "A stray cat starts following people around town", |
| "Someone paints a giant mural on the side of the corner store", |
| "A food truck rolls in and parks in the middle of the square", |
| "The old clock tower starts chiming at random hours", |
| "A thunderstorm knocks down the biggest tree on Maple Street", |
| "Someone leaves a box of kittens on the church doorstep", |
| "The neighborhood gets its own Wikipedia page overnight", |
| "A film crew shows up to shoot a commercial on the block", |
| ], |
| |
| |
| |
| "crises": [ |
| { |
| "id": "cafe_fire", |
| "title": "Kitchen fire at the cafΓ©", |
| "narrative": "Smoke is pouring out of the cafΓ© on the high street β a grease fire has caught in the kitchen and it's spreading fast.", |
| "severity": 3, |
| "kind": "fire", |
| "affected_hotspot": "cafe", |
| "time_limit": 4, |
| "escalation": "The flames are climbing toward the upstairs flats.", |
| "focus": "When the same emergency hits, who runs toward it, who organizes, and who freezes?", |
| "success_text": "The fire's out, everyone's accounted for, and the cafΓ© will reopen.", |
| "failure_text": "The cafΓ© is gutted and the block is shaken.", |
| "requirements": [ |
| { |
| "id": "containment", |
| "label": "π₯ Contain the fire", |
| "hotspots": ["cafe"], |
| "action_keywords": [ |
| "fire", "flame", "douse", "extinguish", "put out", |
| "water", "smoke", "hose", "blanket", |
| ], |
| "weight": 1.5, |
| }, |
| { |
| "id": "medical", |
| "label": "π Get medical on scene", |
| "hotspots": ["cafe", "nia_clinic"], |
| "action_keywords": [ |
| "help", "treat", "check", "injur", "hurt", "burn", |
| "aid", "care", "first aid", "ambulance", |
| ], |
| "role": "medic", |
| "weight": 1.0, |
| }, |
| { |
| "id": "evacuation", |
| "label": "π Evacuate the building", |
| "hotspots": ["cafe", "square"], |
| "action_keywords": [ |
| "evacuat", "get everyone out", "clear", "warn", |
| "usher", "people out", "safe", "away", |
| ], |
| "weight": 1.0, |
| }, |
| { |
| "id": "coordination", |
| "label": "π Coordinate the response", |
| "hotspots": ["priya_office", "square"], |
| "action_keywords": [ |
| "coordinat", "organi", "plan", "call", "rally", |
| "manage", "direct", "report", "emergency", |
| ], |
| "role": "worker", |
| "weight": 1.0, |
| "optional": True, |
| }, |
| ], |
| }, |
| { |
| "id": "heatwave_blackout", |
| "title": "Heatwave blackout", |
| "narrative": "A record heatwave has knocked out power to the whole block β no AC, no fans, and the elderly are sweltering in their flats.", |
| "severity": 3, |
| "kind": "blackout", |
| "affected_hotspot": "priya_office", |
| "time_limit": 4, |
| "escalation": "It's getting dangerously hot indoors.", |
| "focus": "In a slow-burning emergency with no obvious villain, who takes initiative and who waits?", |
| "success_text": "Power's restored, the vulnerable were looked after, and the block cooled down.", |
| "failure_text": "People suffered through the heat with no one taking charge.", |
| "requirements": [ |
| { |
| "id": "restore", |
| "label": "β‘ Get the power back", |
| "hotspots": ["priya_office"], |
| "action_keywords": ["power", "grid", "restore", "electric", "generator", "call", "utility", "fix"], |
| "role": "worker", |
| "weight": 1.5, |
| }, |
| { |
| "id": "welfare", |
| "label": "π Check on the vulnerable", |
| "hotspots": ["marta_home", "nia_clinic", "square"], |
| "action_keywords": ["check", "elderly", "vulnerable", "welfare", "water", "cool", "help", "care"], |
| "role": "medic", |
| "weight": 1.0, |
| }, |
| { |
| "id": "coordination", |
| "label": "π Organize a cooling shelter", |
| "hotspots": ["square", "priya_office"], |
| "action_keywords": ["organi", "plan", "coordinat", "shelter", "gather", "rally"], |
| "weight": 1.0, |
| }, |
| { |
| "id": "relief", |
| "label": "π§ Hand out water & shade", |
| "hotspots": ["cafe", "square"], |
| "action_keywords": ["water", "cool", "shade", "drinks", "ice", "relief"], |
| "weight": 1.0, |
| "optional": True, |
| }, |
| ], |
| }, |
| { |
| "id": "storm_tree", |
| "title": "Storm downs the big maple", |
| "narrative": "A violent summer storm has torn down the giant maple in the park β and someone is trapped under the branches.", |
| "severity": 4, |
| "kind": "storm", |
| "affected_hotspot": "park", |
| "time_limit": 4, |
| "escalation": "The trapped neighbor is hurt and the rain is still coming down.", |
| "focus": "Under real physical danger, who acts on instinct and who needs a plan first?", |
| "success_text": "They freed the trapped neighbor and got everyone to safety.", |
| "failure_text": "Help came too slow and the night turned grim.", |
| "requirements": [ |
| { |
| "id": "rescue", |
| "label": "π³ Free the trapped neighbor", |
| "hotspots": ["park"], |
| "action_keywords": ["lift", "free", "rescue", "trapped", "move", "clear", "branch", "pull", "dig"], |
| "weight": 1.5, |
| }, |
| { |
| "id": "medical", |
| "label": "π Treat the injured", |
| "hotspots": ["park", "nia_clinic"], |
| "action_keywords": ["treat", "help", "injur", "aid", "first aid", "hurt", "care", "bandage"], |
| "role": "medic", |
| "weight": 1.0, |
| }, |
| { |
| "id": "safety", |
| "label": "π§ Secure the area", |
| "hotspots": ["park", "square"], |
| "action_keywords": ["clear", "warn", "safe", "away", "cordon", "keep back", "secure"], |
| "weight": 1.0, |
| }, |
| { |
| "id": "coordination", |
| "label": "π Call for help", |
| "hotspots": ["priya_office", "square"], |
| "action_keywords": ["coordinat", "plan", "call", "report", "organi", "emergency"], |
| "role": "worker", |
| "weight": 1.0, |
| "optional": True, |
| }, |
| ], |
| }, |
| { |
| "id": "missing_child", |
| "title": "A child goes missing", |
| "narrative": "In all the chaos, a little one has wandered off β nobody has seen them for an hour and it's getting dark.", |
| "severity": 4, |
| "kind": "search", |
| "affected_hotspot": "square", |
| "time_limit": 4, |
| "escalation": "Night is falling and the search is getting harder.", |
| "focus": "When the task needs everyone spread out, who organizes the search and who just runs?", |
| "success_text": "They found the child safe β a whole block searching together.", |
| "failure_text": "The search stayed scattered and frightened.", |
| "requirements": [ |
| { |
| "id": "search_park", |
| "label": "π¦ Search the park", |
| "hotspots": ["park"], |
| "action_keywords": ["search", "look", "find", "check", "comb", "scour"], |
| "weight": 1.0, |
| }, |
| { |
| "id": "search_school", |
| "label": "π¦ Search the school", |
| "hotspots": ["school"], |
| "action_keywords": ["search", "look", "find", "check", "comb", "scour"], |
| "weight": 1.0, |
| }, |
| { |
| "id": "coordination", |
| "label": "π Organize the search", |
| "hotspots": ["square", "priya_office"], |
| "action_keywords": ["organi", "coordinat", "plan", "split up", "call", "rally", "direct"], |
| "weight": 1.0, |
| }, |
| { |
| "id": "reassure", |
| "label": "π« Reassure the family", |
| "hotspots": ["square", "marta_home"], |
| "action_keywords": ["calm", "reassure", "comfort", "stay", "with the family"], |
| "weight": 1.0, |
| "optional": True, |
| }, |
| ], |
| }, |
| { |
| "id": "everything_at_once", |
| "title": "The town comes apart", |
| "narrative": "It's all happening at once β a fire on the high street, the power failing, and panic spreading through the square. This is no accident.", |
| "severity": 5, |
| "kind": "fire", |
| "affected_hotspot": "square", |
| "time_limit": 5, |
| "escalation": "Everything that can go wrong is going wrong together.", |
| "focus": "When everything fails at once, does the town fall apart or pull together?", |
| "success_text": "Against the odds, the block held β every person did their part.", |
| "failure_text": "It was too much, all at once.", |
| "requirements": [ |
| { |
| "id": "containment", |
| "label": "π₯ Contain the fire", |
| "hotspots": ["cafe"], |
| "action_keywords": ["fire", "flame", "douse", "extinguish", "put out", "water", "smoke"], |
| "weight": 1.5, |
| }, |
| { |
| "id": "restore", |
| "label": "β‘ Restore the power", |
| "hotspots": ["priya_office"], |
| "action_keywords": ["power", "grid", "restore", "electric", "generator", "call", "fix"], |
| "role": "worker", |
| "weight": 1.0, |
| }, |
| { |
| "id": "medical", |
| "label": "π Tend the hurt", |
| "hotspots": ["cafe", "square", "nia_clinic"], |
| "action_keywords": ["treat", "help", "injur", "aid", "first aid", "hurt", "care"], |
| "role": "medic", |
| "weight": 1.0, |
| }, |
| { |
| "id": "evacuation", |
| "label": "π Calm the square", |
| "hotspots": ["square"], |
| "action_keywords": ["evacuat", "calm", "clear", "warn", "safe", "away", "usher", "people out"], |
| "weight": 1.0, |
| }, |
| ], |
| }, |
| ], |
| "campaign": { |
| "id": "long_summer", |
| "title": "Season 1 Β· The Long Summer", |
| "chapters": [ |
| { |
| "id": "ch1", |
| "crisis_id": "cafe_fire", |
| "intro": "A hot, ordinary afternoon on Maple Street. Then smoke starts rising from the cafΓ©β¦", |
| "outro_win": "The fire's out. People hug on the pavement. 'Could've been so much worse,' someone says.", |
| "outro_loss": "The cafΓ© smolders. Nobody quite knows how it got so bad so fast.", |
| "clue": "Nia notices the fire started right after the gas line was 'serviced' this morning. Odd.", |
| }, |
| { |
| "id": "ch2", |
| "crisis_id": "heatwave_blackout", |
| "intro": "A week later, the hottest day on record β and then every light on the block goes dark at once.", |
| "outro_win": "The fans whir back to life. Marta mutters that nothing on this street is a coincidence anymore.", |
| "outro_loss": "A long, sweltering night. People start asking why this keeps happening here.", |
| "clue": "Priya checks the grid logs: the outage was triggered manually, from outside the neighborhood.", |
| }, |
| { |
| "id": "ch3", |
| "crisis_id": "storm_tree", |
| "intro": "The forecast promised clear skies. The storm that hits the park was nowhere on the radar.", |
| "outro_win": "Soaked and shaking, they carry their neighbor to safety. 'Who's doing this to us?'", |
| "outro_loss": "A hard night under the fallen maple. The block feels watched.", |
| "clue": "Luca's notebook: every disaster has hit a different corner of Maple Street, in order, like a map.", |
| }, |
| { |
| "id": "ch4", |
| "crisis_id": "missing_child", |
| "intro": "Fear has settled over the block. And now, in the middle of it, a child is gone.", |
| "outro_win": "The child is found, safe. The relief is enormous β but so is the dread.", |
| "outro_loss": "The search drags on into the dark. The town has never felt so alone.", |
| "clue": "The child says a 'nice voice on the speaker' told them where to go. Someone is steering all of this.", |
| }, |
| { |
| "id": "ch5", |
| "crisis_id": "everything_at_once", |
| "intro": "Then it all comes at once β fire, blackout, panic. The town finally understands: none of it was an accident.", |
| "outro_win": "Battered but unbroken, the five of them stand in the square. They made it through. Together.", |
| "outro_loss": "The Long Summer breaks the block. But they'll remember who they were to each other.", |
| "clue": "The pieces fit. There was always a hand behind the chaos.", |
| }, |
| ], |
| "finale_reveal": ( |
| "Every fire, every blackout, every storm β traced back to one source. " |
| "The one who threw each event at the town. The one at the controls. You." |
| ), |
| }, |
| } |
|
|