PX-Art

GUIDE

How can Codex use game art assets?

Codex does not draw sprites. What it can do is read a structured art project over a read-only MCP endpoint and turn it into working code. Connect it to PX-Art with an HTTP MCP entry, and it can resolve which asset to use, download the file into your repo, and write frame math, foot pivots, nine-slice panels and tile lookups that match the real metadata.

Where the boundary is

Codex is a coding agent. It reads repositories, writes code and runs commands. It does not produce pixel art, and no MCP connection changes that — the PX-Art surface it connects to is read-only, with no generation tool in it.

What changes is the quality of the code it writes about art. Without a connection, Codex is guessing: it hardcodes a frame width, assumes eight frames, stretches a panel and centres a sprite on its bounding box. With a connection, every one of those numbers is a value it looked up.

Connecting Codex

  1. Unlock and issue the token in PX-ArtTools area, MCP access, or Settings and MCP access. The plaintext appears once — copy it then. Any subscription payment or top-up purchase unlocks read-only MCP permanently; there is no separate MCP charge.
  2. Add an HTTP MCP server entry to Codex's configCodex reads MCP server definitions from its own configuration file. The three values it needs are the transport (HTTP, not stdio), the URL https://px-art.com/api/mcp, and the header Authorization: Bearer pxr_YOUR_TOKEN. Consult your installed Codex version for the exact key names — the endpoint side is what is fixed here.
  3. Verify outside the agent firstRun the tools/list POST by hand before debugging inside Codex. If curl returns twelve tools and Codex does not, the problem is in the client config, not the server.
  4. Keep the token out of the repositoryIt belongs in your local agent config. A token committed to a repo is a leaked credential; regenerate it in the panel, which invalidates the old one immediately.
  5. Give Codex the orientation order in your promptlist_games, then list_game_structure and list_characters, then list_asset_families, then search_assets, then preview_assets, and only then downloads. Skipping to search_assets with a made-up notebook ID is the most common wasted turn.

What Codex should ask for, and in what order

list_games              -> notebookId 12, design {styleKey, tags, tileSize}
list_game_structure     -> pageId / tagId meanings
list_characters         -> one logical character's views, tags and assets
list_asset_families     -> which family can cover this screen at all
search_assets           -> shortlist with role, family, component params
preview_assets          -> look at up to 8 candidates before committing
get_asset_downloads     -> up to 50 originals, short-lived URLs

list_asset_families is the step agents most often skip and most benefit from. A family is one generated set — a UI kit, or the phases of one effect — and it reports a role distribution such as {"panel":2,"button":4,"bar":1,"slot":2} plus the original generation description. That answers "can this set cover my HUD" in one call, instead of paging through assets whose names are auto-numbered.

Turning metadata into correct code

Frame math

A multi-frame asset is one horizontal strip. The catalogue gives both the strip size and the single-frame size, and the relationship is exact:

w = frameWidth * frames        // whole strip
h = frameHeight                // single frame height
frame i  =  crop at (i * frameWidth, 0), size frameWidth x frameHeight

The trap: a scene node's rect is the single-frame size, not the strip width. Codex laying out with w will place every animated node several times too wide, and collision boxes will follow it.

Never play a strip blindly

Check stripKind before writing playback code:

stripKindMeaningCorrect handling
animationReal animation — character action, effect, animated tileLoop at the given fps
statesButton statesIndex by interaction; names in component.states, such as normal, hover, pressed, disabled
glyphsGlyph row such as 0-9Index by character; range in component.glyphs

fps is only present when stripKind is animation. If Codex reaches for fps and finds nothing, that is the signal to stop writing a tween.

UI components

UI assets carry a component block, and ignoring it produces visibly wrong output:

"component": {"type": "panel9", "slice": {"l": 8, "r": 8, "t": 8, "b": 8}}

That is a nine-slice instruction: corners never scale, edges stretch along one axis only, the centre stretches both ways, and the slice values are pixel insets from each edge. Straight-stretching this panel smears its rounded corners and its outline. button4 means a four-state strip, numbers means a bitmap digit row with a glyphs range, and tile carries tileSize and loop.

Sampling

Every asset declares sampling as nearest, linear or auto. Pixel art rendered with linear turns to mush. This is a one-line setting that Codex can get right automatically once it reads the field.

Anchoring

Sprite sheet exports carry the foot pivot as an Aseprite slice, in cell-local coordinates. Anchoring a character to its bounding-box centre instead of its foot pivot is what makes characters sink into the floor on some frames and hover on others.

Delivering a whole scene into the repo

