This is a submission for the Sanity Challenge, Path Two: Vibe-Code Something Strange.
What I Built
Before Daybreak is a short, replayable story about the cost of keeping your word.
Four people are trying to leave a company-controlled site with evidence of concealed injuries. The people controlling the exit offer passage in return for silence. Two witnesses are still inside. You have three decisions: how to handle the offer, what to prepare, and whether to honour your promise.
The interesting part is that the same final action can cost a different person. An earlier conversation establishes who puts their name behind the deal. Break it later, and that person bears the extra detention. Preparing the report instead changes which version you can release. These dimensions meet at the ending.
After playing, you can revisit a decision. The game preserves your previous ending and shows which consequences changed—and which did not. There is no hidden loyalty score or percentage telling you whether you were a good person.
Demo
No player account is required. Select Enter the story, read each scene and make three decisions. Then revisit an earlier choice from the ending.
For a quick comparison: give Alex a private hearing, secure six passes, then publish the original. Revisit decision one, bring everyone into the discussion, and make the same two later decisions. The guarantor—and the person detained—changes. The harm of exposing the witnesses does not disappear.
Code
Public source repository — browse the app, Sanity schema, story seed, review tool and tests directly. The ZIP is an optional snapshot.
The implementation uses Next.js, React and Sanity Studio. The source package includes the story, content schemas, import seed, runtime, graph validation and tests. It requires no paid AI service during play.
My Build Process
I worked with Codex, using AI for implementation, rewriting, testing and design critique. My contribution was to challenge what we were building and whether it made sense to a player.
The first attempt was a warehouse investigation. It was functional, but the packing-lane metaphor got in the way. A conventional detective-game suggestion followed. I challenged that too: other people using AI could receive the same recommendation.
We moved towards trust, betrayal and consequences. I asked the assistant to think dimensionally about branches: a decision should change the conditions of later decisions, not just choose another paragraph.
One proposed dilemma involved a damaged lift, four passengers and medicine. A review exposed the obvious questions: why not split the medicine or take another trip? We dropped the lift. The final conflict concerns public disclosure, source protection and a negotiated agreement, where copying the report does not solve the disagreement.
The early story still had an opening choice that changed little beyond dialogue. We made the guarantor explicit so that the opening could materially alter the outcome of a later broken promise. The player is warned of that responsibility before the final decision.
Sanity integration exposed another mistake. I initially used dotted document IDs. The signed-in editor could read them, but an unauthenticated player could not. We checked Sanity's documented ID rules, changed the public story to root-level IDs and added a regression check. Public reads use no token; adding a secret to the frontend was not the solution.
Automated checks traverse every reachable sequence and verify reconstruction from Sanity documents, missing references, permitted effects, ending coverage and saved-choice replay. Browser checks cover refresh recovery, the guarantor branch, revisiting decisions and comparing endings. These establish that the mechanisms work; they do not prove that the story is compelling or that it will win.
Sanity Project Details
Project ID: o1wtlllc
Dataset: production
Published episode document: bd-episode
Thirty-six linked documents organise the episode:
- Characters describe identity and motive.
- Facts record what is known and who initially knows it.
- Scenes reference ordered choices and disclose information.
- Choices have explicit conditions, effects and recorded consequences.
- Ending fragments are selected by combinations of state, in author-controlled order.
Sanity stores the relationships and narrative fragments. The app uses a bounded evaluator, so content can change behaviour without containing executable code. A custom Studio review tool checks the published graph and all reachable paths. The public Behind the story page reports whether the app is using Sanity or its labelled fallback sample.
This uses a customised Studio tool. It does not claim use of the separate App SDK or Workflows product. Player choices remain in local browser storage and are not sent to the Content Lake.
Agent Session
No raw private transcript is included. The build account above describes the decisions, mistakes and corrections. Any optional session excerpt would need a separate review before publication.



Top comments (0)