Inspiration
We've always been fascinated by emergent behavior — the idea that simple rules can produce breathtakingly complex systems. Ant colonies, coral reefs, and evolutionary arms races all emerge from local interactions without a central plan. We asked: what if an AI could dream up an entire ecosystem from scratch, and we could watch it play out in real time?
The Gemini 3 hackathon was the perfect catalyst. With Gemini's structured JSON output and Imagen 4's image generation, we realized we could build something that feels less like a game and more like a digital terrarium — a living petri dish you configure, seed, and observe. Hence the name: Petridise (petri dish + paradise).
We were also inspired by classic artificial-life projects like Conway's Game of Life, Spore's creature editor, and Nature of Code simulations — but we wanted to replace hand-crafted rules with AI-generated biology.
What it does
Petridise is an AI-driven life simulation observation system. You configure a world — choose a biome, set gravity, temperature, humidity, and atmospheric compounds — and then Google Gemini generates an entire starting ecosystem: organisms with unique traits, locomotion styles, diets, behaviors, and a narrative describing how life emerged.
Imagen 4 then paints a unique background texture for your biome and individual portraits for each organism. The world comes alive in a real-time Phaser.js 2D terrarium where creatures swim, hop, fly, slither, and interact according to AI-defined behaviors. Particle effects, size-based rendering, and locomotion-specific animations make each species feel distinct.
When the simulation timer ends, Gemini analyzes survival data — which species thrived, which struggled — and runs an evolution pass. It can trigger mutations, extinctions, climate shifts, or the arrival of entirely new species, complete with ancestry tracking. You then run the next generation and watch the cycle repeat.
Key features include:
- 🌍 Full world customization or one-click AI randomization
- 🧬 Real vs. fictional organisms toggle
- 🐠 Aquarium mode for a full-screen, always-animating terrarium view
- 💾 Export/import worlds as JSON snapshots
- 🔍 API debug panel to inspect every Gemini & Imagen request
- 🔑 Bring-your-own-key support — paste your Gemini API key right in the UI
How we built it
Frontend: React 18 + TypeScript + Vite for fast iteration, styled with Tailwind CSS. A central useSimulation hook manages the entire state machine — configuration → generation → simulation → evolution — with clean transitions between phases.
Simulation engine: Phaser.js 3 renders the terrarium. Our MainScene handles sprite creation, locomotion-specific movement patterns (sinusoidal swimming, ballistic hopping, Perlin-ish flying, lateral slithering), size-scaled rendering, and particle effects. Organisms are spawned dynamically from the AI-generated species data.
AI layer: Four Vercel serverless API routes talk to Google Gemini:
/api/generate-world→ Gemini 3 Flash produces a complete world specification and organism roster as structured JSON./api/generate-texture→ Imagen 4 Fast creates a biome-appropriate background texture./api/generate-organism-image→ Imagen 4 Fast generates a portrait for each species./api/evolve→ Gemini 3 Flash analyzes simulation results and outputs the next generation with events and narrative.
All Gemini calls use responseMimeType: "application/json" with explicit JSON schemas to guarantee parseable output.
Local dev: An Express server (server.js) proxies the API routes so we can develop without deploying to Vercel.
Deployment: Vercel handles production — serverless functions for the API, static hosting for the SPA, all configured via vercel.json.
Challenges we ran into
Structured output reliability. Even with JSON schemas, Gemini occasionally returned slightly malformed responses — extra prose before the JSON, unexpected field names, or arrays where we expected objects. We added defensive parsing, fallback defaults, and retry logic to handle edge cases gracefully.
Making AI-generated creatures feel alive. Translating a text description like "bioluminescent jellyfish, 3 cm, drifts on currents" into convincing 2D animation required building a locomotion system that maps AI-provided traits (locomotion type, size, speed) to distinct Phaser movement patterns and particle effects — all without hand-drawn sprites.
Evolution coherence across generations. Ensuring Gemini's evolution output was logically consistent with what actually happened in the simulation (population counts, which species dominated) required carefully constructing prompts with simulation statistics and prior-generation context.
Image generation latency. Generating a background texture plus portraits for 5–10 organisms serially would be painfully slow. We parallelized the Imagen calls and display organisms incrementally as their portraits arrive, so the UI never feels stuck.
Balancing AI freedom vs. simulation constraints. If we give Gemini too much freedom, it invents organisms too large for the canvas or with incompatible traits. Too little freedom and the worlds feel generic. Tuning the prompt constraints and JSON schema took many iterations.
Accomplishments that we're proud of
- End-to-end AI-generated ecosystems. From a handful of sliders to a living, breathing terrarium with unique art — every world is different, and none of it is hardcoded.
- Seamless generation-to-generation evolution. Watching a species you seeded three generations ago mutate, split into subspecies, or go extinct — with a narrative explaining why — is genuinely compelling.
- The aquarium mode. Turning the simulation into a screen-saver-quality full-screen terrarium that people actually want to leave running on a second monitor.
- Robust structured output pipeline. Our API layer reliably turns Gemini's creative output into typed TypeScript objects that drive real-time rendering — bridging the gap between free-form AI and deterministic simulation.
- World export/import. You can save a world, share the JSON file, and someone else can load it and continue evolving from where you left off.
What we learned
- Structured JSON output is a game-changer for AI-driven apps. Being able to define a schema and get parseable data back (most of the time) makes Gemini far more useful as a "backend brain" than free-text generation.
- Imagen 4 is remarkably good at stylistically consistent output when you give it detailed prompts with biome context. The backgrounds and organism portraits feel cohesive within a single world.
- Phaser.js is incredibly flexible for non-game applications. Using a game engine for a scientific-feeling simulation observation tool worked amazingly well.
- Prompt engineering is iterative design. Our prompts went through dozens of revisions. Small wording changes dramatically affect the creativity, consistency, and parseability of Gemini's output.
- AI-generated content needs guardrails, not walls. The best results came from giving Gemini creative freedom within a tight structural contract (JSON schema + validation + sensible defaults).
What's next for Petridise
- Multi-species interactions: Model predator-prey dynamics, symbiosis, and competition directly in the Phaser simulation rather than only in the AI's narrative.
- Phylogenetic tree visualization: Show a branching ancestry tree across generations so you can trace how species diverged and evolved.
- Sound design: Use AI-generated ambient audio that matches the biome — ocean waves, volcanic rumbles, alien hums.
- Multiplayer terrariums: Let multiple users observe and interact with the same simulation in real time.
- Longer evolutionary timescales: Support hundreds of generations with summarized history so Gemini can model deep-time evolution — continental drift, mass extinctions, Cambrian explosions.
- 3D terrarium mode: Explore a WebGL-rendered 3D version of the petri dish for a more immersive experience.
Log in or sign up for Devpost to join the conversation.