2D art from code: Art2D
An Art2D recipe is a small JSON file that the engine paints into game art: a sprite sheet of posed frames, an auto-tiling terrain tileset, or a wide backdrop that repeats left to right. It is free, needs no pictures and no image model, and draws in the cartoon look: thick outlines, soft shading and rim highlights. (For hand-drawn relief art from a JavaScript recipe, see Paper Forge.)
Save a recipe in the project (for example Art2D/mygame/coin.ttrart.json), then ask your AI to call paint_art2d {recipe: "Art2D/mygame/coin.ttrart.json", out: "2D/mygame/coin"}. The pictures land in Assets/2D/mygame/. For a sprite, the answer gives the frame size and the clips to put on the sprite component.
Templates for every kind
add_kit platformer2d copies 16 working recipes into the project's Art2D/platformer2d/:
- sprites: hero, beetle, frog, coin, items, blocks, props, platform, leaf;
- terrain: jungle and castle;
- backdrops: jungle far, mid and canopy; castle far and mid.
A file already there is never replaced. Copy one into your game's folder, change it, and paint it. If paint_art2d finds no recipe at the path, it answers with a starter that paints as it is.
Every recipe
"format": "ttr.art2d"."kind":"sprite"(the default),"terrain"or"backdrop"."palette": names for colours,{"gold": "#ffd23f"}.outlineis the ink colour; it defaults to a dark brown.- Colours anywhere: a palette name,
"#rrggbb", or[r, g, b]from 0 to 1. "about": a note for people; the painter ignores it.
Sprite sheets
"frame": [w, h]: one frame's size in pixels. Coordinates are frame pixels, x to the right, y down from the frame's top-left."outline": the default ink width, in pixels."clips":[{"name": "run", "frames": 8, "fps": 12, "once": false}], played in order. The sheet lays the frames out left to right ("columns"wraps them into rows)."parts": drawn in order, back to front. Each part has:"shape":circle,ellipse,box,capsuleorpolygon;"at", plus"size": [w, h]or"radius";"turn"in degrees;"corner"rounds a box or polygon;"points"(a polygon's corners) and"to"(a capsule's other end);"fill","shade"(a colour, or 0 to 1 for darker underneath),"outline","outline_color","rim"(a light edge, in pixels),"highlight"and"opacity";"pose": per clip, one[dx, dy, degrees, squeeze]for each frame, cycling if shorter. Squeeze narrows the part (a coin's spin)."pivot"sets the point it turns around (the default isat);"only": ["run"]or"skip": ["idle"]to show a part in some clips only.
A two-frame bouncing ball:
{
"format": "ttr.art2d", "kind": "sprite", "about": "A red ball that bounces (2 frames).",
"frame": [96, 96], "outline": 4,
"palette": {"red": "#e8463c", "red_dark": "#a82a24", "shine": "#ffd9cf"},
"clips": [{"name": "bounce", "frames": 2, "fps": 6}],
"parts": [
{"shape": "ellipse", "at": [48, 84], "size": [56, 10], "fill": "#000000", "opacity": 0.25, "outline": 0},
{"shape": "circle", "at": [48, 50], "radius": 28, "fill": "red", "shade": "red_dark", "rim": 4,
"pose": {"bounce": [[0, 0, 0, 1], [0, -10, 0, 0.92]]}},
{"shape": "ellipse", "at": [38, 38], "size": [14, 9], "turn": -30, "fill": "shine", "outline": 0,
"pose": {"bounce": [[0, 0, 0, 1], [0, -10, 0, 0.92]]}}
]
}
Terrain tilesets
"kind": "terrain" paints the 16 pieces an auto-tiling block needs (tops, sides, corners, thin ledges, fill). It writes <out>.png and <out>.tileset.json, which a tilemap { tileset "2D/mygame/ground.tileset.json" ... } uses.
"cell"(default 160) and"pad"(16): the cell size, and the margin that lets shapes run past the tile edge on joined sides, so joins have no seams."style":"grass"(a scalloped grass cap on dirt with pebbles, and roots under ledges) or"stone"(brick courses with a cobbled cap and moss)."palette":top,top_dark,fill,fill_dark,speck, plusmoss(stone),woodandrope(bridge),ladderandspike."variants": 1 to 4. With n, the set is painted n × n times, each one patch of a larger fill pattern, so big blocks of ground don't show a repeating tile."extras":["bridge", "ladder", "spikes"](the default). They become the tiles=(one-way bridge),H(ladder) and^(spikes, a hazard).#is solid ground."seed": a different seed scatters the pebbles and blades differently.
Backdrops
"kind": "backdrop" paints one wide picture ("size": [2048, 768] by default) that repeats seamlessly across its width, for parallax layers behind the level.
"sky": [top, bottom]: a gradient behind everything; leave it out for a see-through layer."layers", painted in order: each has a"type"ofhills,trees,columns(ruined pillars),vines,rays,mistorclouds, plus"color","height"(0 to 1 of the picture),"count","seed","opacity", and optionally"outline"and"shade".
Paint the far, middle and near layers as separate backdrops, so each can scroll at its own depth.