This is a submission for the June Solstice Game Jam
Solstice Cipher is a browser puzzle game where you write real JavaScript to decrypt intercepted messages — inside a full Monaco Editor (the same engine that powers VS Code). Each solved cipher pushes back the night until the June 21 solstice breaks.
🎮 Play:
What I Built
The core loop is simple: read an intercepted transmission, implement decrypt(text) in a live code editor, hit Run decrypt(), and advance if the output matches.
There are 5 cipher levels, each tied to a phase of the solstice day:
| Level | Phase | Cipher | Message |
|---|---|---|---|
| 1 | Pre-dawn | Caesar shift | HELLO WORLD |
| 2 | Sunrise | Atbash mirror | THE COOL |
| 3 | Morning | ROT13 | PRIDE HUMAN |
| 4 | Midday | Vigenère (keyword PRIDE) | BE YOU |
| 5 | Longest Day | Caesar + word reverse | THE LIGHT SHINES |
As you progress, a daylight bar fills from 15% to 100% — the sky literally brightens behind the UI. The narrative is set at Bletchley Park, June 1941, framing each puzzle as a transmission Alan Turing's team might have intercepted.
My intended goal: make a game where writing algorithms is the gameplay — not clicking tiles or guessing letters. The solstice theme isn't just decoration: every level is a step from darkness toward the longest day, and the final win screen lands on June 21 with Turing's own words.
Video Demo
The demo walks through:
- Intro — solstice + Turing context
- Live gameplay — Caesar cipher in Monaco Editor, Run decrypt(), daylight advancing
- Gemini AI hint streaming in with line-specific guidance
- Suggest fix → Monaco diff view → Apply patch
- Win screen — THE LIGHT SHINES
Code
Solstice Cipher ☀
A code-breaking puzzle game for the June Solstice Game Jam on DEV.
Write JavaScript decrypt() functions in a real Monaco Editor (VS Code's engine via @monaco-editor/react) to break ciphers before the June 21 solstice. Each solved level brings more daylight — honoring Alan Turing, Pride, and the passage from darkness to light.
Why this idea targets the prizes
| Prize category | How the game fits |
|---|---|
| Overall theme | Solstice countdown, daylight progression, June 21 narrative |
| Best Ode to Alan Turing | Bletchley Park story, Caesar/Enigma-style ciphers, algorithms as gameplay |
| Best Google AI Usage | Optional Gemini 3.5 Flash hints via API |
Quick start
cd solstice-cipher
npm install
npm run dev
Optional: Gemini AI hints
Create .env in the project root:
VITE_GEMINI_API_KEY=your_google_ai_studio_key
Get a free key at Google AI Studio. Without it, static hints still work.
How to play
- Read the intercepted ciphertext and…
Key files if you want to dig in:
-
src/data/levels.ts— all 5 ciphers, starter code, solutions, narrative -
src/components/GameScreen.tsx— main gameplay loop -
src/components/CodeEditor.tsx— Monaco setup + custom Bletchley terminal theme -
src/utils/gemini.ts— Gemini streaming hints + code fix generation -
src/utils/analyzeCode.ts— local static analysis that feeds the AI context -
src/utils/runUserCode.ts— in-browserdecrypt()execution
How I Built It
Stack
- React 19 + TypeScript + Vite — fast dev, static deploy, no backend
- @monaco-editor/react — the entire gameplay UI lives in Monaco, not a fake textarea
- @google/genai — official Google AI SDK for streaming hints
- Motion — intro/win screen animations
Monaco as the game engine
The editor uses an uncontrolled pattern (defaultValue + ref) so typing feels native — no React re-render on every keystroke, which was critical for a smooth coding experience.
I defined a custom bletchley-terminal theme: phosphor green strings, hazard red keywords, dark CRT background. Line highlighting marks the exact lines Gemini flags as buggy.
For Suggest fix, I use Monaco's DiffEditor — red/green side-by-side diff — with Apply/Dismiss. Patches go through executeEdits so undo works naturally.
Running player code safely
Player code runs in-browser via new Function() with a strict contract: define decrypt(text), return a string. Output is normalized (uppercase, trimmed) before comparison. No network, no server — fully static.
// src/utils/runUserCode.ts — simplified
const fn = new Function(`
${code}
if (typeof decrypt !== 'function') throw new Error('Define decrypt(text)');
return decrypt(${JSON.stringify(encrypted)});
`)
Gemini AI — not a chatbot bolt-on
When VITE_GEMINI_API_KEY is set, Turing Assist activates via gemini-3.5-flash and generateContentStream.
Before any API call, the game runs local static analysis on the player's code:
- Detects untouched starter template lines
- Finds passthrough bugs (
result += charwithout shifting) - Classifies run state:
NOT_RUN,RUNTIME_ERROR,WRONG_OUTPUT,CORRECT - Picks a hint mode: GUIDE, DEBUG, or ERROR
That analysis is sent to Gemini along with numbered source code. The model returns hints that reference specific line numbers — never the full plaintext answer.
Suggest fix is a second Gemini call that returns a fenced code block. Multiple candidates are validated by actually running them against the encrypted input; the first working patch wins. If Gemini fails, a local diff engine compares starter vs solution line-by-line as fallback — the game works fully offline without an API key.
Visual design
Industrial brutalist CRT aesthetic: scanlines, telemetry chrome, Enigma rotor graphic, and a Pride stripe on the intro display. The --daylight CSS variable drives a dynamic sky gradient — the UI literally gets brighter as you solve puzzles.
Interesting decisions
- AI as tutor, not spoiler — system prompts forbid revealing answers; hints are contextual to your broken code
- Streaming hints — text appears token-by-token like a live terminal feed
- Dual fallback chain — Gemini → local analysis → static per-level hints; no dead ends
- Code fix validation — never apply a patch that doesn't produce the correct decrypt output
Prize Category
Best Ode to Alan Turing
This category is the heart of the project.
- Setting: Bletchley Park, June 1941 — the same era Turing cracked Enigma
- Mechanics: Gameplay is writing decryption algorithms — Caesar, Atbash, ROT13, Vigenère
- Narrative: Each level references how Turing learned patterns, saw symmetry in code, and turned hidden truth into clarity
- Win screen: Quotes Turing directly — "We can only see a short distance ahead, but we can see plenty there that needs to be done."
-
UI details: Enigma rotor,
SYS / BP-1941header, Bletchley telemetry framing
The game doesn't just mention Turing — it asks you to think like him: break ciphers by writing code.
Best Google AI Usage
Gemini is integrated as Turing Assist, a cryptography tutor that understands your current code state:
| Feature | How Gemini is used |
|---|---|
| Smart hints |
generateContentStream with system prompt + local code analysis → line-specific GUIDE/DEBUG/ERROR hints |
| Suggest fix | Second call returns a minimal patch; validated by running against ciphertext |
| Fallback | Local static analysis + offline hints when no API key — AI enhances, never blocks |
| SDK | Official @google/genai — not a raw fetch wrapper |
The AI receives structured context (run status, detected issues, numbered code) rather than a generic "help me solve this puzzle" prompt. That makes hints feel like a pair programmer at Bletchley, not a spoiler bot.
Set VITE_GEMINI_API_KEY in .env (free key from Google AI Studio) to enable live AI. Without it, static hints still work.
Quick Start (for judges who want to run it locally)
git clone https://github.com/longphanquangminh/solstice-cipher-encrypt-coding-game.git
cd solstice-cipher
npm install
npm run dev
Optional — enable Gemini hints:
VITE_GEMINI_API_KEY=your_key_here
Tags
#devchallenge #gamechallenge #gamedev #react #typescript #monacoeditor #googleai #gemini
Thanks for reading — and happy solstice! 🌈☀
Top comments (1)
this is such a clever take on the jam theme. Making Monaco the actual gameplay instead of a fake textarea is a great call, it really really feels like you're at a terminal breaking codes.
the daylight bar filling up as you solve each cipher is a nice touch, and I love how Gemini is used as a tutor (line-specific hints) instead of just handing you the answer :D Solid Turing tribute too. Well done bro ~