💡 Inspiration

Most group chats don't go quiet because people stop caring. They go quiet because nobody wants to be the awkward first person to say "hey, anyone still here?"

We kept seeing it ourselves — a study group, a trip chat, a hackathon team — alive for a few days, then silent. The problem isn't a missing message. It's the social cost of sending the first one.

So instead of nudging one person to restart the conversation, we asked: what if the group itself became the game? Roll Call is our answer — a low-pressure, playful reason for a quiet Zymix group to come back to life.

🎲 What it does

When a Zymix group has been inactive for ~3 days, a small prompt appears in the chat: start a quick adventure? One tap is all it takes.

  • AI generates a cold-open story and assigns every member a role.
  • On each turn, a player picks an action (or types their own) and rolls a D20.
  • The dice decide success, failure, or a new twist — and the AI writes the next beat around what just happened, keeping the story continuous.
  • Friends outside Zymix can be pulled in via WhatsApp to drop a Fate Card — a temporary event, clue, rule, or condition that bends the story.
  • At the end, AI produces a shareable ending card with the final story and the highlight moment.

The whole thing is built to run in about 3 minutes — short enough to lower the barrier, fun enough to restart the chat.

🛠️ How we built it

Stack: Next.js 14 (App Router) · TypeScript · Tailwind · Zod · Vitest, with Z.ai GLM-4.6 as the creative engine and Manus for UX/UI design.

The game runs as a state machine: cold → loading → choosing → rolling → playing → ended, backed by thin API routes (/api/quest, /api/roll, /api/fate, /api/questcard).

AI acts as a lightweight Game Master. All prompt construction lives in pure, testable functions in lib/director.tsbuildQuestPrompt, buildProloguePrompt, buildActionsPrompt, buildRollPrompt, buildFateCardPrompt, buildQuestCardPrompt. Each call asks GLM for strict JSON, which we then validate.

A core principle we set early: GLM output is untrusted. Every response is parsed through a Zod schema before it touches the UI; a parse failure isn't an error, it's a fallback trigger. We even built a GLM_OFFLINE switch that runs the full game on deterministic fallbacks — so the demo can never crash, even with no network.

To keep the story coherent across turns, the GM passes a running story state (clues, relationships, location/character status, active consequences) into each roll prompt, so consequences persist instead of resetting every round.

🧗 Challenges we ran into

  • Making AI output reliable. LLMs love to return "almost JSON." Wrapping every call in Zod + a fallback path was the single most important decision for a stable demo.
  • State across Next.js route boundaries. Each API route is its own module, so a normal in-memory store kept getting wiped. We used a globalThis-based quest store to survive module boundaries and hot reloads.
  • Story continuity. Early versions felt like disconnected scenes. Passing an explicit story-state object into each prompt fixed the "the AI forgot what just happened" problem.
  • Tone & safety. Every prompt is constrained to a witty, Gen Z, safe register — no violence, explicit, or hateful content — while still feeling high-stakes and fun.
  • Time pressure. We stayed test-aware (dice, schema, fallback, director, store all unit-tested) but pragmatic, focusing coverage on the paths that would break a live demo.

📚 What we learned

  • Treating AI as an untrusted input — validate, then fall back — is what turns a flaky AI feature into a shippable product.
  • A small, explicit state contract beats a bigger prompt every time for continuity.
  • The hardest part of a "social" feature isn't the tech; it's lowering the social cost of the first move. Designing for that changed the whole product.

🚀 What's next

  • Deeper Zymix integration (real inactivity triggers, in-chat surfaces).
  • More adventure themes and richer Fate Card mechanics.
  • Persistent group "lore" so each session builds on the last.

Team 49B — Suzy Su (backend & narrative) · Xiaomin Fan (frontend & art) · concept by both Track: Vibe with ZYMIX · Challenge 2: Entertainment Mini AI: Z.ai GLM-4.6 (story & game logic) · Manus (UX/UI)

Built With

Share this project:

Updates