LOOP game: notification banner reads 'Unknown: Dont send that message to Jess' while the player is already in the Jess conversation, having typed 'help'

Coding  ·  NYU ITP  ·  2025

LOOP

You were always on both ends.

A narrative phone-simulation game. You receive a text from an unknown number. They claim to be you — 24 hours from now. There is no first version.

p5.js GPT-4o-mini Web Audio API Interactive Narrative
Role Design + Code
Context NYU ITP — Chatbots for Art's Sake
Stack p5.js · GPT-4o-mini · Web Audio API
Year 2025

Chatbots for Art's Sake

The interface
is the narrative.

Every visual choice in LOOP is part of the story. The monospace clock. The reminders widget with "call dr. about appointment." The bedroom camera that stays offline for the entire game — until it doesn't. None of that is in the chat. The environment creates dread before the bot says a word.

LOOP looks 95% like a real iPhone. That 5% is where it lives. Dread comes from familiarity. The design principle is restraint over spectacle: the scariest version of this interface is the one that almost passes as normal. Cheap horror uses distorted fonts. LOOP uses mundane reminders and a camera feed that says "Last Updated: 3 seconds ago."

LOOP Home Cameras screen: Front Door live, Back Door infrared night vision, Bedroom Window offline with a MOTION alert in red

Home Cameras — CAM 04 offline. Motion detected.

01 The Interface

Every screen in LOOP is built from scratch in p5.js and HTML. The lock screen shows a real ticking time and a notification from "Unknown." The home screen has a reminders widget with items like "call dr. about appointment" — mundane enough to feel real.

The home camera app shows three feeds: Front Door (live, night vision), Back Door (last updated 3 seconds ago), and Bedroom Window, offline with a red MOTION alert. That camera goes offline as a design choice. Something is there. The game never explains it.

Screen cracks run down the right side of the phone frame. The audio layer adds glitch sounds, a pulsing alarm, and an iOS-style text ping. None of it is labeled. The wrongness is in the details.

LOOP home screen: reminders widget showing 'call dr. about appointment' and 'pick up prescription', dock with Messages (4 unread), Reminders, and Home Camera

Home screen — reminders widget, dock, LOOP wordmark

LOOP betrayal UI: notification banner reads 'Unknown: i know you're trying to text Jess. don't. i am you. i know.' appearing over the open Jess conversation

When you tap any other contact and try to message them — Unknown fires a notification instantly. The code watches the messages list. Every contact click is intercepted.

02 Story Engine

The bot is GPT-4o-mini on the NYU ITP/IMA proxy. A 200-line system prompt drives three acts, each with its own voice rules and advancement conditions. The hardest design problem was the chatbot voice: it had to feel like a scared person texting at midnight — not a bot, not a philosopher.

That meant hard constraints: no metaphors, no exclamation points, no therapy-speak, never start with a capital letter, two sentences maximum. The prompt is more about what it cannot say than what it should. Act advancement is tracked in JavaScript — turn counts, silence timers, betrayal state — and the bot receives a tagged response; the code handles state transitions.

Act 1 Calm. Careful.

You're texting from an unknown number. Patient, lowercase, like someone who has had this conversation before and is trying to do it right this time.

Act 2 Urgent. Controlling.

Seven instructions, one at a time. Don't go outside 2–4pm. Don't answer the door. Let unknown calls ring. Each requires conversation before the next is given.

Act 3 Fragmenting.

Messages get shorter. Sometimes one word. Signal dropping. The loop closes. "there is no first version." The only exit: set a reminder for 11:47 tomorrow.

"who is this"  /  "it's you. from tomorrow."  /  "that makes no sense"  /  "i know. i said the same thing."
03 Four Endings

The game tracks not just what the player says in the main chat, but whether they opened the camera app, whether they tried texting a contact, whether they went silent. Four endings, each triggered by a different kind of behavior.

Ending D — the betrayal path — is the one players find by accident. The contacts list is fully interactive. You can open Jess, Tyler, Maya, and type. The game watches. If you try to warn someone else, the unknown number already knows.

Ending A

Break the Loop

You refuse to send the message. Tomorrow's version of you receives no warning. They go outside at 2pm. They answer the door.

Ending B

Stay in the Loop

You set the reminder. Another version of you will receive this message at 11:47 tomorrow. The chain has no origin and no end.

Ending C

You Became the Sender

Three silence timeouts. The bedroom window camera — offline, motion detected — comes to life. The horror sequence begins without you.

Ending D

You Told Someone

You texted Jess to explain. The notification arrives instantly: "dont send that message to jess." The unknown number was watching the whole time.

Ending C — SOMEONE IS HERE: camera app turns deep red, Front Door shows SIGNAL LOST, Back Door shows BREACH DETECTED, Bedroom Window shows MOTION — RECORDING

Ending C — silence triggers the camera horror sequence. The bedroom window, offline all game, starts recording.

D

How it was built.

01

The interface is the narrative.

Every visual choice — the monospace font, the dark field, the cyan accent — is part of the story, not decoration around it. The game doesn't have a theme applied to a chat app. The chat app is the story.

02

Restraint over spectacle.

Dread comes from what is almost normal. The scariest version of this interface looks 95% like a real iPhone. No distorted fonts. No gore. A reminders widget with "call dr. about appointment" is more unsettling than any jump-scare.

03

Fragmentation is intentional.

As the story collapses in Act 3, the design earns the right to break. But only because Acts 1 and 2 held. The horror of Act 3's one-word messages is that you remember what full sentences felt like.

04

The paradox must be felt, not explained.

LOOP never uses the words "time loop." The visual design makes you feel the loop before the text tells you about it — because if it had to be explained, it wouldn't land.

05

Every screen is a proof of work.

The kind of detail a viewer zooms in on to see if it holds up. The camera timestamp. The unread badge count. The screen crack on the right side. It has to hold up. A portfolio piece that doesn't survive scrutiny isn't a portfolio piece.

R

What I took away.

Constraining the bot's voice was the hardest design problem.

Every LLM wants to be helpful, verbose, emotionally validating. Every line in the LOOP prompt had to fight that. The result — two sentences, lowercase, no metaphors, never say "I understand" — was more about prohibition than prescription. The voice only worked once I stopped writing what the bot should say and started writing what it could never say.

Behavioral tracking is what makes interactive fiction feel authored.

Players who find Ending D almost always think the betrayal path was written just for them. That recognition — "it knew I would try that" — is the game's best moment. It only exists because the code watches the messages list, the contacts, the silence timer. The feeling of being observed is produced entirely by observation.

The audience and the protagonist are the same person.

LOOP works because the player is alone, late at night, on a phone. The dread is personal. Portfolio viewers arrive as an audience and leave as participants. Players arrive as participants and leave with the uneasy feeling that the loop already started before they picked up the phone.

Next project

Under the Weather