Project Info
Inspiration
What if your favorite reality TV dating show took a dark turn? We were inspired by the dramatic storytelling of shows like Love Island and the intrigue of murder mystery visual novels like Ace Attorney. We wanted to create an interactive narrative experience that combines romance and solving mysteries — two of the most compelling, aspirational, and fun experiences in storytelling!
What it does
"Love Island: To Die For!" is an AI-powered murder mystery visual novel where you play as the newcomer to a reality show investigating the death of Hunter, one of your fellow contestants. You interrogate four suspect-contestants, each with their own motives, alibis, and secrets. Through turn-based conversations, you must piece together the truth from a web of romantic rivalries, hidden relationships, and carefully constructed lies. The game features both traditional individual "dates" with characters, and a unique feature for our gameplay: group conversations where suspects interact with each other. Here you can compete for romantic affection, but also engage with different conversation dynamics that reveals specific information. With a progress bar tracking your remaining turns, you must use your questions wisely to uncover the whodunnit!
How we built it
We built a full-stack application with a Python backend and Next.js/React/Tailwind frontend. The backend uses JanitorAI's LLM API to power dynamic, context-aware character responses that are finetuned perfectly for immersive storytelling. We also developed from scratch a multi-agent context management and memory system, in order to incorporate detailed personality profiles, backgrounds, and conditional secrets that are revealed based on conversation topics. We created a relationship system that tracks connections between characters, enabling us to update agent context and create consistent and believable inter-character interactions, while also progressively revealing clues. The frontend features a pixel-art visual novel aesthetic with smooth animations and custom components for dialogue boxes, character headshots, and progress tracking. And — of course — we designed an intricate murder mystery plot with multiple suspects, each with their own secrets and interconnected relationships that unfold naturally through gameplay.
Challenges we ran into
Creating believable, consistent AI characters was surprisingly difficult — we had to carefully craft system prompts that maintained personality while allowing for natural conversation flow and controlled information revelation. Balancing the mystery difficulty was another challenge: we needed to ensure clues were discoverable but not too obvious, and that different conversation paths could still lead to solving the mystery. Managing conversation state and context across multiple characters and conversation turns required careful state management. We also struggled with timing the reveal of secrets — characters needed to feel reluctant to share information but eventually crack under the right questioning.
Accomplishments we're proud of
We're incredibly proud of the rich, dynamic narrative we created with four distinct characters and complex relationships. Our bespoke multiagent context management system was both lightweight and complex enough to create a genuinely evolving narrative experience — and a great learning experience. The relationship system we built allows characters to reference each other authentically and reveal different information based on who else is present in group conversations. We also love our pixel-art UI that sets the vibe perfectly!
What we learned
We learned that context engineering for multiagent narrative games requires a completely different approach than typical chatbot applications — you need to manage character consistency not just with the main character but with N possible other live relationships and conversation history. Especially for our needs, we learned (through doing!) how do achieve this with minimal token usage. On the technical side, we gained experience with streaming LLM responses in real-time UIs, managing complex state in React, and designing turn-based conversation systems. We also learned valuable lessons about game design — something half our team was doing for the first time this hackathon! We learned how to plant clues, create red herrings, and structure satisfying mysteries, all on the job. We discovered the importance of conditional information revelation and how to structure character descriptions to enable emergent storytelling.
What's next
for Love Island: To Die For We want to expand the game with multiple episodes featuring different murder mysteries and new casts of characters. We plan to add a deduction system where players can formally accuse suspects and present evidence, with different endings based on whether you correctly identify the killer. Voice acting and character animations would bring the personalities to life even more. We'd love to implement a memory system where characters remember previous conversations across multiple playthroughs, creating meta-narrative experiences. Adding branching storylines where player choices affect character relationships and unlock different plot paths would increase replayability. Finally, we want to create a level editor that lets players craft their own murder mysteries with custom characters, relationships, and secrets, turning LIT:DF into a platform for community-created interactive mysteries.
💀 Love Island: To Die For 💕
A multi-agent open dialogue murder mystery created for CalHacks 12.0
🏆 Won Best Multiplayer Chat Experience
Snapshots
Analysis
View
Metric
- 35
- 13
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- FlaskIn code
- JavaScriptIn code
- Next.jsIn code
- OpenAIIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
9 of 9 appear in the indexed code.
AI coding agents
No AI coding agent signals were found in this repository.
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
88 KB
Source files
33
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
syenko/calhacks
69 files · 11.2 MB · @ eb13d24
Structure
Interface
20 files · 29%Screens, components and styles rendered to the user.
Application logic
11 files · 16%Domain rules, services and shared utilities.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- TypeScript77%
- Python19%
- Markdown3%
- JavaScript1%
- CSS1%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
frontend/package.json
npm · 11- next
- react
- react-dom
- +8 more
backend/pyproject.toml
pypi · 3- flask
- flask-cors
- openai
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
Feature verification
AI-powered character conversations via JanitorAI LLM APIVerified
The backend uses JanitorAI's LLM API to power dynamic, context-aware character responses
Claimed on Devposthigh confidencebackend/test.py:26— get_chat_completion instantiates an OpenAI client pointed at base_url https://janitorai.com/hackathon and calls chat.completions.createbackend/app.py:230— do_chat endpoint calls get_chat_completion with the message history to generate character responses
Deduction/accusation system with win/lose endings based on correct killerVerified
We plan to add a deduction system where players can formally accuse suspects and present evidence, with different endings based on whether you correctly identify the killer
Claimed on Devposthigh confidencefrontend/src/app/accuse/page.tsx:26— handleAccuse compares the selected character to the killer from GameContext and routes to /win or /lose accordinglyfrontend/src/context/GameContext.tsx:61— killer is hardcoded to CharacterId.Daisy in GameContext, confirming a working (if simplistic) accusation resolution system, despite this being listed under future plans in the writeup
Four suspect-contestants to interrogateVerified
You interrogate four suspect-contestants, each with their own motives, alibis, and secrets
Claimed on readmehigh confidencebackend/characters.json:6— characters array defines exactly four characters: Daisy, Sienna, Grace, Drew, each with detailed background/motive/secret text
Group conversations where suspects interact with each otherVerified
A unique feature for our gameplay: group conversations where suspects interact with each other
Claimed on Devposthigh confidencebackend/app.py:71— do_multicharacter_chat drives a turn between two characters, having each respond in sequence and feeding each other's lines back into their own historyfrontend/src/components/Select.tsx:72— Select.tsx lets the player pick two characters and POSTs to /start_multicharacter_chat for a group date
Individual one-on-one 'date' conversationsVerified
The game features traditional individual 'dates' with characters
Claimed on Devposthigh confidencebackend/app.py:192— start_chat and do_chat endpoints handle single-character conversationfrontend/src/components/Select.tsx:61— handleDateSelect posts to /start_chat when maxSelected === 1 for individual dates
Pixel-art visual novel UI with custom dialogue/headshot/progress componentsVerified
The frontend features a pixel-art visual novel aesthetic with smooth animations and custom components for dialogue boxes, character headshots, and progress tracking
Claimed on Devposthigh confidencefrontend/src/components/DialogBox.tsx:136— custom SVG pixel-art bordered dialogue box with a text streaming/typewriter effectfrontend/src/components/CharacterHeadshot.tsx:1— dedicated character headshot component used across select/accuse screensfrontend/src/components/ProgressBar.tsx:32— custom pixel-art SVG progress bar component
Progress bar tracking remaining turnsVerified
With a progress bar tracking your remaining turns, you must use your questions wisely
Claimed on readmehigh confidencefrontend/src/components/ProgressBar.tsx:13— renders an SVG progress bar from cur/max propsfrontend/src/components/Chat.tsx:207— Chat.tsx renders ProgressBar with cur={maxTurns - turns + 1} and max={maxTurns}, decrementing as turns are used
Turn-based conversation system with max turns per characterVerified
Through turn-based conversations, you must piece together the truth
Claimed on readmehigh confidencefrontend/src/data/constants.ts:1— constants define MAX_INDIVIDUAL_TURNS and MAX_GROUP_TURNS used to cap conversation lengthfrontend/src/components/Chat.tsx:199— MessageInput is disabled once turns exceed maxTurns, enforcing turn-based limits
Bespoke multi-agent context management and memory systemCode-supported
We also developed from scratch a multi-agent context management and memory system, in order to incorporate detailed personality profiles, backgrounds, and conditional secrets
Claimed on Devpostlow confidencebackend/app.py:42— MESSAGE_HISTORY is a global dict keyed by character name holding each character's own running conversation, acting as a simple per-character memory storebackend/game.py:17— A separate Game class exists but contains an unreachable/buggy loop (while response: before response is defined) and is not imported or used by app.py, suggesting this system is partial/experimental rather than the primary implementation
Conditional secrets revealed based on conversation topicsCode-supported
Detailed personality profiles, backgrounds, and conditional secrets that are revealed based on conversation topics
Claimed on Devpostlow confidencebackend/characters.json:9— Character descriptions contain conditional instructions like 'ONLY IF you are prompted about the time of the murder, reveal...' but these are natural-language prompt instructions relying on the LLM to follow them; no code enforces or gates the conditionality
Relationship system revealing information based on who is presentCode-supported
We created a relationship system that tracks connections between characters...revealing different information based on who else is present in group conversations
Claimed on Devpostmedium confidencebackend/characters.json:24— relationships array defines pairwise 'reveals' text conditioned on conversation topicsbackend/app.py:158— start_multicharacter_chat injects the relevant relationship 'reveals' text into each character's message history when a group date with that pair begins
Streaming LLM responses in real-time UICode-supported
On the technical side, we gained experience with streaming LLM responses in real-time UIs
Claimed on Devpostmedium confidencebackend/test.py:35— get_chat_completion calls the LLM with stream=False, so the backend does not actually stream tokensfrontend/src/components/DialogBox.tsx:48— DialogBox simulates streaming client-side with a setInterval typewriter effect over the already-complete response text, not true real-time token streaming
Branching storylines affecting character relationshipsClaimed only
Adding branching storylines where player choices affect character relationships and unlock different plot paths would increase replayability
Claimed on Devposthigh confidenceCross-playthrough character memoryClaimed only
We'd love to implement a memory system where characters remember previous conversations across multiple playthroughs
Claimed on Devposthigh confidenceLevel editor for community-created mysteriesClaimed only
We want to create a level editor that lets players craft their own murder mysteries with custom characters, relationships, and secrets
Claimed on Devposthigh confidenceMultiple episodes / new casts of charactersClaimed only
We want to expand the game with multiple episodes featuring different murder mysteries and new casts of characters
Claimed on Devposthigh confidenceVoice acting and character animationsClaimed only
Voice acting and character animations would bring the personalities to life even more
Claimed on Devposthigh confidence
An AI agent derived these features from the project’s Devpost page and readme, then searched the code for each one. Verified features are backed by cited code; claimed-only features had no supporting code, which is not by itself proof a feature is missing.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.