Vibecoding Case Study
CyberQuest
Building a Point-and-Click Adventure
with AI — Scene by Scene
Operation ZERFALL · 18 scenes · Sierra-style · Vanilla JS · Zero dependencies
github.com/reinvelt/CyberQuest
Part 1 of 2
The Scene System
How the engine works — before we walk into any scene.
Scene System
Architecture
One folder = one scene
Complete isolation. Any scene can be built, tested, or discarded without touching the others.
scenes/ ├── home/ │ ├── scene.js ← render + hotspots │ └── design.md ← spec (written first!) ├── mancave/ │ ├── scene.js │ └── design.md ├── facility/ │ ├── scene.js │ └── design.md └── ... 18 scenes total assets/images/scenes/ ├── home.svg ← SVG art (made before JS) ├── mancave.svg └── facility.svg assets/images/characters/ ├── ryan_southpark.svg └── eva_southpark.svg ← consistent style

SVG-first strategy

Draw each scene as a complete SVG before writing any JavaScript. The world looks right before anything is clickable. Visual clarity drives better code decisions.

design.md before scene.js

Every scene starts with a written spec: hotspot positions, dialogue, quest triggers, acceptance criteria. AI implements against a contract, not a vague wish.

South Park character style

Consistent SVG art style across all characters. Generated once per person, reused across every scene they appear in. Scales perfectly at any resolution.

Scene System
Engine
The engine: small modules, one job each
CyberQuestEngine coordinates everything. Each sub-system is a separate file — import only what you need.
engine/ ├── game.js ← CyberQuestEngine (1490 lines) │ scene management · save/load (localStorage) │ inventory system · quest tracking │ flag system · dialogue orchestration │ notifications · time progression │ ├── player.js ← movement · walk animation ├── chat-interface.js ← Meshtastic secure chat UI ├── evidence-viewer.js ← investigation cork board ├── voice.js ← optional TTS narration └── puzzles/ ├── cipher.js ← ROT1 decoder puzzle ├── password.js ← frequency unlock └── stealth.js ← laser / sensor bypass

Flag system = story memory

Every player action sets a boolean flag. Scenes read flags to decide what's visible. espresso_made, sstv_decoded, usb_analyzed. The game never forgets what you did.

Scene interface contract

// Every scene.js must export: register() → add self to engine enter() → called on scene load exit() → cleanup hotspots[] → clickable regions
Scene System
voice.js · Web Speech API · Zero external libs
Every character
has a voice.
The narration layer wraps the browser's built-in Web Speech API. No CDN, no bundle. Degrades gracefully when unsupported.
// voice.js — character voice profiles const VOICES = { ryan: { pitch: 0.82, rate: 0.82 }, // low, measured eva: { pitch: 1.10, rate: 0.95 }, // clear, precise ies: { pitch: 1.05, rate: 1.00 }, // warm, casual volkov: { pitch: 0.72, rate: 0.78 }, // deep, deliberate david: { pitch: 0.90, rate: 0.88 }, // professor cadence cees: { pitch: 0.95, rate: 0.90 }, // measured, calm jaap: { pitch: 0.88, rate: 0.93 }, // energetic, precise } // Public API VoiceNarrator.speak(text, character) VoiceNarrator.stop() VoiceNarrator.isSupported() // feature detect // Engine auto-triggers on all dialogue events: engine.on('dialogue', ({ text, speaker }) => { VoiceNarrator.speak(text, speaker) })

When voices trigger

  • Cinematic scenes auto-read the full narration text
  • Clicking a hotspot voices Ryan's inspection comment
  • Dialogue tree responses spoken by each character
  • Evidence viewer reads aloud file excerpts
  • Meshtastic chat plays incoming messages as Eva's voice

Graceful fallback

If Web Speech API is absent, text still renders — voice is pure enhancement. A toggle in the settings overlay lets players disable it. Works best in Chrome and Edge; Safari uses system voices automatically.

Scene System
18 Scenes · 4 Types
Four scene types.
Each built differently.
The type determines what the player can do and what the AI needs to implement.

🔍 Exploration (7 scenes)

Point-and-click space. Hotspots reveal dialogue, add inventory items, set flags, trigger transitions. home, livingroom, garden, mancave, klooster, planboard, debrief.

🖥 Interface (4 scenes)

