From Prompt to Playable: Using AI-Assisted Coding to Turn Enzyme Science into an Interactive Outreach Tool for Elora Therapeutics
When we needed a way to make enzyme therapy tangible for investors and the public, we turned to vibe coding and built an HTML5 game from scratch using nothing but natural language prompts and a single afternoon.
Microplastics have been detected in human blood, lungs, and the placenta, and in over a dozen organ systems, with studies finding an average concentration of 4.2 particles per milliliter of blood in healthy adults. At Elora Therapeutics, the mission is to develop the first FDA-targeted enzyme therapy capable of degrading polyethylene terephthalate (PET) microplastics inside the human body. Explaining that science to investors, journalists, and the general public, however, is a different kind of challenge. Slide decks and white papers communicate the data, but they rarely create the visceral, emotional connection that drives someone to champion a cause.
The question became: how do you make enzymatic degradation of synthetic polymers feel real and immediate?
The answer was a video game.
MicroPlastic Blaster puts the player in control of a human cell under siege, firing enzyme projectiles at waves of incoming microplastic particles. The gameplay directly mirrors the therapeutic mechanism of action: FAST-PETase enzymes intercept and degrade PET fragments before they can damage cellular structures. Rather than hiring a game development studio or spending weeks learning a framework, the entire project was built using Vibe Coding, the AI-assisted development paradigm coined by Andrej Karpathy in February 2025, which uses natural language prompts to replace traditional line-by-line programming. The technology stack was deliberately minimal: vanilla JavaScript and HTML5, packed into a single .html file with zero external dependencies. This was not an accident. JavaScript game code is the most richly represented genre in LLM training data, which means AI models can generate, debug, and iterate on it with remarkable fluency. A single-file architecture also meant the game could be deployed to any web server, embedded in WordPress as an iframe, or shared as a simple link in a pitch deck, all within minutes of completion:
| Factor | JS + HTM | Phaser.js | React Game | Pygame |
|---|---|---|---|---|
| Single-file deploy | Yes | CDN needed | Build step | Not browser-native |
| Iframe embed | Trivial | Possible | Complex | No |
| LLM code generation | Excellent | Good | Moderate | Not web |
| Time to deploy | < 1 hour | 2–3 hours | 4+ hours | N/A |
| Mobile support | Touch events | Built-in | Varies | No |
The development process followed a structured six-hour timeline:
Over the next day, the game evolved through 62 distinct versions, growing from a bare-bones prototype into a richly featured experience with co-founder power-ups, VC Coin mechanics, leaderboard persistence via localStorage, and a heads-up display that tracks kills by polymer type. The result is a tool that is simultaneously memorable, shareable, educational, and brand-aligned, precisely the qualities that make it effective as a fundraising and outreach asset.
Design Evolution From Prototype to Version 115: One thing I found useful is that defining a fairly strict architecture from the start enabled easier, rapid LLM-driven iteration. The codebase is organized into clearly separated concerns so new enemies, facts, and power-ups can be easily added as the game evolves. This modularity meant that each vibe coding prompt could target a specific section without destabilizing the rest. The game grew from roughly 200 lines in version 1 (31 KB) to over 2,000 lines in version 115 (66 KB), yet the single-file discipline was maintained throughout, and I was pleasantly surprised by the lack of file-size bloat.
├── CSS Styles (responsive, dark sci-fi biotech theme)
├── HTML UI (start screen, HUD, game-over screen)
└── JavaScript
├── Configuration (MP_TYPES, FACTS, POWERUP_TYPES)
├── Drawing Functions (drawBackground, drawCell, drawMicroplastic, etc.)
├── Game Logic (spawn, fire, collision detection, power-ups)
├── Game Loop (update → render → requestAnimationFrame)
└── Event Handlers (click, touch for mobile)
Microplastic Type Definitions: Each microplastic type maps directly to a real polymer class, with scientifically motivated attributes controlling gameplay behaviour.PET particles are the slowest but toughest, reflecting the real-world challenge of degrading crystalline PET. Each polymer is rendered with a unique shape (jagged, foam, circle, block) so players learn to visually identify different plastic types:
const MPTYPES = [
{ name: "Polypropylene", short: "PP", color: "#ff4757",
size: 20, speed: 0.8, hp: 1, points: 15, shape: "jagged" },
{ name: "Polyethylene", short: "PE", color: "#ffa502",
size: 22, speed: 0.7, hp: 2, points: 20, shape: "foam" },
{ name: "Polystyrene", short: "PS", color: "#7bed9f",
size: 18, speed: 0.95, hp: 2, points: 25, shape: "circle" },
{ name: "Polyethylene terephthalate", short: "PET", color: "#a29bfe",
size: 24, speed: 0.6, hp: 3, points: 30, shape: "block" }
];
Power-Up System: Power-ups map directly to Elora’s therapeutic pipeline and fundraising narrative. FAST-PETase activates triple-shot enzyme streams, mirroring the engineered variant’s enhanced catalytic efficiency over wild-type PETase. The VC Coins power-up introduces a fundraising mechanic: collecting coins slows disease progression (microplastic speed), visually reinforcing the message that investment directly translates to therapeutic impact:
const POWERUPTYPES = [
{ name: "FAST-PETase", color: "#00e5ff", emoji: "⚡",
effect: "rapid", duration: 6000 },
{ name: "Enzyme Boost", color: "#ffd32a", emoji: "💪",
effect: "power", duration: 6000 },
{ name: "Cell Repair", color: "#ff4757", emoji: "❤️",
effect: "heal", duration: 0 },
{ name: "Chain Reaction", color: "#a29bfe", emoji: "💥",
effect: "blast", duration: 4000 },
{ name: "VC Coins", color: "#facc15", emoji: "💰",
effect: "vc-slow", duration: 5000 }
];
Enzyme Firing Mechanics: The fireEnzyme function calculates projectile trajectories from the cell toward the player’s click/tap target. Co-founder power-ups produce dramatically different firing patterns:
function fireEnzyme(targetX, targetY) {
const startX = GAMEWIDTH / 2;
const startY = GAMEHEIGHT - 80;
const angle = Math.atan2(targetY - startY, targetX - startX);
const baseSpeed = 9;
const speed = vcSpeedActive ? baseSpeed * 0.5 : baseSpeed;
if (enzymeType === "marc") {
playSound("shoot-marc");
const streams = 7;
const spread = 0.4;
for (let i = 0; i < streams; i++) {
const t = i / (streams - 1);
const a = angle - spread / 2 + spread * t;
enzymes.push({
x: startX, y: startY,
vx: Math.cos(a) * speed * 1.3,
vy: Math.sin(a) * speed * 1.3,
size: 7, color: "#22d3ee",
damage: enzymePower * 10,
style: "marc"
});
}
return;
}
// Standard enzyme fire...
enzymes.push({
x: startX, y: startY,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
size: 6, color: "#00e5ff",
damage: enzymePower * 0.5
});
}
Collision Detection: Collision is computed using Euclidean distance between enzyme projectiles and microplastic particles. Destroyed particles trigger cascading visual effects and score updates:
function checkCollisions() {
const cellX = GAMEWIDTH / 2;
const cellY = GAMEHEIGHT - 80;
for (let i = enzymes.length - 1; i >= 0; i--) {
for (let j = microplastics.length - 1; j >= 0; j--) {
const e = enzymes[i];
const m = microplastics[j];
if (!e || !m) continue;
if (Math.hypot(e.x - m.x, e.y - m.y) < m.size + e.size) {
m.hp -= e.damage;
enzymes.splice(i, 1);
if (m.hp <= 0) {
playSound("destroy");
score += m.points * level;
killCounts[m.short]++;
effects.push({
x: m.x, y: m.y,
type: "explosion", color: m.color, alpha: 1, radius: 5
});
microplastics.splice(j, 1);
}
break;
}
}
}
}
Sound Synthesis Without External Files: All sound effects are generated procedurally using the Web Audio API, keeping the game truly zero-dependency, although in later version I did add MP3 files for extra oomph with powerup sounds:
function playSound(type) {
if (!audioCtx || muted || !sfxGainNode) return;
const now = audioCtx.currentTime;
if (type === "destroy") {
const o1 = audioCtx.createOscillator();
const o2 = audioCtx.createOscillator();
const g = audioCtx.createGain();
o1.connect(g); o2.connect(g);
g.connect(sfxGainNode);
o1.type = "sine";
o1.frequency.setValueAtTime(600, now);
o1.frequency.exponentialRampToValueAtTime(1200, now + 0.08);
o1.frequency.exponentialRampToValueAtTime(200, now + 0.25);
o2.type = "triangle";
o2.frequency.setValueAtTime(800, now);
o2.frequency.exponentialRampToValueAtTime(100, now + 0.3);
g.gain.setValueAtTime(0.15, now);
g.gain.exponentialRampToValueAtTime(0.001, now + 0.3);
o1.start(now); o2.start(now);
o1.stop(now + 0.3); o2.stop(now + 0.3);
}
}
I did eventually break one of my initial rules, no external file dependencies, to increase the richness of gameplay. I am glad I did! Much more fun and engaging now with real images and music, all of course made using Gemini AI, including Nano Banana for the images and Lyria for the music:
Firebase Leaderboard: One of my key learnings from the Learn to Code with AI certificate I recently completed is the use of a real-time asynchronous database using Firebase DB (from Google) to build a persistent database to host the leaderboard.
All three local-storage functions (getLeaderboard, saveLeaderboard, addScoreToLeaderboard) and renderLeaderboard/toggleLeaderboardPanel were rewritten as async functions using the Firebase REST API at https://microplastic-blaster-default-rtdb.firebaseio.com/leaderboard.json:
GET scores: fetch(FIREBASE_LB_URL) — handles both Firebase object and array response formats
PUT scores: stores the full sorted top-5 array in one atomic write
gameOver() made async with await on both Firebase calls
renderLeaderboard shows a “Loading leaderboard…” placeholder while fetching
Once this one was set up, the DB automagically handled the setup, and I ended up with a nice, simple DB recording date, level, name, and score for the top five players:
{
"leaderboard": [
{
"date": "2026-04-09",
"level": 16,
"name": "Marc",
"score": 152075
},
{
"date": "2026-04-07",
"level": 16,
"name": "Brian Clough",
"score": 132200
},
{
"date": "2026-04-07",
"level": 13,
"name": "Wallace",
"score": 81700
},
{
"date": "2026-04-07",
"level": 12,
"name": "Marc",
"score": 71840
},
{
"date": "2026-04-07",
"level": 11,
"name": "Gromit",
"score": 69755
}
]
}
Summary: Great fun project overall, ~6 hours to get up and running with a working version, and I am now in what appears to be an infinite timeline to completion! My impression is that vibe coding is fast for building demos, wireframing, and planning, but tweaking, polishing, and adding final touches are more efficiently achieved by digging into the code.
🧬 MicroPlastic Blaster
Deploy Enzymes. Destroy Microplastics. Save the Body.
A browser-based arcade game by Elora Therapeutics — the biotech developing first-in-class enzyme therapy to remove microplastics from the human body. Fire enzymatic blasts at incoming polymer particles, protect the cell, and climb the global leaderboard.
🎮 Gameplay
You are the body’s enzymatic defense. Microplastic particles — PET, PE, PS, PP, plus branded consumer-plastic enemies — descend toward a target cell at the bottom of the screen. Click (or tap) to launch enzyme projectiles and intercept them before they reach the cell membrane.
– Each microplastic that breaches the membrane deals health damage proportional to the current level.
– The game ends when cell health reaches zero — the “Cell Overwhelmed” screen appears.
– Difficulty increases every 720 game ticks; spawn rate accelerates with level.
– Score = particle point value × current level.
⚗️ Microplastic Types
| Polymer | Abbreviation | Colour | HP | Speed | Points | Shape |
|---|---|---|---|---|---|---|
| Polyethylene terephthalate | PET | Purple | 3 | Slow | 30 | Block |
| Polypropylene | PP | Red | 1 | Fast | 15 | Jagged |
| Polyethylene | PE | Amber | 2 | Medium | 20 | Foam |
| Polystyrene | PS | Green | 2 | Fastest | 25 | Circle |
| Aquafina bottle | WATER | Blue halo | varies | Medium | — | Image sprite |
| Starbucks cup | COFFEE | Green halo | varies | Medium | — | Image sprite |
⚡ Power-Ups
Power-ups drift down the playfield and are collected by firing an enzyme at them (or by direct cell contact). Each lasts 10 seconds.
| Power-Up | Icon | Effect |
|---|---|---|
| FAST-PETase | ⚡ | Rapid-fire enzyme shots |
| Enzyme Boost | 💪 | Increased projectile damage |
| Cell Repair | ❤️ | Restores cell health |
| Chain Reaction | 💥 | Explosive chain-blast on impact |
| Marc ×10 | Co-founder avatar | 10× fire rate + Marc’s voice line |
| Paul ×10 | Co-founder avatar | 10× fire rate + Paul’s voice line |
Co-founder power-ups (Marc / Paul) disable the background fight track while the voice clip plays, then restore normal audio automatically on clip end.
🏆 Leaderboard
Scores are persisted to a Firebase Realtime Database (top 5 retained). On game over, players enter a display name and submit; the leaderboard renders immediately. It is also accessible from the start screen via View Leaderboard.
Firebase endpoint: https://microplastic-blaster-default-rtdb.firebaseio.com/leaderboard.json
Entries store: `name`, `score`, `level`, `date (ISO YYYY-MM-DD)`.
🔧 Tech Stack
| Layer | Technology |
|---|---|
| Rendering | HTML5 Canvas 2D API (800 × 600 logical resolution) |
| Scaling | CSS transform + responsive resizeCanvas() — fills viewport on desktop and mobile |
| Audio | Web Audio API (synthesised SFX) + <Audio> element (voice clips, fight track) |
| Leaderboard | Firebase Realtime Database (REST PUT/GET) |
| Style | Vanilla CSS — no frameworks, no build step |
| Assets | External PNGs + MP3s (co-founder avatars, brand sprites, audio clips) |
The entire game is a **single self-contained HTML file** with no npm dependencies or build pipeline.
📁 Asset Requirements
The following files must reside in the same directory as the HTML file:
microplastic_blaster_115.html
marc.png: Co-founder avatar (Marc)
paul.png: Co-founder avatar (Paul)
aquafina_new.png: Bottled water enemy sprite
starbucks_new.png: Coffee cup enemy sprite
Elora-Therapeutics-LogoStackedBlue.jpg: Cell badge logo
marc.mp3: Marc co-founder voice line
paul.mp3: Paul co-founder voice line
fight.mp3: Background music track
Missing image assets degrade gracefully (fallback canvas fills / text labels). Missing audio assets fail silently.
🚀 Run Locally
No server is required for basic gameplay. Open the HTML file directly in any modern browser:
📱 Mobile Support
The canvas scales to fill the viewport on screens ≤ 700 px wide using `Math.max(w/GAMEWIDTH, h/GAMEHEIGHT)` to avoid letterboxing. Touch events (`touchstart`) are mapped to enzyme fire. The HUD collapses to a single-column layout below 700 px and hides column headers below 480 px. All breakpoints are handled in CSS only.
🔬 The Science — Rotating Insight Messages
Between enzyme blasts, the in-game Microplastic Insight overlay rotates scientifically grounded messages every 8 seconds, covering topics including:
– Microplastic accumulation in blood, organs, and adipose tissue
– PET-linked inflammation and endocrine disruption
– Chronic oxidative stress from particle-driven immune activation
– The absence of endogenous polymer-degrading enzymes in mammals
– The estimated 5 g/week human microplastic ingestion burden