Generator selection
Pick a generator and see what it costs.
Choosing the generator is the largest cost and capability decision in a PixelKiln manifest. The figures here were measured against a live PixelLab account; ENDPOINTS.md contains the detailed experiments.
Quick choice
| You need | Generator | Measured cost | Candidates/output |
|---|---|---|---|
| Standalone prop or icon with arbitrary dimensions | map (default) | 1 generation | 1 |
| Exact fixed palette | pixflux, or imagePro for a larger or non-square canvas | 1 generation (imagePro: 10–25) | 1 inline image (imagePro: 1–64 by size) |
| Candidate variety, richer rendering, future rotation/animation | 1dir | 10–25 generations | 4–64 by size |
| Ground tiles or connectable structural sets | tiles | 10–25 generations | variations or complete set |
| Two-terrain Wang tileset for elevation (grass to water, floor to cliff), or a sidescroller platform set | terrain | Pro 15 at 32px and sidescroller 3, Pro 25 at 64px, standard 3 (all measured; standard plans at 4) | 16 or 25 tiles |
| Platform tileset for a sidescroller (stone body, grass top) | terrain, terrainOrientation: "sidescroller" | 3 generations | 16 tiles |
| A single elevation tile — a raised mesa, a cliff block | isometricTile | 1 generation | 1 |
| Larger or non-square scene or background, up to 792 wide and 688 tall | imagePro | 10–25 generations by canvas | 1–64 by size |
| Controlled pose/expression sequence in ComfyUI | frames | 0 free provider units | one atomic ordered set |
| Animated GIF or spritesheet from Retro Diffusion | animation | $0.07–$0.25 per animation (published price) | 1 GIF or PNG sheet |
| A character facing 4 or 8 directions, its poses, and its animations | character | 1 per base (standard), 10–25 per pose or portrait, 1 per template loop (2–4 as skeleton-v3), 20 per outfit (measured once) | one set of directions, one ordered loop, or one portrait |
| A prop, creature, or vehicle with rotations, states, or loops but no character rig | objectPro | about 6 per base at 64px (unmeasured) | one set of directions, or one ordered loop |
| UI chrome — panels, buttons, health bars, toolbars | uiAsset | 20 generations (measured once, at 256x192) | 1 composited image |
| One UI element from a description, 16px and up, optionally guided by a concept image | uiElement | 10–25 generations (unmeasured) | 1 image |
| A styled still on the Pro Flash model, or the south sprite a Pro Flash character will rotate | imageProFlash | 5–9 generations (PixelLab's provisional quote) | 1 image |
| An animated effect (spell, hit, explosion, aura), on its own or around a sprite | vfx | free from presets and parts; 1–28 when described to PixelLab's artist (lite measured at 1; plans at twice the quote) | one ordered frame set |
Start with map unless a required capability points elsewhere. Twenty-five
map re-rolls cost the same as one 64×64 1dir call.
terrain and imagePro have no section below: their fields and limits are in
the PixelLab skill reference,
including Pro's border controls, sidescroller sets, and connecting sets that
share a terrain (an asset's connect), and a terrain set's export shape is
in Tiles. Retro Diffusion
animation styles are in Set up Retro Diffusion.
map
map calls PixelLab's map-object endpoint. It is purpose-built for isolated
props, badges, and icons, supports arbitrary width/height, and costs a flat one
generation at every supported size.
Use it when:
- one result per prompt is acceptable;
- prompt prose can carry the style;
- exact palette conformance and reference-image transfer are not required.
It does not accept style images or a forced palette. On a measured 1-bit restyle,
switching from reference-anchored generation to map changed median palette
distance from 6.6 to 41.9; cheap output is not cheap when unusable.
The API describes map objects as transparent, but both 256px isolated-object
attempts in the environment provider benchmark were
opaque. map has no noBackground control in PixelKiln. Check alpha before
assuming the file can be placed directly over a map.
Drawing into a scene
A map asset can declare a scene: an existing picture of the place the
object belongs in (a floor, a room, a level). PixelLab draws the object into
that scene and in its style, which is the one way to match a specific map's
look without a style image. The price is still one generation.
"barrel": {
"prompt": "a small wooden barrel",
"width": 64, "height": 64,
"scene": { "image": "maps/tavern-floor.png", "placement": { "oval": 0.3 } }
}
scene.imageis a manifest-relative PNG. It can be another asset's output; until that file exists,planshows this asset as blocked. Its bytes are part of the spec's identity, so a redrawn scene makes the object stale.scene.placementis where the object goes:{ "oval": f }or{ "rectangle": f }, a region PixelLab generates coveringf(0.05–0.95) of the scene, or{ "mask": "path.png" }, a PNG the size of the scene, white where the object goes and black for context. The default is{ "oval": 0.3 }, PixelLab's own.- PixelLab only. Other providers refuse
scenewhen the manifest is resolved.
Unverified until a real call is billed: whether the scene has to match the
object's width/height or can be a larger picture; where an oval or a
rectangle sits, since the API takes no position (presumably centered); and
whether the result is the object alone or the object composited into the
scene. Check the first result before drawing a batch.
1dir
1dir is the single-facing sibling of PixelLab's rotatable/animated object
pipeline. It is square and priced by canvas area:
| Pixel area | Cost |
|---|---|
| ≤1024 | 20 |
| ≤2048 | 25 |
| larger | 40 |
Candidate count is also size-derived and does not reduce price:
| Square size | Candidates |
|---|---|
| ≤42 | 64 |
| ≤85 | 16 |
| ≤170 | 4 |
| >170 | 1 |
Use 1dir when candidate comparison, rendering detail, rotations, or animation
justify the price. Style reference images are its strongest consistency tool.
The largest reference determines output size, so references should already be
at the target resolution. Keep style references separate from live assets:
editing a reference intentionally invalidates every spec using it.
Candidate scoring is deterministic RGB palette-distance arithmetic. No LLM selects the artwork; the local contact sheet exists for human judgment.
Batch: several distinct objects for one call's cost
1dir's own candidate mechanic (the table above) normally returns several
variations of one prompt to choose from. PixelLab's
/create-1-direction-object also accepts item_descriptions: instead of N
variations of one thing, N different described things, for the exact same
canvas-tiered price — a loot table's worth of icons for the cost of one call.
One asset is the batch leader (an ordinary 1dir asset; its own prompt is
implicitly slot 0), and its siblings claim the remaining slots:
{
"assets": {
"chest": { "prompt": "a treasure chest" },
"potion": { "prompt": "a health potion", "batch": { "of": "chest", "index": 1 } },
"key": { "prompt": "a rusty key", "batch": { "of": "chest", "index": 2 } }
}
}
index is 1-based, unique, and contiguous among siblings (the leader is
implicitly 0); the total (1 + members) cannot exceed the size's own candidate
count from the table above (16 at ≤85px, for example). Every member must
share the leader's exact canvas size — they are one API call, one size.
Only the leader spends. Its estimate() prices the whole call, same as a
standalone 1dir asset of that size; every member reports zero cost, so
--budget never double-counts one call across N lock entries. Submitting
fans the leader's one job out to every member's own lock entry directly —
members never call the provider a second time.
Every sibling's identity depends on the whole group. The spec hash includes the full ordered list of descriptions, not just an asset's own prompt, so changing any one member's text — or adding or removing a member — marks every sibling stale together. This isn't a choice pixelkiln made: PixelLab has no endpoint to add one more item to an already-submitted batch, so a batch's membership needs deciding before it's generated. Growing an existing batch later means declaring a new one, not editing the old.
Review works exactly like any other 1dir asset, once per sibling: each
lands in pixelkiln pick independently (all sharing the same, real candidate
set), and picking a different index for each is what actually turns N
generated frames into N separate, kept assets. A member's row starts already
scrolled to, and marked DECLARED, at its own declared index — a hint
from the confirmed slot order below, not a forced choice; any candidate in
the set can still be picked for any sibling.
Confirmed live against a Tier 2 account: a 32px, 3-item batch (a chest
leader plus a potion and a key member) billed exactly 20 generations — the
ordinary 1dir floor tier, unaffected by item_descriptions — and
item_descriptions[0] does own candidate slot 0: frame 0 came back as the
chest, frame 1 as the potion, frame 2 as the key, in exactly the declared
order. The remaining candidates (61 of 64, at this size) are the model's
ordinary per-slot variety, not repeats of any one description — free bonus
material, not additional declared items. Only confirmed at this one size;
whether the cost table's higher tiers hold unchanged is still unconfirmed.
pixflux
pixflux costs one generation, returns inline without polling, and supports a
hard palette constraint:
"gameboy": {
"generator": "pixflux",
"palette": ["#0f380f", "#306230", "#8bac0f", "#9bbc0f"],
"outDir": "art/gameboy"
}
A palette prompt is a request; pixflux's swatch is a constraint. Measured
two- and four-color outputs contained exactly the supplied colors.
Trade-offs:
- rendering is flatter than
1dir; - style reference images are unavailable;
- the same
color_imagepayload does not work onmap; - inline results are temporarily cached between submit and fetch;
noBackgrounddefaults to true in PixelKiln, which is correct for sprites but wrong for scenes and banners.
Set noBackground: false for full-bleed artwork. Prompt prose cannot undo a
post-generation background-removal step.
tiles
tiles calls the tile-pro endpoint and understands tile geometry and
connectable output sets.
"ground": {
"generator": "tiles",
"tileSize": 32,
"tileType": "isometric",
"tileView": "low top-down",
"outlineMode": "segmentation",
"outDir": "assets/tiles/src"
}
Independent variations enter the normal review-and-pick flow. A tileFeature
instead creates a structural set in provider order:
| Feature | Meaning |
|---|---|
roads | 18-configuration connected path/road set. |
tileset | 16-tile Wang-corner terrain transition. |
building | Floor/wall/doorway/pillar/stair construction kit. |
Describe a tileset asset as the transition, "fairway grass to rough meadow",
rather than one terrain. Every returned member is required, so PixelKiln
records numerical roles such as tile-00 rather than treating them as choices.
Important constraints:
- Style mode copies geometry from
styleImagesand ignorestileTypeandtileView. It is useful when new independent tiles must match an existing ground plane. tileFeatureandstyleImagescannot be combined; PixelLab rejects it and the manifest catches it before spending.- Use
outlineMode: "segmentation"for continuous ground. The provider default outlines every tile, which produces dark seams when repeated. - Six-edge and unknown adjacency families remain lossless in generic export but are rejected by engine exporters that cannot map them safely.
frames
frames currently belongs to ComfyUI. It repeats one committed still-image
workflow while varying one explicit per-asset binding, such as an ordered set
of pose PNGs. It is not video diffusion. The whole sequence stays one planned,
reviewed, downloaded, refined, and approved asset; partial sets never become
packaging input.
Keep a fixed seed for identity, or opt into a deterministic seedStep. Use a
quality profile so every frame shares one palette and must agree on detected
native grid step and phase. The review page animates the sequence, shows the
ordered strip, and lets the reviewer pause playback. It starts paused when the
system requests reduced motion and stops while it is offscreen. After approval,
pack emits the sprite sheet and stable
asset/frame-XX atlas ids. See
Set up ComfyUI.
character
character is PixelLab's character family as managed assets: a base drawn
facing 4 or 8 directions (from a prompt, or from your own south-facing
sprite with reference), states (a pose or a text-edited outfit) that
PixelLab applies to every direction of an existing character, animations,
one loop of one character in one direction, portraits, a bust made from
the south sprite, and outfit transfers, an existing loop's frames
re-clothed from a reference image instead of text. A state, animation,
portrait, or outfit depends on its parent the way a revision does: the
parent must be downloaded and current before the child can be submitted,
and regenerating the parent makes the child stale.
| Asset | PixelLab call | Cost |
|---|---|---|
base, mode: standard | create-character-with-4/8-directions | 1 |
base, mode: v3 | create-character-v3 | 1 + ceil(size² × 8 / 65536): 2 at 64px, 3 at 128px; from a reference, the rotations alone on its canvas: 1 at 64px |
base, mode: pro | create-character-pro | 10–25 by canvas |
base, mode: pro-flash | create-character-pro-flash | image tier (5 to 96px, 6 to 208px, 9 above) + ceil(size² × 8 / 65536): 6 at 64px, 8 at 128px, 17 at 256px; rotations only from a reference |
| state | create-character-state | 10–25 by canvas |
animation with a template | animate-character | 1 |
| animation from text (v3) | animate-character | ceil(size² × frames / 65536): 1 at 64px, 2 at 128px |
animation, mode: pro | animate-character | 10–25 by canvas |
| portrait | portrait-character-pro | 10–25 by size (16px billed exactly 20 live, before the October 2026 cut) |
| outfit | transfer-outfit-v2 | 20 (a 2-frame, 92×92 job billed exactly this live; not yet measured at other frame counts or canvases) |
The 20–40 tiers are PixelLab's; the tier is resolved from the canvas when
the job runs and reserved against the floor, so plan reports the tier the
canvas lands in. plan prices a 64px state at 40 (the 1dir tier for that
many pixels); one live 64px state in September 2026 moved the balance by
about 22, so the estimate reads high, which is the safe side for a budget.
poll now reads what a job like this actually billed and records it
alongside the estimate as billed; pixelkiln history, plan --json, and
the gallery show both when they differ, though gen's wave budget still
spends against the (safe-high) estimate.
Every direction of a base or state is one file
(<asset>-south.png, ...); an animation's frames are <asset>-frame-00.png
onwards, with the resting pose as frame 0 unless keepFirstFrame is off.
enforcePalette snaps all of them. Since each direction of a loop is its
own generation, declare the east-facing loop as a mirror of the west one
(and each diagonal as a mirror of the other) and PixelKiln flips it locally
for nothing; see Mirrors. pack --format godot
writes each base direction as a still and each animation as a looping set.
The gallery
labels a state or loop with its parent ("state of bot", "loop of
bot.dented, east"), links parent and children in the record, and counts the
family in the style header ("3 characters, 4 states, 6 loops"). See
Characters.
objectPro
objectPro wraps PixelLab's /create-object-pro-flash — the same base
→ state → animation family as character, for PixelLab's separate,
skeleton-free "object" entity. Use it for a prop, creature, or vehicle that
needs a pose (state) or a directional loop (animation) but has no
humanoid/quadruped rig to fit: a floating rune, a treasure chest, a turret,
anything character's template concept does not describe.
It reuses character's own authoring shapes — asset.state/asset.animation
are the identical fields, and a mirror flips an animation's direction the
same way. Everything character's templates/proportions/skeleton bring is
simply absent: no mode, template, proportions, isometric, concept,
or styleCharacter — /create-object-pro-flash is the only base-creation
path, and setting animation.template/subject/outline/shading/detail
on an objectPro animation is rejected at resolve time rather than silently
ignored, since none of them reach the API for an object.
objectDirections(1 or 8, default 8, style-level) is the rotation count — a real choicecharacterdoes not offer (character pro-flash is always 8). A 1-direction object'sanimation.directionmust besouth; anything else is rejected, since the endpoint 400s ifdirectionsis even sent for a 1-direction object.reference(asset-level, base only) rotates the author's own south-facing sprite instead of drawing from the prompt, same ascharacter's reference — but only ever reads the south image, since one frame is all/create-object-pro-flashtakes.- A style image anchors the look the same way
characterpro-flash's does, includingstyleTraits(which of the image's palette/outline/detail/shading to carry over). - Regenerating an already-animated direction is simpler than
character's: the object endpoint has its ownreplace_existingflag, so PixelKiln always passes it rather than fetching the object first to find and delete a prior take (character's own workaround for not having one). pixelkiln gallery --editshows anobjectProfamily the same way it shows a cast — states under their base, loops with their direction — and a base or state's drawer offers "+ New state" and "+ New animation", restricted to the fields above (notemplate/subject, since neither applies). See Working with a cast.
Cost is not independently measured. objectProCost() assumes
/create-object-pro-flash/its state/its animation price identically to
character's own measured pro-flash formula (proFlashCharacterCost),
since the request bodies are near-identical minus template_id — treat it
as a working assumption, not a confirmed number, until checked against a
live account.
Adoption (pixelkiln adopt) has not been extended for objectPro's own
<object id>#<animation group id> remote-id scheme yet, unlike character's
dedicated adoption path — a base may already be adoptable through the
generic object-matching pixelkiln already does for 1dir/map, since a
pro-flash object shares that same /objects identity space, but this is
untested.
isometricTile
isometricTile wraps PixelLab's /create-isometric-tile — a different
endpoint from both tiles (which also has its own isometric tileType
for full connectable Wang/road/building sets) and terrain (/create-tileset,
confirmed square-only, no isometric option at all). This one generates a
single standalone isometric tile, no candidates, no connectable set.
Use it when a per-tile height/elevation primitive is what's needed — a raised mesa, a cliff block, a standalone rock outcrop — rather than a connected ground set.
isometricTileShapecontrols vertical thickness:"thin tile"(~15% of canvas height),"thick tile"(~25%), or"block"(~50%, the API default). This is a more direct elevation control than anything intilesorterrain.isometricTileSizeis the API's own tile grid size, 16 or 32 (default 16) — a separate concept fromsize, the generation canvas (16–64px; the endpoint's own guidance is that sizes above 24px "often produce better quality results").outlinedefaults to"lineless"on this endpoint specifically, unliketiles-pro's"outline"default — its own valid values are"single color outline","selective outline", or"lineless".
Cost: 1 generation flat, measured. PixelLab's own OpenAPI response schema
example shows { type: "usd", usd: 0.02 }, which reads as billing in real
dollars — but a real call against a live subscription account billed exactly
1 generation instead (usage: { type: "generations", generations: 1 }), and
costUnit here is "generations" like every other generator. Only one
size/tile-shape combination (32px canvas, "block") has actually been
measured; the endpoint's own docs give no size-tiering formula the way
1dir/tiles do, so this assumes flat pricing across the 16–64px range
rather than guessing a tier.
Style images, init_image/init_image_strength (image-to-image), and
color_image (native forced-palette) are not modeled yet — PixelKiln's own
palette/enforcePalette post-processing works generically on the
downloaded tile regardless, if a closed palette is what's actually needed.
uiAsset
uiAsset wraps PixelLab's /create-ui-asset — panels, buttons, health bars,
and other UI chrome, composited as one flat image. It is non-square capable
like imagePro: width/height default to 256×256 but can be set per asset,
subject to the endpoint's own aspect-gated size tiers (square up to 512×512,
16:9 up to 688×384, 9:16 up to 384×688, 4:3 up to 600×448, 3:4 up to 448×600;
pixelkiln refuses anything under 192 or over 688 per side and leaves the
exact aspect ceiling to the API).
Two asset-level fields, usable together or alone:
pieces: an array of exact shape regions (rounded_rect,circle, orpolygon, each with a uniqueidand optionallabel) positioned on a virtual 0–512 coordinate canvas, independent of the actual output size.elements: named, auto-positioned scaffolds —button,icon_button,toolbar,tab,panel,window,health_bar,avatar,triangle,pentagon,hexagon,octagon.
Omit both for a plain full-canvas panel from the prompt alone. A style-level
uiColorPalette string (e.g. "brown and gold") is a free-text prompt hint
sent as color_palette — a different, PixelLab-side concept from
PixelKiln's own hex-array palette/enforcePalette (local quantization),
which still applies to the downloaded image afterward if an exact palette is
needed.
No cropping, no nine-slice, no states. GET /ui-assets/{id} returns one
composited image with no per-piece sub-image or bounding-box data, confirmed
absent from the response schema regardless of how many pieces/elements
were requested — despite pieces' own precise coordinates, PixelLab does not
hand back a way to split them out again. A themed variant of an existing
panel (an empty vs. full health bar, say) needs no new mechanism: it is a
plain revision (image-to-image) of the base panel, which already carries
this for every other generator.
Cost: confirmed live at one data point — 20 generations for a 256x192
canvas, the low end of the create_ui_asset MCP tool's "20–40
generations" claim. PixelKiln still estimates with the same canvas-tier
formula as 1dir/tiles, which predicts the 40 ceiling for every valid
uiAsset size (its 192px floor is already past that formula's top tier) —
the measured call proves the formula wrong here, since it billed the floor
price at an area well above where 1dir/tiles would bill the ceiling.
Left as an over-read for --budget until a second size is measured; see
ENDPOINTS.md for the full writeup.
imageProFlash
imageProFlash wraps PixelLab's /create-image-pro-flash: one native
pixel-art image on the Pro Flash model, the same model the character and
objectPro pro-flash engines draw with, as a plain still. It sits between
pixflux/map (1 generation, no style reference) and imagePro (10–25 by canvas):
{
"styles": {
"stills": {
"generator": "imageProFlash",
"styleImages": [{ "path": "refs/house-style.png" }],
"styleTraits": { "palette": true, "outline": true, "detail": false, "shading": true },
"outDir": "art/stills"
}
},
"assets": {
"knight": { "prompt": "a knight in blue armor, facing the viewer", "width": 64, "height": 64 }
}
}
- Sizes run 16 to 256 per side in multiples of 4, and can be non-square. PixelLab's native sizes (24, 32, 32×48, 64, 96×64, 96) are its most reliable; other sizes are its "custom (beta)" range.
- One
styleImagesentry is the style image, andstyleTraitschoose what it lends (palette, outline, detail, shading; each on by default), the same switches apro-flashcharacter base takes. Traits without a style image are refused. - One call returns one image, recorded straight away. The lock also records
PixelLab's
image_idandsource_image_idfor it: a Pro FlashcharacterorobjectProbase whosereferenceis this image's downloaded file reuses it by that id instead of uploading the same pixels again (see Characters). - Cost: 5 generations up to 96px on the longer side, 6 up to 208px, 9
beyond, from PixelLab's own
/pro-flash/costquotes, which PixelLab calls provisional. The billed amount on the finished job is what the lock keeps.planandgenuse these tiers offline. The gallery's price quote (--edit) asks the endpoint itself when the project has aPIXELLAB_API_KEY, and marks those rows live.
The same model also edits and inpaints: "engine": "pro-flash" on an
image-to-image or inpaint revision; see
Controlled asset revisions.
uiElement
uiElement wraps PixelLab's /generate-ui-v2 ("Generate UI (Pro)"): one UI
element — a button, a health bar, an inventory slot, a dialogue box — from
the prompt alone. Where uiAsset lays a panel out from pieces/elements
on a 192px-and-up canvas, uiElement has no layout vocabulary and goes down
to 16×16, which suits icons and small widgets:
{
"styles": {
"hud": {
"generator": "uiElement",
"uiColorPalette": "brown and gold",
"styleImages": [{ "path": "refs/hud-concept.png" }],
"outDir": "art/ui"
}
},
"assets": {
"slot": { "prompt": "wooden inventory slot with metal corners", "width": 32, "height": 32 },
"hp-bar": { "prompt": "health bar with a red fill", "width": 96, "height": 16 }
}
}
width/heightdefault to 256×256 and can be non-square: 16 up to 792 wide and 688 tall, with the exact ceiling set by aspect ratio upstream (square tops out at 512×512, 16:9 at 688×384).- The style's single
styleImagesentry, if any, is sent as the endpoint'sconcept_image: design guidance for the element, not a strict style transfer. More than one is refused. uiColorPaletteis sent ascolor_palette, the same free-text hintuiAssettakes. PixelLab removes the background by default; setnoBackground: falseon the style to keep it.- One call is expected to return one image, recorded straight away. If the
endpoint ever returns several, they go to candidate review like
imagePro's.
Unmeasured. The schema carries no usage example and no call has been
billed yet. The plan prices it on the same 10/15/25 canvas tiers as
1dir/tiles, the safe over-read for a Pro endpoint, and the completed
job's shape is read defensively (pollUiElement names the keys it got if
the shape is not the documented images list).
vfx
vfx renders animated pixel-art effects with PixelLab's VFX workbench:
spells, hits, explosions, auras, shields, status icons, weather. The workbench
is a renderer, not a model. An effect is a recipe of layers, most of them
dropped in as tuned parts, and it renders the same pixels every time. It is
free on a PixelLab subscription, and PixelLab offers it only over MCP, which
pixelkiln calls with the same PIXELLAB_API_KEY. An effect can also be
described in words for PixelLab's paid VFX artist; see
Described effects.
{
"styles": {
"fx": { "generator": "vfx", "outDir": "art/fx" }
},
"assets": {
"robot.zap": {
"prompt": "lightning on the robot",
"vfx": { "preset": "lightning_strike", "sprite": "art/chars/robot-south.png" }
},
"boom": {
"vfx": { "preset": "explosion", "parts": [{ "name": "scorch_mark" }], "fps": 12 }
},
"zap.tuned": {
"vfx": { "recipe": "fx/zap.vfx.json" }
}
}
}
- Start from one
preset(pixelkiln vfx presetslists them) or onerecipe, and addparts(pixelkiln vfx parts) on top.partsalone also start an effect. Each part is{ "name": … }plus any of the workbench's own options, sent as given:size,colour,amount,speed,start,end,anchor,at,offset,travel,role,params. recipeis a bare recipe JSON or a.vfx.jsonrecord written bypixelkiln vfx. That is how an effect tuned by hand, in the workbench or with the sliders on pixellab.ai, enters a manifest: export it withpixelkiln vfx --effect <id> --out fx/zap, then pointrecipeat the record.spritebuilds the effect around a character: a manifest-relative PNG or JPEG, or acharacter:<id>:<direction>,object:<id>, orgallery:<id>reference. A path may be another asset's output. Until that file exists the effect is blocked, andgenrenders it in a later wave once it does. The exported frames include the sprite.fpsoverrides the preset's or recipe's own rate.nameis the effect's name in your PixelLab My effects; it defaults topixelkiln:<style>/<asset>.promptis optional and only a label.- An asset that lists no
stylesjoins every style of its own kind: avfxstyle takes the assets with avfxblock, and every other style the assets without one. A mirror or revision of an effect names its style.
The workbench builds an effect from tuned parts. An effect that is a drawn
object or a character's own motion, like a sword turning into lightning or a
mage casting a fireball, is a job for generation instead: an imagePro
sheet of candidates, then an animate-pixminimax revision with an optional
lastFrame. PixelLab's
VFX tutorial shows that
workflow, and Set up PixelLab maps it onto
PixelKiln.
Outputs. The exported spritesheet is cut into frames,
<asset>-frame-00.png onward, recorded as an ordered frame set with the
effect's fps and whether it loops. pack lays them out like any loop, and
pack --format godot writes a one-shot effect with loop: false. The
gallery plays them, shows the rendered size, and links each generation to
its effect on pixellab.ai.
Identity. An effect goes stale when its preset, parts, fps, recipe
content, or sprite content changes. It does not go stale for a renamed or
moved file, a new name or prompt, or a style's prompt, size, or palette
settings, none of which reach the workbench. Plan cannot see slider changes
made on pixellab.ai or changes to PixelLab's own presets.
Regenerating. A regeneration exports over the effect the asset rendered last time, so My effects keeps one entry per asset. If that effect was changed on pixellab.ai since, or deleted, a new effect is saved instead and the edited one is left alone; the lock records why.
Described effects: the paid VFX artist
A description in place of a preset, recipe, or parts asks PixelLab's VFX
artist (POST /vfx, added in 0.4.130) to build the effect. The artist is the
same one behind the website's VFX creator: it picks and tunes parts from your
words, renders the effect, checks its own work, and saves it to My effects.
"zap.described": {
"vfx": {
"description": "a blue lightning strike that hits the ground and leaves sparks",
"artist": "pro",
"sprite": "art/chars/robot-south.png"
}
}
Use the free workbench when a preset or a few parts get you there, or when you want to tune the effect by hand; it renders the same pixels every time. Use the artist when you would rather describe the effect than assemble it. It costs generations, and the same description draws a different effect each time.
descriptionis the effect in plain words: what it is, its colours, how it moves, how long. It cannot be combined withpreset,recipe,parts, orfps; the artist picks those itself.artistislite(the default, quick and cheap) orpro(the stronger artist, for detailed effects).spritemust be a local PNG up to 512×512, another asset's output included. The endpoint takes the sprite's pixels, socharacter:,object:, andgallery:references are refused; point at the character's own output file instead. JPEG is refused too.nameis capped at 80 characters, and the default is cut to fit.
Cost. PixelLab quotes each job when it is submitted and bills on delivery: the quote, or more when the effect ran long, never more than twice the quote. The quote comes from this table (generations):
| lite | pro | |
|---|---|---|
| no sprite, or a sprite up to 128 px | 1 | 6 (8 with a sprite) |
| sprite up to 256 px | 3 | 14 |
| sprite up to 512 px | 5 | 28 |
plan and --budget count twice the quote, the most a job can bill, so
a budget is never overrun. A sprite that is another asset's output not drawn
yet is priced at the 512 px tier until it exists. The lock records PixelLab's
own quote (quotedGenerations) and the bill read from the finished job.
These prices are PixelLab's published table; no artist bill has been
measured here yet.
Outputs and identity. The artist's spritesheet is cut into the same
ordered frame set as the workbench's, with its fps and loop flag. The lock
records the effect id, its edit link, the artist's message, the anchor, the
parts it used, and the file names. The asset goes stale when its
description, artist, or sprite content changes, and not for name or
prompt. Adding these fields left every workbench effect's identity as it
was.
Regenerating. Every regeneration is a new effect, billed again. The
manifest's description is the whole effect, not a change to the last one,
so it is never sent as one. The previous effect stays in My effects, and the
lock names it (previousEffect). To change one saved effect in place at the
change price, use pixelkiln vfx --description "<what to change>" --effect <id> (CLI). To turn a described effect into a free,
repeatable recipe, export it with pixelkiln vfx --effect <id> --out fx/zap and point a workbench recipe at the record.
Style variants
Styles are namespaces. Add another style to re-derive the same asset ids into a separate output directory and separate lock keys:
"styles": {
"base": { "generator": "map", "outDir": "art/base" },
"neon": {
"generator": "1dir",
"size": 64,
"promptPrefix": "neon-noir game icon",
"promptSuffix": "magenta/cyan rim light, transparent background",
"styleImages": [{ "path": "art/style-refs/neon.png" }],
"outDir": "art/neon"
}
}
Seed a prose-only variant with two or three assets, commit the best results as dedicated references, then generate the remainder. Reference images control inherent subject colors more reliably than prose alone.
Limits and post-processing
PixelLab submissions must be spaced more than two seconds apart and concurrent background jobs are tier-limited. PixelKiln enforces both globally.
Image-in/image-out resize, rotate, and pixel-art conversion endpoints are generative and can change a closed palette or alpha channel. They cost the same as a fresh one-generation image. Regenerate at the target dimensions when palette fidelity matters; background removal is the measured exception, a real de-fringe pass.
PixelLab's portrait, outfit-transfer, lip-sync, and skeleton-driven
animation endpoints are outside the current library scope; the character
family itself is the character generator.