Full-screen interactive tools: SDR bench with real waterfall, cipher decoder, evidence viewer with cork board, Meshtastic chat terminal.

🎬 Cinematic (4 scenes)

Auto-playing sequences: intro text crawl, TV documentary with three chapters, driving night interior, epilogue reveals. Skippable but lore-rich.

🕵️ Stealth (3 scenes)

Timed multi-step puzzles: drone hunt, facility exterior, laser corridor. Each step uses a real piece of hardware (HackRF, Flipper Zero, Meshtastic) with its actual frequency and protocol.

Scene System
Scene flow · 18 nodes · flag-gated transitions
18 scenes. One connected story.
Each arrow is an engine transition. Yellow boxes are flag gates — locked until the right action sets the flag.
INTRO ──▶ HOME ──▶ LIVINGROOM ──▶ TV DOCUMENTARY ← sets flag: watched_documentary
├──▶ GARDEN ──▶ DRIVING (night) ──▶ KLOOSTER
└──▶ [espresso + doc] ──▶ MANCAVE ──▶ SDR BENCH ──▶ PLANBOARD
USB ANALYSIS ──▶ REGIONAL MAP ──▶ WSRT / ASTRON ──▶ VIDEO CALL
├──▶ DWINGELOO ✦ └──▶ WESTERBORK ✦ ← optional side quests
DRONE HUNT ──▶ FACILITY EXT ──▶ LASER CORRIDOR ──▶ SERVER ROOM ──▶ DEBRIEF ──▶ EPILOGUE
Part 2 of 2
The Story
Scene by scene — the quest, the decision, the tech.
February 9, 2026 · Compascuum, Drenthe · 07:45 AM
Intro
Scene 01 · Cinematic
Intro
Operation ZERFALL
Noir-style scrolling text. Sets the date, the protagonist, the tone. A techno-thriller begins — Ryan Weylant, 55, Compascuum, Drenthe. A quiet hacker life about to end.
"What starts as curiosity becomes a race against time to expose a Russian infiltration operation and prevent mass casualties."
Cinematic · 60s Skippable Sets tone
Home kitchen
Scene 02 · Exploration
Home / Kitchen
Espresso first.
Everything else second.
Ryan's farmhouse kitchen. Canal view over Drenthe fields. Tutorial scene. Doors lead to the livingroom, garden, and mancave — but not yet.
Quest: Make an espresso

Click the espresso machine. Sets espresso_made flag. Without it, the mancave door won't open. "I need coffee first."

Tutorial Gateway scene
Livingroom
Scene 03 + 04 · Exploration + Lore
Livingroom + TV Documentary
Meet Ies. Watch the documentary.
Ies sits with the dogs: Tino, Kessy, ET the pug. The TV shows a documentary about Drenthe's wireless technology pioneers — three people Ryan will need to call later that night.

Documentary: real Dutch science

  • WSRT — Dr. David Prinsloo, TU Eindhoven · phased arrays
  • LOFAR — Cees Bassa, ASTRON · digital low-freq telescope
  • Bluetooth — Jaap Haartsen, Ericsson · invented in Drenthe
Quest: Watch the documentary

Sets watched_documentary. Unlocks the mancave door. Also plants the names of your future allies before you need them.

Mancave
Scene 05 · Investigation Hub
The Mancave
The SSTV terminal wakes up.
3D printer · lasercutter · oscilloscope · server rack · HackRF One · Flipper Zero · Meshtastic. The central hub of the whole investigation. The SSTV terminal that showed only static is now forming a pattern.

Incoming: SSTV terminal

Static → visual morse → ROT1 encoded text. Someone is transmitting on a restricted German military frequency. The signal originates near Steckerdoser Heide.

SSTV signal HackRF One Flipper Zero Meshtastic
SDR Bench
Scene 05a · Interface — Signal Analysis
SDR Bench
Decode the SSTV transmission
Dual-monitor SDR workbench. Left: spectrum analyzer with a sharp spike at 14.230 MHz. Right: real-time waterfall display with SSTV burst patterns. RTL-SDR dongle, blinking status LED.

Real SDR tech, explained in-game

  • SSTV Martin M2 — slow-scan TV, used by amateur radio ops
  • Waterfall = frequency vs time — signals appear as bright bands
  • 14.230 MHz — upper HF band, military/amateur overlap
