PAGAN is a language for game art: palettes, sprites, tiles, 3D models, animations and style rules, written as plain text. Your AI agent writes it, PAGAN checks and renders it, and your game gets engine-ready sprites.
Looking for 3D? Try KILN: smooth, stylised 3D models as text. For audio, SEGAN. Both are PAGAN's sister libraries.
drag to turn
16 headings, one light, from this 61-line filemodels/ship.model.yaml
name: ship
description: >
Player ship: a wooden two-masted brig. Oak hull with a raised stern castle (lit brass lanterns),
forecastle, bowsprit. Square sails braced to catch the wind on both masts, a jib to the bowsprit,
red pennants. Top-down 3/4 view, no water (it sits on a moving sea). 16 headings so it turns
smoothly; the pennants flutter in the "sail" animation.
size:[92,70]pivot:[46,46]origin:[32,0,0]# the hull's centre at the waterline lands on the pivotdirections:16outline: auto
status: draft
style_version:1tags:[player, vehicle, ship]materials:hull:{keys: ["3", "4", "5", "7"]}deck:{keys: ["4", "5", "6"]}rail:{keys: ["1", "2"]}mast:{keys: ["1", "2", "4"]}lamp:{keys: ["e"]}# one key = unshaded: lanterns glowtrim:{ramp: gold }sail:{keys: ["8", "9", "a", "b"],two_sided: true }flag:{ramp: red }parts:
- hull:{from: [0,0,0],length: 64,beam: 19,height: 7,bow: 0.4,stern: 0.1,material: hull,top: deck,rim: rail }
- box:{from: [0,-6,7],to: [12,6,10],material: hull,top: deck,rim: rail }# stern castle
- box:{from: [51,-5,7],to: [56,5,8],material: hull,top: deck,rim: rail }# forecastle
- box:{from: [1,-9,3],to: [50,-9,3],material: trim }# gold stripemirror: true
- box:{from: [16,-9,5],to: [17,-9,6],material: rail }# gun portsmirror: true
- box:{from: [26,-9,5],to: [27,-9,6],material: rail }mirror: true
- box:{from: [36,-9,5],to: [37,-9,6],material: rail }mirror: true
- box:{from: [30,-2,7],to: [35,2,7],material: rail }# cargo hatch
- box:{from: [-1,2,8],to: [-1,3,9],material: lamp }# stern lanternsmirror: true
- cylinder:{base: [24,0,7],height: 36,material: mast }# main mast
- cylinder:{base: [45,0,7],height: 30,material: mast }# fore mast
- line:{from: [60,0,8],to: [73,0,14],material: mast }# bowsprit
- sail:{at: [24,0,12],width: 20,height: 13,bulge: 2.2,brace: 30,material: sail,yard: mast }
- sail:{at: [24,0,27],width: 15,height: 9,bulge: 1.8,brace: 30,material: sail,yard: mast }
- sail:{at: [45,0,11],width: 17,height: 11,bulge: 2,brace: 30,material: sail,yard: mast }
- sail:{at: [45,0,24],width: 12,height: 8,bulge: 1.6,brace: 30,material: sail,yard: mast }
- triangle:{points: [[48,0,10],[70,0,13],[46,0,34]],material: sail }# jib
- box:{from: [20,0,41],to: [24,0,42],material: flag }# pennantsid: pennant
- box:{from: [42,0,35],to: [44,0,36],material: flag }id: fore_pennant
animations:sail:fps:6poses:
- {}
- {pennant: {offset: [0,1,0]},fore_pennant: {offset: [0,1,0]}}
- {}
- {pennant: {offset: [0,-1,0]},fore_pennant: {offset: [0,-1,0]}}
The translation layer
You don't learn PAGAN. Your agent does.
With the PAGAN skill (Claude) or the MCP server (any agent), your AI agent becomes the translator between what you want and the art your game loads.
You English
"A zombie that shambles towards the player."
Agent Claude + PAGAN skill / MCP
writes zombie.model.yaml
runs pagan lint
looks at the preview
fixes what's off
PAGAN the compiler
renders 8 headings
6-frame walk cycle
one camera, one light
byte-identical builds
Your game any engine
zombie.png
zombie.tres
manifest.json
Interactive demo
Watch an agent make game art
Choose your own adventure: pick what you're building, then what to ask for next. Start over to take another path. Each reply shows the art, what the agent wrote, and the files your game gets.
A scripted conversation. The art, source files, diffs, lint results and build output are real PAGAN output, rebuilt from the source files in this site's repo.
Let your agent do it
An agent building your game calls PAGAN like a service
While you play-test, an orchestrator agent asks PAGAN for the art it needs, reads back the manifest and wires the sprite into the scene. manifest.json is the contract, so it works for any engine; Godot resources come for free.
orchestrator → paganwrite_asset zombie.model.yaml
"Wave 2 needs an enemy: top-down, 8 directions, walk + attack."
Everything below is real build output from the demo projects, drawn in your browser from the same PNG sheets and manifest a game loads.
1 Art as source code
The agent writes text you can read, diff, review and keep in git. "16 headings so it turns smoothly" is a one-line change, and the review is a normal pull request.
models/ship.model.yaml@@ -2,12 +2,12 @@description: > Player ship: a wooden two-masted brig. Oak hull with a raised stern castle (lit brass lanterns), forecastle, bowsprit. Square sails braced to catch the wind on both masts, a jib to the bowsprit,- red pennants. Top-down 3/4 view, no water (it sits on a moving sea). 8 headings; the pennants- flutter in the "sail" animation.+ red pennants. Top-down 3/4 view, no water (it sits on a moving sea). 16 headings so it turns+ smoothly; the pennants flutter in the "sail" animation.size:[92,70]pivot:[46,46]origin:[32,0,0]# the hull's centre at the waterline lands on the pivot-directions:8+directions:16outline: autostatus: draftstyle_version:1
2 3D in, perfect 2D out
One voxel model gives every heading and every animation frame, lit by one project-wide light and seen through one camera. No drift between directions, ever. 1 to 32 headings.
3 One style, everywhere, forever
Palettes with ramps, a project light and style versions. "Make the night darker" ispagan palette adjust grave --lightness -0.07 --saturation 0.85, and every asset follows.
4 It checks its own work
The linter catches orphan pixels, ramp misuse, clipped outlines and animations that pop. The agent reads the findings and fixes them. A real one, from the zombie's first attack:
W007 attack_se_1 -> attack_se_2: 63% of pixels change
Fixed: 9 smaller steps, 0 warnings
5 Animation that doesn't jitter
Poses move parts by whole voxels, so the torso stays on exactly the same pixels while the legs drag. The changes row shows what moved; lint W007 measures it.
6 Variants and team colours
Recolours with identical geometry. The manifest carries a hex → hex swap table for each, so a game can recolour one sheet in a shader. These are recoloured in your browser that way.
7 Free, open, local
MIT-licensed. Runs on your machine, offline. No account, no credits, no API key, no cloud. Builds are deterministic: the same sources give byte-identical files.
8 Built for agents
A Claude skill that teaches the whole workflow, an MCP server for any agent, --json on every command, and a long-term memory in the project: BRIEF.md, STYLE.md, asset status and a style changelog.
9 Engine-ready
manifest.json describes every sheet: frame rects, animations, fps, pivots, headings, tiles, variant swaps, normal maps. Any engine can read it. For Godot 4, PAGAN also writes SpriteFrames and TileSet resources, verified by loading them in headless Godot.
# Godot 4
var zombie := AnimatedSprite2D.new()
zombie.sprite_frames = load("res://assets/generated/sprites/zombie.tres")
zombie.centered = true
zombie.offset = Vector2(0, -17) # manifest: godot_offset
zombie.play("walk_" + heading) # one animation per heading
10 3D games, too
Free cameras, kill cams, undersides: the same model file also builds as a real mesh (glTF), one node per part, with its animations and the hit zones, joints and "detachable" flags game code reads. A ramp shader keeps engine lighting on the palette: the sun picks the shade exactly as PAGAN's renderer does. This is the zombie's actual .glb, drawn in your browser by that rule. Drag it, look from below.
1,724 triangles · 16 voxels per metre · ground textures from tilesets · previews from any angle (pagan preview --orbit)
# Godot 4
var zombie := load("res://assets/generated/models/zombie.tscn").instantiate()
zombie.look_at(player.global_position, Vector3.UP, true) # its front is +Z
zombie.get_node("AnimationPlayer").play("walk")
# a hit: which part? the rig's meta is each node's metadata
var zone = hit_node.get_meta("extras").get("hitzone") # "head", "arm", "leg"
How it compares
Three kinds of tool
Facts as of October 2026, from each tool's own documentation. Pick what fits your game.
Where PAGAN loses: it isn't a painter. For one-off, organic, illustration-heavy art, a diffusion tool is faster. PAGAN wins on a whole game's worth of consistent, animated, rotatable, maintainable assets.
Install
One line, then ask
Requires Python 3.11+. Pin a tag so your art builds the same way next year (v0.8.0 is current).
$ pip install "pagan @ git+https://github.com/lukasgolino/PAGAN@v0.8.0" # install PAGAN (Python 3.11+)$ pagan skill install # copy the skill into this repo's .claude/skills/
Then ask Claude: "I'm making a naval exploration game; make the player's ship, three masts, 8 headings."
$ pip install "pagan[mcp] @ git+https://github.com/lukasgolino/PAGAN@v0.8.0" # PAGAN with the MCP server$ claude mcp add pagan -- pagan mcp --project ./art # or in any client: command `pagan mcp --project <dir>`
Works with Claude Desktop, Claude Code, Cursor or your own agent. Add --allow-godot to let it verify builds in headless Godot.
$ pip install "pagan @ git+https://github.com/lukasgolino/PAGAN@v0.8.0" # install$ pagan init my-art --perspective top-down-3/4 # a project: palettes/, sprites/, tiles/, models/$ cd my-art && pagan new model ship --size 96x96 --directions 8 # write the art$ pagan lint && pagan preview ship && pagan build # check it, look at it, build it
Every command takes --json and exits non-zero on errors.
Open source
Free, for good
PAGAN is MIT-licensed. Every released version stays free to use, change and ship, commercially or not. No account, no telemetry, no cloud: it runs on your machine.
Contributing: open an issue first for notation changes; every feature lands with tests, output stays byte-identical, and anything that changes rendered pixels gets a version bump.
Game repos pin a tag, so your art never changes under you.
Sister libraries: KILN (smooth 3D models) and SEGAN (audio), same design, same workflow.
MIT · free forever · made with PAGAN
Gallery
Everything on this page
Every asset the demo projects build, at 1 pixel per pixel × 3. Status: draft (art review pending).
zombie8 headings · walk, attack
zombie (rotten)decay ramp
zombie.ash+ragvariant_axes
zombie.ash+scrubsvariant_axes
zombie.green+flannelvariant_axes
zombie.green+ragvariant_axes
ship16 headings · sail
ship.blueteam colour
ship (damaged)hidden parts, roll
ship (hull)no sails yet
gravestone1 view
graveyardgenerated, seamless
graveyard (night)after palette adjust
logogenerator script
mark16×16 icon
FAQ
Straight answers
Is PAGAN an AI image generator?
No. PAGAN doesn't paint: it compiles. Your AI agent writes PAGAN source files (palettes, grids, voxel models, animations); PAGAN checks them and renders them. The quality comes from the agent's modelling and PAGAN's renderer, not from a diffusion model, so results are exact, repeatable and editable.
When should I use a diffusion tool instead?
For one-off, organic, illustration-heavy art (a painted portrait, a splash screen), an image model is faster. PAGAN wins when you need a whole game's worth of assets that match: consistent headings, animations that don't jitter, one palette, and changes that reach every asset at once.
Which agents work with it?
Any agent that speaks MCP (Claude Desktop, Claude Code, Cursor, your own). The PAGAN skill, which teaches the full workflow, is for Claude. Without either, the CLI's --json output is easy for any program to drive.
Is it only for pixel art?
No. Flat, vector-like arcade art works too: polygon shapes with rims, drawn at 2x and smoothed on build (supersample). Pixel art is the default.
Does it work for 3D games?
Yes. Besides sprites in 1-32 headings, every 3D model can build as a real mesh (binary glTF, .glb): one node per part with joints, hit-zone metadata and animations, a palette ramp texture, and for Godot a scene with a shader that keeps the engine's lighting on the palette. Tilesets can export repeatable ground and wall textures. You pick the voxel size (texel density) for your game once.
Which engines?
Any: manifest.json describes every sheet, frame, animation, pivot and colour swap. Godot 4 gets SpriteFrames and TileSet resources out of the box.
Who owns the art?
You do. PAGAN is MIT-licensed and runs locally; nothing is uploaded and nothing is claimed.
Is the demo a live AI?
No. It's a scripted conversation, so it can't make things up. But every image, source file, diff, lint result and file listing in it is real PAGAN output, rebuilt from the project files in this site's repository.