Pet maker
Paste a photo of your dog or cat, make the pet, then adjust anything. The photo stays in your browser.
1Start
From a photo or a breed. Or skip this and change the looks below.
From a photo
From a breed
2Change the looks
Every change shows on your pet right away. Undo takes it back.
Pick a part, then click the photo or a photo color.
How a pet is made
- RecipeA small JSON object: head shape, ears, coat, markings, eyes, body, colors.
- Frame
PetGen.frame(recipe, view, action, f)draws a 32 × 32 grid of parts. - Palette
PetGen.palette(recipe)turns the recipe's colors into one color per part. - Pixels
PetGen.pixels(grid, palette)gives RGBA, ready for a canvas or the app's sprite.
Files
- petgen.js the drawing code, no dependencies, works in the browser and in node
- petgen-data.json heads, bodies, tails and shapes (about 100 KB)
- presets.js the 55 breeds, each a recipe
Source: design/pixel-bodies/ in the prototypes repo (branch design/combined-viewer). It is a port of tama360.py, checked pixel for pixel by test_petgen.mjs (2448 of 2448 frames).
Poses match the app
| Pose | view | action | frames | ms per frame |
|---|
The same names as Pose in frontend/features/pets/sprites/scene.ts. Side faces right; for left, reverse each row.
Use it in the app
import PetGen from "./petgen"; // petgen.js
import data from "./petgen-data.json";
PetGen.init(data);
// rows of CSS colors, null = transparent: the shape spriteScene() returns today,
// so PetSprite.tsx can draw a recipe pet without changes
export function petRows(recipe, pose, facing = "right") {
const px = PetGen.pixels(PetGen.frame(recipe, pose.view, pose.action, pose.frame), PetGen.palette(recipe));
const rows = [];
for (let y = 0; y < 32; y++) {
const row = [];
for (let x = 0; x < 32; x++) {
const i = (y * 32 + x) * 4;
row.push(px[i + 3] ? `rgb(${px[i]},${px[i + 1]},${px[i + 2]})` : null);
}
rows.push(facing === "left" ? row.reverse() : row);
}
return rows;
}
This pet's recipe
From a photo (backend)
On claude.ai this page asks Claude with the prompt below and keeps only the options it knows (fromReply in this page). In the app this belongs on the backend with the vision model, for example POST /api/ai/pet-photo returning a recipe, so keys never reach the client.
To bring it into the app
- Add
petgen.jsand its data underfrontend/features/pets/sprites/, with types for the recipe. - Where
spriteScene()is called, drawpetRows()when the pet has a recipe. - Store the recipe on the pet (a JSON column), set by the owner here or by the photo step.
- Add the photo step on the backend with the prompt above.