Skip to main content
LogoJuan Manuel Allo Ron

Solstice Vigil: a solo RPG narrated by Gemma 4 in your browser

By Juan Manuel Allo Ron on Jun 22, 2026
Key art for Solstice Vigil — a wanderer between a frozen gold day and deep blue night

At the June solstice, the sun stopped setting. You are the wanderer trying to keep day and night from tipping over completely.

That is the premise of SOLSTICE VIGIL, a solo narrative RPG I built for the DEV June Solstice Game Jam. Each choice moves a balance meter between the Long Day and the Hush of Night. Push too far and the vigil ends. There is no boss fight — just a count of how many days you held the wheel, what you became along the way, and which strange things you stumbled into.

I wanted it to feel like an old manuscript you could actually play: mythic, a little lonely, not very chatty.

Play it → · Source on GitHub →

What you can do

  • Balance day and night. The meter drives phase, mood, and how close you are to tipping over.
  • Get scenes narrated on your own device. Gemma 4 (E2B) runs in Chrome through Google AI Edge LiteRT-LM and WebGPU. No server, no API key, nothing leaving the machine.
  • Earn identities instead of picking a class. Titles like Ember Saint or Moon Herald show up after your choices pile up.
  • Find rare encounters. Fifteen of them, with a codex, eligibility rules, and cards worth sharing.
  • Roll a d20 on bold choices. Sometimes the solstice pushes back.
  • Turn on speech narration if you want the scene read aloud. Music ducks while it plays.
  • Try demo mode if you do not want to download the ~2 GB model. The full loop works with hand-written scenes.

Demo mode is on the title screen, via ?demo=1, or from the link on the loading screen.

The split that makes it work

The diagram is the important part. JavaScript owns the game: balance, endings, identities, encounters, dice. Gemma gets structured context and returns JSON. It narrates; it does not decide outcomes.

SOLSTICE VIGIL architecture — JS owns game state; Gemma 4 narrates on-device

That split is why on-device generation feels playable past the first few scenes instead of falling apart. If the model were also deciding whether you tipped into eternal day or earned a rare encounter, coherence would fall apart fast. Plain JavaScript handles the rules; the model handles the voice.

Places to start reading in the repo:

  • src/components/game/SolsticeVigil.tsx — game loop, on-device LLM, UI states
  • src/lib/prompt.ts — narrator prompt and turn context
  • src/lib/identity.ts / src/data/identities.ts — inferred wanderer titles
  • src/lib/encounters.ts / src/data/encounters.ts — rare wonders
  • src/lib/dice.ts — d20 resolution
  • tests/ — Playwright unit + E2E (demo mode for CI)

How I built it

On-device Gemma 4

I built this because I wanted to try Gemma 4, and Chrome’s on-device LLM path made that possible without standing up a backend.

The game loads @litert-lm/core from a CDN, pulls the Gemma 4 E2B .litertlm file from Hugging Face, caches it with the Cache API, and streams scene JSON over WebGPU. Save state lives in localStorage. The model narrates; JavaScript decides.

The shell and the manuscript UI

Astro + React was the shell. Static delivery, React island for the game, room to grow if the vigil ever becomes more than one page.

View Transitions handle screen and scene changes. Phase flips and identity reveals feel less like hard cuts that way.

I also went looking for newer CSS worth using. border-shape gives the notched manuscript frames; clip-path covers browsers that do not have it yet. The design spec in the repo (docs/design.md) describes the mood: dark mythic fantasy, gold daylight against cold blue shadow, ruined stone and ritual stillness.

On top of that: Web Speech for optional narration, Gemini for the two soundtrack pieces (The Wheel of Sediment, Vigil of the Still Valley) — same toolchain as The SDLC Song Cycle — and Playwright + TDD because agent-written code looks fine until you actually click through it.

Building mostly from my phone

Most of this was built from my phone. I am a full-time dad, so “can I keep working while away from the desk” was not a bonus constraint. It was the whole point.

I started with a version of my grill-me skill in ChatGPT. What is the loop? Why would anyone share a run? Why solstice, specifically? That argument became the PRD.

Then I moved to Zo Computer and got the first playable prototype working away from my desk: balance meter, phase flip, on-device Gemma, local save. The production app came after that proof.

For visuals I used Google Stitch and ChatGPT to try directions fast. Dense or spacious? Dashboard or manuscript? Gold day or blue night? The spec in docs/design.md is what survived that round.

Desktop Cursor was the one part I could not do on my phone. Once the direction was clear, I ran several implementation plans in parallel. Same shape as the workflow I wrote up in My Current AI Workflow for Building Apps: argue the idea first, prototype early, design before you let agents run loose, ship in small slices, test the behavior for real.

Demo walkthrough

The desktop demo covers the premise, on-device Gemma loading, an identity reveal, a rare encounter, a d20 roll, and demo mode.


Catch up with me on X (twitter):@juan_allo

Share

---

Similar Articles

@2026 Juan Manuel Allo Ron. All Rights reserved

Follow me on X