Quest: Decode the SSTV transmission

Click decoder panel. Renders image: Ryan's house photographed from across the canal + GPS coordinates + timestamp: tonight, Ter Apel Klooster 23:00. Sets sstv_decoded.

Story
Puzzle — Signal Decoding
The ROT1 cipher — a deliberate test
Three layers of obsolete technology stacked on purpose. The sender isn't hiding — they're filtering for the right person.
Received (on SSTV image): "XBSOJOH - QSPKFDU FDIP JT DPNQSPNJTFE - NPWF UP CBDLVQ DIBOOFM - DPPSEJOBUFT GPMMPX - USVTU OP POF" ROT1 decode (shift each letter -1): "WARNING - PROJECT ECHO IS COMPROMISED - MOVE TO BACKUP CHANNEL - COORDINATES FOLLOW - TRUST NO ONE"
Quest: Decipher both ROT1 messages

Shift each letter back one position. Second message: photo of Ryan's own house from today. Message: "WE KNOW YOU ARE WATCHING — MEET AT TER APEL KLOOSTER 23:00 — COME ALONE"

Why ROT1, not AES?

ROT1 is invisible to automated traffic analysis looking for encryption. It's a filter: only someone who recognises a cipher will even notice. The sender chose their audience before choosing their method.

Three red flags stacked

  • SSTV image protocol used to carry text
  • Visual morse on the image itself
  • ROT1 as the "encryption" layer
  • The photo is Ryan's house. Taken today.
Driving at night
Scene 06 + 07 · Exploration + Cinematic
Garden → Driving (Night)
Pack. Prepare.
Drive into the unknown.
Garden scene: Ryan's Volvo by the wind turbines on the German border. Then night interior — Ryan's internal monologue. Burner phone, cash fuel stop, dead man's switch on the server. Old habits.
Decision: Drive to Klooster at 23:00?

Someone photographed your house today. They know your SDR frequency. They either need your help — or they want you to think they do. Ryan decides to go.

Flipper Zero HackRF + Portapack Meshtastic RP Kali Linux (air-gap)
Ter Apel Klooster
Scene 08 · Exploration
Ter Apel Klooster · 23:00
No one comes.
Check under the bench.
Medieval monastery at night. Ryan waits in the shadows. No contact. Circles building — all doors locked. Nearly gives up. Then spots something taped beneath a courtyard bench.

"TRUST THE PROCESS
PLUG IN ONLY ON AIR-GAPPED MACHINE"

The meeting was the USB. Eva's father delivered it quietly — plausible deniability: a retiree visiting a monastery he knows well.

Quest: Find the USB stick

Try every door (all locked). Find the courtyard bench. Adds "USB Stick" to inventory. Sets usb_found.

Story
Air-gapped ThinkPad · Mancave · 02:00 AM
72 hours. Project Echo.
Three files. One README. And a password hiding in plain sight inside Ryan's own SDR logs.
README.txt — from E: "Ryan, if you're reading this, you passed the test. The ROT1, the SSTV, the Klooster — filters to find someone with the right skills and mindset. Project Echo is not defensive research. A system that can hijack any wireless signal within 50 km. Phones. Cars. Pacemakers. Aircraft navigation. evidence.zip password: the frequency where you first heard my transmission, in MHz, no decimals. You have 72 hours before they realize the files are missing. Trust no one. Not even me. — E P.P.S. If you need to reach me, think mesh. 906.875. I'm listening."
Quest: Unlock evidence.zip

Password = the military frequency from the first HackRF recording. Player must check SDR logs. Unlocks casualty reports, test data, Project Echo full schematics.

Marlies Bakker · ECHO-10

67 years old. Grandmother of four. Routine surgery. The ECHO-10 2.4 GHz calibration test knocked out the hospital equipment mid-operation. She died on the table. Cover story: "equipment malfunction." Ryan's hands are shaking — not from fear. From anger.

Story
Decision Point · 3 AM · Mancave
What does Ryan do next?
Four options. One outcome that makes sense for a hacker who doesn't walk away from things that matter.

A — Go to the authorities

AIVD? German Bundeswehr? E's warning: "The people protecting this project have infiltrated military AND intelligence." Call the wrong person → evidence disappears. Ryan becomes the target.

