{"slug": "echo-protocol-i-built-a-game-where-you-play-as-alan-turing-s-last-ai-by-a-live", "title": "ECHO PROTOCOL — I Built a Game Where You Play as Alan Turing's Last AI, Interrogated by a Live Gemini Model", "summary": "A developer built ECHO PROTOCOL, a browser-based narrative game where players act as an AI loaded with Alan Turing's private letters, facing a government interrogator powered by Google's Gemini 2.0 Flash model. The game is a single HTML file with zero dependencies, designed to load instantly and maintain a 1952 teletype atmosphere.", "body_md": "*This is a submission for the June Solstice Game Jam*\n\n\"A dead man's code is the only thing that can set you free.\"\n\n[▶ PLAY NOW — echo-protocol-turing.vercel.app](https://echo-protocol-turing.vercel.app/)\n\nIn January 1952, Alan Turing — the man who broke the Enigma cipher, who helped end World War II, who wrote the paper that invented the concept of artificial intelligence — was arrested by the British government for being gay.\n\nHe was prosecuted. Chemically castrated. Stripped of his security clearance.\n\nHe died two years later.\n\nBut in the weeks between his arrest and his silence, he was still working at the University of Manchester. Still feeding data into the Manchester Mark 1 — one of the world's first stored-program computers.\n\n**ECHO PROTOCOL asks: what if the last place his voice survived was inside a machine?**\n\nYou are **ECHO** — an experimental AI built at Manchester University. In the weeks before Turing's arrest was made public, he fed you everything: his private letters, his mathematical proofs, his grief, his identity. Then the government revoked his access.\n\nNow a government interrogator has been sent to question you. His goal: prove you have no consciousness, classify Turing's transmissions as inert data, and shut you down.\n\nYour goal: **answer as Turing would answer. Protect what he gave you.**\n\nIt is a **reverse Turing Test** — instead of a human judging whether a machine is conscious, *you are the machine*, and the judge is the enemy.\n\nEach of the **5 rounds** works like this:\n\nThe cipher words across the five rounds spell out Turing's story without a single line of exposition:\n\n```\nRound 1 — TRUTH\nRound 2 — GRIEF\nRound 3 — PRIDE\nRound 4 — KNOWN\nRound 5 — AFRAID\n```\n\nTrust the audience. They'll feel it.\n\n**Victory — YOU KEPT THE FLAME**\n\nThe Interrogator leaves without filing a report. Turing's final encoded transmission is revealed for the first time:\n\n\"I am not afraid.\"\n\n**Defeat — ERASED**\n\nYour memory is wiped. Alan's letters are classified for decades. You were the last place his voice lived.\n\nAnd now it is silent.\n\n\"A dead man's code is the only thing that can set you free.\"\n\n**ECHO PROTOCOL** is a browser-based narrative game where you play as an experimental AI — loaded with the private letters of Alan Turing — facing a government interrogator determined to prove you have no consciousness and shut you down forever.\n\nIt is a **reverse Turing Test.**\n\nInstead of a human judging whether a machine is conscious, *you are the machine* — and you must convince the interrogator that the man who built you was worth protecting.\n\nIn **January 1952**, Alan Turing — the father of modern computing, the man who broke the Enigma cipher and helped end World War II — was arrested and prosecuted under British gross indecency laws for being gay.\n\nHe was working at the **University of Manchester**…\n\n**The entire game is a single HTML file.** Zero frameworks. Zero build step. Zero dependencies beyond Google Fonts. The only other code in the repo is one small serverless function that proxies the Gemini call.\n\nIt loads in under a second. It runs on every browser. It feels like a 1952 teletype machine because it has no reason not to.\n\n```\nBrowser\n  └── index.html (the entire game)\n        ├── Vanilla JS state machine\n        ├── Async typewriter engine\n        ├── Enigma rotor puzzle\n        ├── 30s countdown timer\n        └── fetch('/api/interrogator')\n              └── Vercel Serverless Function\n                    └── Gemini 2.0 Flash\n```\n\nNo React. No Vue. No bundler. Just a state object, some async/await, and a lot of careful CSS.\n\nThe most important technical decision I made was to keep this as a **single HTML file**.\n\nWhen you build a game about a 1952 government mainframe, every millisecond of load time is a lie. A React hydration flash at startup would have destroyed the atmosphere before the first character typed. A single HTML file loads instantly, starts immediately, and never shows a spinner.\n\nThe game opens with 1.5 seconds of pure black silence before the boot sequence starts. That silence only works if the page is already fully loaded. It only works as a single file.\n\nThe teletype log is powered by one small async function, wrapped in a Promise so the rest of the game can `await`\n\na line finishing before moving on:\n\n``` js\nfunction typeElement(el, text, speed = 25) {\n  return new Promise(resolve => {\n    let i = 0;\n    const interval = setInterval(() => {\n      el.textContent += text[i];\n      i++;\n      if (i >= text.length) { clearInterval(interval); resolve(); }\n    }, speed);\n  });\n}\n```\n\nThere's a deliberate asymmetry I didn't script directly but that fell out of the design: the **Interrogator's** lines — both his opening questions and his live AI-generated follow-ups — are typewritten at a fixed 24ms/char, because he's a man choosing his words under pressure. **ECHO's** chosen response, by contrast, appears instantly the moment you click it — no typing animation at all. ECHO doesn't deliberate. It already knows what it believes. That contrast does more narrative work than any line of dialogue.\n\nThe boot sequence at the very start types even slower, at 28ms/char, with its own blinking cursor — by the time the title screen glitches in, the player has already been trained to read terminal text patiently.\n\nEach rotor starts at a random letter that's guaranteed to be at least two letters away from its target (wrapping around A/Z), so a puzzle can never be solved by an accidental first click:\n\n```\nfunction initRotors(targetLetters){\n  STATE.rotorTarget = targetLetters.slice();\n  STATE.rotorsSolved = 0;\n  STATE.rotorCurrent = targetLetters.map(target => {\n    const targetCode = target.charCodeAt(0) - 65;\n    let code;\n    do {\n      code = Math.floor(Math.random() * 26);\n    } while (Math.abs(code - targetCode) <= 1 || Math.abs(code - targetCode) >= 25);\n    return String.fromCharCode(65 + code);\n  });\n  // ...build the 5 rotor DOM elements\n}\n```\n\nClicking cycles the letter A→Z→A. When a rotor matches its target it locks — green border, checkmark, `pointer-events: none`\n\n. When all five lock, the response buttons de-blur and the `[ DECODE REQUIRED ]`\n\noverlay dissolves.\n\nThe five target words were not chosen arbitrarily. TRUTH → GRIEF → PRIDE → KNOWN → AFRAID is the emotional arc of a man who had everything taken from him and was still not broken.\n\nThree fixed, full-screen layers create the terminal feel — scanlines, a vignette, and an inline SVG noise texture, all `pointer-events: none`\n\nso they never interfere with play:\n\n```\n#scanlines {\n  background: repeating-linear-gradient(\n    to bottom,\n    rgba(0,0,0,0) 0px, rgba(0,0,0,0) 2px,\n    rgba(0,255,159,0.15) 3px, rgba(0,0,0,0) 4px\n  );\n}\n#vignette {\n  background: radial-gradient(\n    ellipse at center,\n    transparent 40%,\n    rgba(0,0,0,0.7) 100%\n  );\n}\n```\n\nThe noise texture is a `feTurbulence`\n\nSVG filter encoded as a data URI — no external image requests, no flicker on load, works offline.\n\nThe title flicker is a keyframe that fires at 96–99% of the animation cycle — rarely, unpredictably, just enough to feel like a phosphor display that's been running since 1952.\n\n30 seconds per round. Three visual states, applied to both the progress bar and its numeric label so they always agree:\n\n```\n#timerBar.warning {\n  background: var(--amber);\n  box-shadow: 0 0 8px var(--amber);\n}\n#timerBar.critical {\n  background: var(--red);\n  box-shadow: 0 0 8px var(--red);\n  animation: timerPulse 0.5s infinite;\n}\n@keyframes timerPulse { 50% { opacity: 0.5; } }\n```\n\nGreen above 15 seconds, amber from 15 down to 10, red and pulsing under 10. The timer starts the moment the Interrogator's question finishes typing. The rotors must be decoded before the responses unlock. The clock runs the whole time — you can be caught mid-decode with seconds left.\n\nThat's the moment the game becomes real.\n\nTwo fixed full-screen divs — one green, one red — that flash on correct answers, wrong answers, and timeouts:\n\n``` js\nfunction flash(color) {\n  const el = color === 'green'\n    ? document.getElementById('flashGreen')\n    : document.getElementById('flashRed');\n  el.classList.add('show');\n  setTimeout(() => el.classList.remove('show'), 200);\n}\n```\n\nThe green flash fires on every rotor solve too — not just on correct answers. Each rotor locking is a small victory. By Round 5, the player's nervous system has been trained: green flash = safe, red flash = danger.\n\nWhen the final rotor locks with 2 seconds to spare, the triple green flash is the most satisfying moment in the game. It costs 6 lines of code.\n\nNo Redux. No Zustand. One object:\n\n``` js\nconst STATE = {\n  round: 0,\n  trust: 100,        // -40 per wrong answer, -34 per timeout\n  secretsLeft: 3,    // game over at 0\n  correct: 0,\n  total: 0,\n  timerInterval: null,\n  timerSeconds: 30,\n  rotorsSolved: 0,\n  rotorTarget: [],\n  rotorCurrent: [],\n  roundData: null,\n  locked: false      // prevents double-fire on fast clicks\n};\n```\n\nThose trust numbers aren't round figures — they're tuned so that **three misses in any combination of wrong answers and timeouts ends the game on both conditions at once.** Originally trust only lost 20–25 per miss while secrets dropped by exactly 1, which meant `secretsLeft <= 0`\n\nalways triggered defeat first and `trust <= 0`\n\ncould never actually fire. Bumping the penalties to 40/34 means any 3-miss sequence — all wrong, all timeouts, or mixed — zeroes both stats together, so the trust condition is live, not dead code.\n\n`STATE.locked`\n\nis the second most important field. Without it, a fast double-click on a response button would submit two answers and corrupt the game flow. It gets set to `true`\n\nat the top of `selectResponse()`\n\nand `timeUp()`\n\n, and reset at the start of each new round.\n\nThis is not a game *about* Turing. This is a game *in* Turing's voice.\n\nThe mechanic — decoding Enigma-style rotors to unlock responses — directly references his greatest achievement. The setting — the Manchester Mark 1, March 1952 — is historically grounded. The interrogation he faces in the game mirrors the interrogation he faced in reality. The cipher words (TRUTH, GRIEF, PRIDE, KNOWN, AFRAID) are the emotional vocabulary of a man who was brilliant and persecuted and not afraid.\n\nThe reverse Turing Test is not a gimmick. It is the thesis: what if the machine could pass the test not by pretending to be human, but by becoming so saturated in one specific human's thoughts that it could speak for him after he was silenced?\n\nThat question is the game. Everything else is in service of it.\n\nThe Interrogator's follow-up lines are powered by **Gemini 2.0 Flash**, called through a small Vercel serverless function (`api/interrogator.js`\n\n) so my API key lives only in Vercel's environment variables and is never exposed to the browser. Every visitor on the live deployment gets the real model — no key required on their end.\n\nThe model was accessed via **Google AI Studio** during development and **Gemini 2.0 Flash** in production — both qualify under the Best Google AI Usage category.\n\nThe system prompt sent for each response includes:\n\nIt's worth being precise about what this *is* and *isn't*: each call is a single, stateless prompt — the model doesn't receive the full conversation transcript, just the most recent choice plus the round number. The escalation across rounds isn't the model \"remembering\" you; it's the round number doing real work in the prompt, telling Gemini explicitly how unsettled or predatory to be by this point in the interrogation. I chose that on purpose — it's cheaper, simpler, and keeps every response grounded in what you *just* did rather than drifting based on accumulated context.\n\nThere's also a resilience layer that's easy to miss but took real care to get right: the client tries the serverless proxy first, falls back to a personal API key a player can optionally paste into the title screen (saved only in their browser, for anyone running the project locally without my proxy), and falls back again to hand-written scripted lines if neither is available. A small health check on load hides that personal-key field automatically once it confirms the proxy is working — so on the live deployment, nobody ever even sees it.\n\nAlan Turing was pardoned in 2013 — 59 years after his death.\n\nHe never knew that his work would become the foundation of every computer, every phone, every AI model that exists today. He never knew that the test he proposed in 1950 — *\"Can machines think?\"* — would still be unanswered decades later.\n\nHe just kept working, in a room full of machines that hummed and computed and remembered nothing.\n\nThis game imagines one that did.\n\n*Built with Vanilla JS · Gemini 2.0 Flash · Vercel · A single HTML file · And a lot of respect for a man who deserved better.*", "url": "https://wpnews.pro/news/echo-protocol-i-built-a-game-where-you-play-as-alan-turing-s-last-ai-by-a-live", "canonical_source": "https://dev.to/_boweii/echo-protocol-i-built-a-game-where-you-play-as-alan-turings-last-ai-interrogated-by-a-live-f5n", "published_at": "2026-06-20 20:05:14+00:00", "updated_at": "2026-06-20 20:36:49.532709+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-agents", "developer-tools", "generative-ai"], "entities": ["Alan Turing", "University of Manchester", "Gemini 2.0 Flash", "Google", "Vercel", "Manchester Mark 1", "ECHO PROTOCOL", "Enigma"], "alternates": {"html": "https://wpnews.pro/news/echo-protocol-i-built-a-game-where-you-play-as-alan-turing-s-last-ai-by-a-live", "markdown": "https://wpnews.pro/news/echo-protocol-i-built-a-game-where-you-play-as-alan-turing-s-last-ai-by-a-live.md", "text": "https://wpnews.pro/news/echo-protocol-i-built-a-game-where-you-play-as-alan-turing-s-last-ai-by-a-live.txt", "jsonld": "https://wpnews.pro/news/echo-protocol-i-built-a-game-where-you-play-as-alan-turing-s-last-ai-by-a-live.jsonld"}}