My Own Pokémon Generation

Overview

Mid-play, in a window inside the game itself, the player types a few words. While the game is still running, an AI turns them into a brand-new Pokémon species — art, name, typing, base stats, and moves — and registers it as a first-class species. You meet it in the tall grass, catch it, nickname it, and raise it like any other.

Nothing is pre-authored. The species that ends up in the save file has never existed before and exists nowhere else.

Part of what games have always offered is the making of something that is yours. What that has meant in practice is a choice from a fixed set. This project exists to test whether generative AI makes yours literally true — and, more to the point, whether something literally yours is something a player actually grows attached to.

Walkthrough

Talking to an old woman in Petalburg Woods starts the sequence. You describe the creature you have in mind; the words are turned into a species while you carry on playing; and a few minutes later it is waiting in the tall grass — to be encountered, caught, and used from then on exactly like anything else in the game. All of it is made on the spot: the name, the typing, the base stats, the move set, both battle sprites, and the party icon.

An elderly couple stand in Petalburg Woods. A dialogue box reads: Say… what sort of creature do you imagine it to be?
Talking to the old woman starts it.
The Easy Chat entry screen titled "Picture the creature:" with the words BEAUTIFUL, ATTACK and FIRE entered.
You give her six words through Emerald's own Easy Chat system.
The player stands in the woods beside tall grass. A dialogue box reads: The tall grass is rustling… Something is in there!
Generation runs on the PC for a few minutes. A cry signals that it is ready.
A battle screen. A red lizard with a flame on its head faces the player. The text reads: Wild FLAMEREL appeared!
FLAMEREL, a Fire-type lizard, appears in the rustling grass.
A Poké Ball is thrown at FLAMEREL during the battle.
It can be caught with a Poké Ball, like any other species.
The naming screen asking for FLAMEREL's nickname, with GGG entered.
It can be nicknamed, like any other species.
The party screen showing the generated species alongside three ordinary Pokémon, with its own party icon.
It sits in the party with its own icon, like any other species.
The Pokémon Info screen for FLAMEREL, showing Fire type, the Blaze ability, a naughty nature, and met at Level 7 in Petalburg Woods.
Its summary screen works, like any other species.

A full run, end to end, is recorded here: My Own Pokémon Generation — demo02.

Why this, and not a creature generator

The interesting problem is not whether an AI can invent a Pokémon. It is whether it can invent one the game can absorb without falling apart. Left to itself, a generator produces something either unusable — a 900-point stat monster that trivialises the game — or unpleasant: a malformed sprite that stops reading as a creature at all.

So the design work here is not the creature. It is the space the creature is generated inside: the stat bands, the rules of move legality, the silhouettes that survive a 64×64 sprite, the vocabulary the player is even allowed to describe with. The model explores that space. It does not get to define it.

This project is where my design philosophy stops being an argument and gets put to the test: define the goals, values, constraints, and boundaries that shape a design space, let the generation happen inside it, and find out whether the result holds together.

The framework is the research

The LLM never writes freely. It fills slots in a fixed schema, and every output is re-checked by a validator. Violations are sent back for regeneration together with the specific rule that was broken.

Balance constraints keep the game playable. Base stats are held to a fixed band — 280–360, roughly starter tier — with per-stat ranges, and out-of-band specifications are rejected outright. Moves are auto-extracted from the pokeemerald source, then filtered to the species' own type or Normal, with one-hit-KO moves, self-destruct effects, and fixed or overpowered damage removed. The resulting set is checked for soundness: enough attacking moves, at least one same-type attack, at most one high-power move. Level assignments are made deterministically by the framework, not the model. Everything else is pinned — one ability per type, fixed catch rate, growth curve, gender ratio, TM compatibility — so individual variation stays confined to the schema slots and runs remain comparable.

Appearance constraints keep the output from breaking down. Body plans come from a whitelist of silhouettes that survive a 64×64 sprite: quadruped, rodent, bird, lizard. Colour is chosen from a named whitelist, and the Pokédex body colour is derived mechanically. Features are limited to one to three short canned phrases, with a blocklist rejecting human features, blood, weapons, and text. The framework composes the final prompt itself and appends a fixed epilogue: one creature, full body, coherent anatomy, no extra limbs, calm expression.

It works, and it can be watched working. In one recorded run the model proposed a base stat total of 380; the validator pushed back three times — 380, 360, 340 — until the specification landed inside the band at 320.

How it runs

The game itself generates nothing. A resident Python process on the PC does the work, and the two halves talk through a file mailbox that an mGBA Lua script polls every frame.

  1. Text. A local model (qwen3:8b) turns the words into a validated species record.
  2. Image. An image model renders a reference illustration, then three character-consistent views: the front battle sprite, the back sprite, and the party icon.
  3. Convert. The art is quantised to a shared 15-colour palette and converted into pokeemerald's sprite format.
  4. Encode. Sprites become GBA binaries — 4bpp and 1bpp tiles, gbapal palettes, BIOS-compatible LZ77 compression.
  5. Inject. The binaries are written into a reserved region of the ROM.

Writing to the cartridge at runtime means the running instance picks up the new species without a reset, and the identical byte sequence goes to disk so the change survives a reload.

What appears is persistent and irreversible. It roams: flee or lose, and it stays in the world. Knock it out, and it is gone for good.

Implementation

The generator, the constraint framework, the GBA encoders, and the game-side patch are published in full: github.com/takafumihoriuchi/my-own-pokemon-generation.

Postscript — on attachment

The prototype settles a technical question. Behind it sits the one I actually care about: does a Pokémon generated for you, existing nowhere else, come to mean more than one that shipped with the game?

From playing my own build — a sample of one, and worth reading as nothing more — two conditions seem to govern the answer.

A case from outside the game speaks to both. Working by hand with ChatGPT, going back and forth until I was satisfied, I designed a species of my own — Hanagitsune. I am attached to it. I had made it rather than requested it, and what came out cleared the quality bar.

Hanagitsune, front view: a pale green fox whose tail is a cascade of flowering vines. Hanagitsune, back view, showing the full length of the flowering tail.
Hanagitsune — a guardian of the forest, with a tail in bloom. Grass and flowers spring up wherever it has run, calling new life even into barren ground. Its figure is taken as a sign of the forest growing toward its future.

Both conditions are addressable. A deeper crafting process — choosing, revising, rejecting — moves the first; better models and a more carefully designed prompt framework move the second. That is where this goes next.

So the prototype's result is not a verdict on the question. It is the question made measurable: two variables that can now be moved deliberately and watched.

Built on the pret/pokeemerald decompilation as personal research. No ROM, ROM patch, or game asset is distributed, and every sprite here is AI-generated original art. Pokémon is a trademark of Nintendo, Creatures Inc. and GAME FREAK Inc.; this project is unaffiliated with and unendorsed by them.