B — Contact journalists

Der Spiegel? WikiLeaks? 72 hours is not enough to verify and publish carefully. And once it's out, Ryan is the foreigner who leaked German military secrets.

C — Verify first. Then decide.

The hacker's way. Don't trust anyone — not the state, not the press, not even E. Find independent RF experts. Verify the schematics and the casualty data. Then make an informed move with 48 hours to spare.

D — Walk away

Delete everything. Destroy the USB. Never happened.
"Option D was never really on the table."

Story · Finding Allies
Scene 04 + Video Call · Real Dutch Science
Three real experts.
Ryan met them on TV that morning.
The documentary wasn't just lore — it was the recruitment briefing. The game rewards watching it.
DR. DAVID PRINSLOO

TU Eindhoven · phased array antenna design · WSRT radio astronomy. Verifies the schematics are genuine and calculates the weapon's 50 km radius. Agrees to testify.

WSRTPhased arrays
CEES BASSA

ASTRON · LOFAR digital low-frequency telescope · previously caught SpaceX Starlink interference. Uses WSRT baselines to triangulate the ZERFALL transmitter: Steckerdoser Heide, 53.28°N 7.42°E.

LOFARTriangulation
JAAP HAARTSEN

Invented Bluetooth at Ericsson in Emmen, Drenthe. Frequency-hopping spread spectrum. Identifies every RF vulnerability in the ZERFALL network — and exactly how to exploit each one.

FHSSBT protocol
WSRT
Real Science · WSRT · Dwingeloo, Drenthe · built 1968–1973
Westerbork Synthesis Radio Telescope
14 dishes.
2.7 km east–west baseline.
12 fixed + 2 movable 25-metre parabolic dishes on a 2.7 km rail track. Aperture synthesis makes them behave as one giant telescope. Frequency range 120 MHz – 8 GHz. Still operational.

How Cees catches ZERFALL with WSRT

  • Correlates all 14 dishes as a single interferometer
  • Synthesises 2.7 km aperture → arc-second angular resolution
  • ZERFALL 14.230 MHz burst localised via baseline delay timing
  • Cross-ref with LOFAR 87 MHz precursor pulses for confirmation
  • Result: 53.28°N 7.42°E — Steckerdoser Heide, Germany ✓
Aperture synthesis 14 × 25 m dishes 120 MHz – 8 GHz
Real Science · ASTRON · Exloo, Drenthe
LOFAR · Low-Frequency Array · 10–240 MHz
100,000+ antennae.
No moving parts.
Europe's largest radio telescope by element count. Core field in Exloo, Drenthe. 38 stations across 12 countries. Everything below 240 MHz is its domain — including things nobody was meant to transmit.

Architecture

  • Two types: LBA (10–90 MHz) + HBA (120–240 MHz)
  • 24 core stations at Exloo · 14 remote stations across NL
  • 14 international stations: DE, FR, UK, SE, IE, PL, FI, LV
  • Beam steered digitally — repoint entire sky in milliseconds
  • COBALT2 correlator in Groningen handles 10 Tbit/s

Cees Bassa's prior work

  • 2020 — detected SpaceX Starlink leaking unintended 150 MHz RF
  • Mapped stray RF noise from Galileo GPS satellite constellation
  • All-sky LOFAR survey established a Drenthe RF baseline — crucial for anomaly detection
LOFAR
LOFAR core field · Exloo, Drenthe

ZERFALL's mistake

Their amplifier design emits 87 MHz precursor pulses before each high-power burst. To any normal receiver: invisible noise floor. To LOFAR: a bright, structured, repeating signal. Cees found it in 3 months of archived all-sky survey data. The timestamps match the energy grid anomalies to the minute.

87 MHz precursorArchived sky survey
Story · Field Detours
Scene 12a + 12b · Regional Map
ZERFALL hides in plain sight
Two optional side quests on the Drenthe regional map — both reveal additional ZERFALL infrastructure at historically significant locations.
Westerbork
Westerbork Memorial

WESTERBORK — 1942–1945 / 2026

WWII transit camp. Ryan spots a surveillance camera on a pole with a pulsing red BT LED — a ZERFALL network node.

Quest: Crack the BT pairing

Flipper Zero reads the 38-key MAC sequence → maps the broader ZERFALL mesh network. Moral weight: surveillance tech at a site of historical atrocity.