For a full arranged screen, get_scene_bundle gives Codex a complete, verifiable file plan:

scene-42-r7/
  scene.json          # written verbatim from the "content" field
  map.tmj             # Tiled map; absent for non-map scenes
  assets/88-grass.png # downloaded from downloadUrl, then size + hash checked

Four rules cover the whole procedure: create the root directory; write any file that has content; download any file that has a downloadUrl; verify size and the returned SHA-256. Paths in scene.json and map.tmj already reference assets/{assetId}-{filename}, so nothing needs rewriting.

For tilesets specifically, the in-app export ZIP already contains four files that a code agent can consume directly:

atlas.png      # tiles laid out by row and column
tileset.json   # name, image, tileSize, columns, tileCount, tiles[]
tileset.tsx    # Tiled tileset XML, per-tile role / sourceRow / sourceCol / assetId
tileset.tmj    # a preview map that opens in Tiled directly

Each entry in tiles[] carries id, assetId, name, file, role, sourceRow, sourceCol, atlasCol and atlasRow — enough for Codex to build a role-keyed lookup rather than hardcoding atlas indices:

{"name": "forest", "image": "atlas.png", "tileSize": 32,
 "columns": 8, "tileCount": 24,
 "tiles": [
   {"id": 0, "assetId": 301, "name": "grass 01", "file": "301.png",
    "role": "fill", "sourceRow": 0, "sourceCol": 0,
    "atlasCol": 0, "atlasRow": 0}
 ]}

Limits and caveats

  • Codex cannot generate art through this connection. Read-only means read-only; new assets come from the app.
  • It cannot see the assembled scene. Thumbnails per asset exist, capped at 220px on the longest side. There is no whole-scene render, so visual acceptance still happens in your engine.
  • Download URLs expire. Codex should fetch into the repo in the same turn and never write a URL into a config file or commit one.
  • Batch limits are real. preview_assets takes at most 8 IDs, get_asset_downloads at most 50, and a scene bundle packs at most 50 dependent assets — over the limit the tool errors clearly instead of silently truncating.
  • Back off on 429. Bulk parallel pulls trip the rate limit; use the Retry-After value.
  • Do not claim engine support that is not there. There is a thin adapter on the Godot side; Tiled files and Aseprite-format JSON are standard interchange formats. Anything else is integration you write.
  • Generation is probabilistic — assets need human review before production. Commercial use of legitimately generated assets is permitted, but third-party rights, applicable law and AI provider terms remain your responsibility, and AI output is neither guaranteed exclusive nor guaranteed copyrightable.

More on the agent-facing data model: AI game assets for coding agents and MCP game assets. What the strips themselves are made of: sprite sheet generator.

FAQ

Can Codex generate pixel art or sprites?

No. Codex is a coding agent with no image model in this loop, and the PX-Art MCP surface it connects to is read-only with no generation tool. Art is generated by you in the app; Codex reads the result and writes the code that loads it.

How do I connect Codex to PX-Art?

Add an HTTP MCP server entry to Codex's configuration pointing at https://px-art.com/api/mcp with an Authorization: Bearer pxr_... header. The transport is Streamable HTTP rather than stdio. Verify the connection with a plain tools/list POST via curl before debugging inside the agent.

What is the single most common mistake an agent makes with sprite data?

Using the strip width where the frame width belongs. A multi-frame asset stores w as frameWidth multiplied by frames, while a scene node's rect is the single-frame size. Laying out with w makes every animated node several times too wide and drags collision boxes along with it.

How does Codex know whether to animate a multi-frame asset?

By reading stripKind. Only animation should be played, at the fps the asset provides. states means index by interaction using component.states, and glyphs means index by character using component.glyphs. The fps field is present only for animation strips.

What does Codex do with a tileset export?

The tileset ZIP contains atlas.png, tileset.json, tileset.tsx and tileset.tmj. tileset.json lists each tile with id, assetId, name, file, role, sourceRow, sourceCol, atlasCol and atlasRow, which lets an agent build a role-keyed lookup instead of hardcoding atlas indices. tileset.tsx and tileset.tmj open in Tiled directly.

Does connecting Codex cost credits?

No. MCP calls are read-only and free. Credits are spent only on generation in the app. Read-only MCP is unlocked permanently by any subscription payment or top-up purchase, and paid status is checked both at token issue and on every call.

Related

Give Codex real numbers instead of guesses

Frame widths, strip kinds, nine-slice insets, sampling modes and foot pivots — read from your own project rather than assumed.

Create a free accountSee pricing

New accounts start with 20 credits. Formal checkout is still under review and not open yet.