Mia Schwartz

One Night Ultimate: Fordham Edition

Background

A peer group at Fordham obsessively played a game called One Night Ultimate: Werewolf edition. This game defined their hangouts and became a central activity to every get-together. Every member grew a personal connection to the game, but this personal aspect ended with a mass-produced physical game and app. Thousands of people can buy the game and download the app, but nobody else has One Night Ultimate: Fordham Edition. By using the group members' own images and voices, I created custom packaging, characters, audio files, and a full-stack companion web app. Their kinship is memorialized in ONU: Fordham Edition.

Product Philosophy

For the full-stack web app, the core of decision-making was centered on clean functionality. The app would primarily be used on a phone for its easy accessibility, so mobile development was prioritized. With the app, users would be able to:

  • Select and de-select characters
  • Play and Pause narration for the selected characters
  • Input responses for unique character scenarios
  • Start and Pause a timer for the game round
  • Adjust the volume for background and character audio

Product decisions depended on whether a feature added significant development time, was necessary for core functionality, or improved the user experience. The original game features many customizable settings, but the primary audience for this application doesn't need all that extra functionality. I stripped it down to the minimal number of features first, and then added on from here.

Key Features

Physical Components

In addition to the web app, there was a comprehensive physical build to this project. Without getting into too much detail here, the scope of the physical manufacturing process included a custom printed box, 14 unique role tiles, 17 tokens, and a comprehensive rulebook with detailed role descriptions for each character, mapped to the 14 members of the group.

Character Selection and Narration Flow

The core functionality that is required for an MVP of this product is the ability to select and deselect the characters. This step allows players to select only the characters they plan on using for that round. The selection feature creates the necessary foundation for the narration flow. Depending on the selected characters, audio files will play in a specific order which was predetermined by the rules of the game. In order to enhance the experience of playing, I added the ability to play and pause the narration for real-life scenarios where players need to pause, but they don't want to restart the round.

User Input for Unique Characters

Certain characters require user interaction to determine what the next audio line will be. The user may respond by tapping a Yes or No button to a question or by entering a number between 1-10. This only applies to a few characters, and only if they're selected for that round.

Timer

A key aspect of the game is the ability to start a timer within the app. For a simpler UI, the timer is only accessible when there are no characters selected. This happens so that the Play and Timer buttons don't get easily mixed up. Users can adjust the length of the timer, and a unique audio sound will signal the end of the timer.

Settings

The newest feature is the settings capability. This gives users the ability to adjust the volume of the background and character audio. Since it was easy to implement and improved the user experience by giving them more control, I decided to add this feature, however it isn't necessary to use the overall product.

Architecture and Technical Decisions

System Design

The app is entirely client-side, communicating directly with S3 rather than through a traditional backend. This was a deliberate choice — the goal of this project was to focus on front-end development, and there wasn't a need for heavy server-side logic or persistent user data beyond the current game session.

Audio is organized by role, with each character's lines numbered in sequential order to control playback. Characters with interactive user input required additional mapping, since different responses lead to different lines — though the first and last line for every character stayed constant, which simplified testing. In S3, files follow the same logic: organized by character and naming convention, numbered sequentially for most characters, except those with interactive options, which required a different structure to account for branching lines.

Build Process & Debugging

The build order was front-end first, then the content database, then the audio logic. In hindsight, the database and audio logic should have come first — that section was the hardest to debug, partly because AI-generated code introduced errors I wasn't experienced enough in JS to catch at the time, including repeat code that only triggered when specific subsets of characters were selected rather than all of them, making the bugs inconsistent and hard to reproduce. Verifying the audio sequencing logic also required manually testing the probability ratios for specific roles to confirm lines triggered correctly and in order.

Early on, the audio logic was initially built in PHP, but quickly pivoted to JS once it became clear JS handled the audio content type better. Since little had been built yet, the switch was a relatively quick correction rather than a costly rebuild.

Deployment

GitHub Pages was chosen because it's free, static-site-friendly, and easy to update going forward.

Tech Stack

Front End

  • HTML
  • CSS
  • JS

No libraries, no frameworks, just straight JS with CSS and HTML for styling and markup. Kept it simple for a straightforward learning experience.

Infrastructure and Tooling

  • AWS S3
  • GitHub
  • ElevenLabs
  • ChatGPT
  • Claude Code
  • Cursor

The two main learning curves here were familiarizing myself with AWS S3 and learning which tools to use for design, audio, and programming. ElevenLabs handled audio generation from a script and voice capture, ChatGPT created custom images, and Claude Code plus Cursor aided in programming the web app to bring everything together.

Lessons Learned

Claude Code and Cursor served very different roles for me, and together they showed me both the benefits and the harms of relying on AI throughout development. Claude Code helped me develop code, but I was still the primary decision-maker. Cursor often took over and developed too fast, to the point where I had no idea what it was actually coding. It was doing a lot of unassisted work, which led me to leave Cursor completely and move to Claude Code.

Working with AI as a coding tool taught me that it needs proper direction and a critical eye to produce something efficient and not overly buggy. That critical eye is a skill that only grows with experience, and I'm still building it.

If I were to do this again, I would map out the unique audio scenarios upfront instead of testing every use case as I went. That would have saved time during the hardest part of development to debug.

I also learned that building an accessible web app means testing across real browsers. I had some exposure to cross-browser issues in my professional work before, but this project gave me a much better understanding of the actual root causes behind these bugs, like inconsistent metadata between file types.

Future Improvements

  • Refactor the code. There's a lot of extra code right now causing audio to misfire at times, especially on mobile, so I plan on rewriting the entire audio script so that every line has a purpose.
  • Fix minor visual bugs, like the background image having blank sections on the sides in the mobile version.

The primary functions now exist, so the rest of development will focus on improving and polishing the overall app experience.