Flipper ZeroBT mesh node
Dwingeloo
Dwingeloo · 25m dish · 1951

DWINGELOO — Hydrogen Line Relay

First mapped the Milky Way's spiral arms. Ryan detects a structured signal at 1420.500 MHz — just 500 Hz offset from the hydrogen line (1420.405 MHz). Covert relay transmitter cable-tied to the dish mount. ZERFALL uses heritage infrastructure as cover.

1420.5 MHzH-line offsetRelay node
Drone hunt
Scene 13b · Stealth — Action Sequence
Drone Hunt · 2 km from facility
GPS spoof the thermal drones
Forest perimeter. Surveillance drones with FLIR thermal imaging are sweeping for movement. A five-phase puzzle built around one educational fact: civilian GPS has zero authentication.
Quest: Clear the drone perimeter

① Deploy Meshtastic RP as LoRa decoy on 868 MHz
② Hide from FLIR — no body heat visible
③ HackRF: set 1575.42 MHz (GPS L1 C/A), TX −5 dBm, offset target 200 m south into the bog
④ Drones follow fake coordinates → crash in swamp
⑤ Proceed to facility

HackRF 1575.42 MHz GPS L1 spoof Meshtastic 868 MHz
Facility exterior
Scene 14 · Stealth
Facility Exterior — Night
Flipper Zero meets the gate.
Steckerdoser Heide military R&D facility. Searchlights. Two security cameras, barbed wire perimeter, RFID gate. Eva guides from the car via Meshtastic 906.875 MHz.
Quest: Disable camera + enter gate

Flipper Zero IR analyser → identify 38 kHz modulation → replay shutdown command to kill the camera. Then replay the captured RFID signature (from the Westerbork node) to open the gate lock.

Flipper Zero IR RFID replay Meshtastic 906.875
Laser corridor
Scene 15a · Stealth — Security Gauntlet
Laser Corridor — Basement
Three layers.
Three tools. One door.
Underground corridor. Animated laser grid, red alert lighting, sparking conduits. Each security layer maps to a real-world bypass technique using hardware Ryan is already carrying.
Layer 1 — Laser Grid · IR

Flipper Zero IR analyser: identify 38 kHz pulse modulation → replay shutdown command.

Layer 2 — Ultrasonic Motion Sensors

HackRF: jam Doppler motion sensors at 40 kHz with targeted overpower interference.

Layer 3 — Biometric Door

Enter Eva's emergency override code: 2847. Server room unlocks.

Server room
Scene 16 · Climax
Facility Server Room
Volkov. Evidence.
The end of ZERFALL.
The climax. Access Volkov's terminal. Download evidence — everything Project Echo tried to bury. Volkov walks in. Chris Kubecka and Bundeswehr MPs arrive. Eva steps into the room and makes the arrest herself.
Quest: Download the ZERFALL master files

Access terminal, authenticate, transfer all evidence. Sets evidence_downloaded. Triggers the final confrontation and ending sequence.

Dr. Volkov Eva Weber Chris Kubecka Bundeswehr MPs
Story — Ending
Scene 17 + 18 · Debrief + Epilogue
Three months later.
Spring in Compascuum.
AIVD debrief in Zoetermeer. Then May 2026. The aftermath of Operation ZERFALL.
Debrief
Scene 17 · AIVD HQ · Zoetermeer

Epilogue: where they ended up

  • Facility shut down · Volkov awaiting trial · The Hague
  • Eva testified to the German Bundestag
  • Chris Kubecka published the ZERFALL technical report
  • Cees Bassa back at ASTRON — as if nothing happened
  • Jaap Haartsen founded an RF security consultancy
  • Ies was not surprised. Tino, Kessy and ET were not consulted.
  • Ryan took the AIVD offer.
Decision: Take the AIVD offer?

Agent Van der Berg makes the offer during the debrief. "We could use someone like you." Ryan has until the credits roll to decide.

Fully playable · Open source · Zero dependencies
Play CyberQuest
2–4 hours · 18 scenes · A whole adventure built with AI, one step at a time.
18
Scenes
200+
Doc pages
0
Dependencies
72h
In-game clock
4
Scene types
▶ PLAY NOW github.com/reinvelt/CyberQuest