vibe-shooter: Gemini as the Game Master
A React and Canvas arcade shooter where Gemini generates structured anomalies, the frame loop stays deterministic, and the fallback path is just as important as the AI path.
- vibe-shooter makes Gemini matter by giving it authority over bounded gameplay events, not over the entire experience.
- The repo protects playability by validating model output and falling back to a deterministic anomaly when the API path fails.
- React, refs, and Canvas split the slow UI shell from the fast combat loop, which keeps the shooter responsive.
- The project lands between a classic arcade game and a chat-first AI toy, and that middle ground is the real argument.
The AI is not the narrator. It is the referee.
Most AI games use the model for flavor. vibe-shooter gives Gemini a job that actually changes the match. It does not write lore on the side. It generates anomalies that alter health, scrap, and momentum inside a loop that still obeys fixed combat rules.
That distinction is the entire trick. If the model disappears, the game does not collapse into a dead demo. It falls back to a static interference event, keeps the player moving, and preserves the arcade rhythm.
What an anomaly actually is
The anomaly system is small on paper and powerful in practice. Player state, especially level and current scrap, is sent into a Gemini request. The model returns structured output, the game checks that structure, and only then does the event become playable.
type AnomalyEvent = {\n title: string\n safeChoice: { label: string; delta: number }\n riskyChoice: { label: string; delta: number }\n fallback?: boolean\n}\n\nconst event = await generateAnomaly({\n level: player.level,\n currentScrap: player.scrap,\n})
That pipeline matters because it turns the model into a constrained mechanic. The AI can shape risk and reward, but it cannot invent arbitrary game state. Schema checks and fallback logic are the fence.
How the game stays smooth while AI is thinking
This is where the repo earns its stripes. React owns the shell, the HUD, and the anomaly modal. The moving parts live elsewhere: bullets, enemies, collisions, and frame updates run through Canvas with mutable refs and requestAnimationFrame, so the app does not ask React to reconcile every tiny motion.
That split is the enabling architecture. The game can wait on AI without stalling the combat loop, because the loop is already insulated from the slower UI layer. In other words, the model sits beside the engine, not inside it.
The code is vibe-coded, but the boundaries are disciplined
The stack is practical, not performative. TypeScript keeps the game entities honest, Canvas handles the render loop, and Web Audio synthesizes effects without loading a single asset file. That makes the project feel lighter than its concept should allow.
The same discipline shows up in the input model. Mobile control zones, entity arrays, and audio triggers are all explicit rather than magical. You can feel the shortcuts of vibe coding, but you can also see the constraints that keep the repo legible.
Why this is different from a normal shooter, and from a normal AI toy
| Dimension | Classic arcade shooter | Chat-first AI toy | vibe-shooter |
|---|---|---|---|
| Core loop | Move, shoot, survive | Prompt, wait, read output | Move, shoot, and absorb anomaly events |
| Role of AI | None | Owns the experience | Touches only the bounded event layer |
| Moment-to-moment change | Driven by level design and player skill | Driven by model output and conversation | Driven by deterministic combat plus AI-generated risk or reward |
| Failure mode | Hard game over | Hallucination or drift | Fallback interference event keeps the game playable |
| Player trust | High, because rules stay fixed | Low, because the model may wander | Higher, because the model is fenced in by schema and validation |
| Performance model | Pure real-time loop | Usually asynchronous and loose | Canvas and refs keep the loop fast while React handles the shell |
| Why it matters | Proves craftsmanship | Demonstrates novelty | Shows how AI can be a mechanic instead of a mascot |
Origin and lineage: a template that became a thesis
The surrounding ecosystem matters because it shows how prompt-native repos spread. The upstream README frames the project as a vibe-coded game built against a codebase that is meant to be extended by prompting, not by hand-editing every feature. That is useful context, but it is not the main story here. The main story is that this fork-like lineage uses the same prompt-friendly posture to put Gemini inside the runtime, not just inside the workflow.
Vibe Shooter is a fully vibe-coded Next.js web game powered by the AI-optimized thirdweb API which handles authentication, wallet management, gasless transactions, and more.
Build features by prompting against your codebase + `llms.txt`. The thirdweb API covers user authentication, wallet management, gasless transactions, and more out of the box.
That lineage makes the repo more interesting, not less. It shows how a prompt-first template can become a runtime thesis when the AI stops being a helper and starts being a bounded game master.