---
name: comfyui-art
description: Generate game art locally with ComfyUI, using the model profile that fits the user's graphics card (Z-Image Turbo by default, smaller builds or SDXL for cards with less video memory) — concept paintings, character portraits, pixel-art sprites and sprite sheets, props, placeholder art — then clean it onto a project's palette and canvas. Use when ComfyUI is the generator — the project's style guide (docs/art/art-direction.md) names it, art-direction picked it, or the user asks for ComfyUI — and they want images or art created, drawn, iterated on or explored ("make a portrait for the old sailor", "we need a sprite for the cook", "try some style variations"). With no generator chosen yet, art-direction §2 first checks what is already set up. Handles starting ComfyUI, the concept → pixel-art → palette pipeline, and both guided iteration (the user picks each round) and unattended iteration (a critic agent picks); its palette cleanup also works on images from other generators.
---

# ComfyUI art

Local image generation with ComfyUI. Everything is driven by scripts in this skill's `scripts/`
folder — call them with the absolute path of this skill:

- `comfy.py` — `hardware`, `status`, `start`, `free`, `txt2img`, `img2img` (crop, scale, denoise).
  Talks to ComfyUI's HTTP API. Do not drive the ComfyUI web page by clicking: its Run button opens
  a menu, and typed text lands in the node search, which cost several retries in the session this
  skill came from.
- `profiles.py` — the model profiles `comfy.py` can run. A profile is one complete setup: model
  files, the nodes that load them, sampler settings and its prompting notes.
- `pixel_post.py` — `key` (background removal), `report` (palette usage and a letter grid),
  `remap` (colour fixes by meaning), `holes`, `sheet` (review sheets), `frames`, `anim`.

The project's own palette tool (e.g. `pixelforge`) does the palette snap; this skill does not
replace it.

## 0. One-time setup (the user's machine)

ComfyUI is a free app that runs open image models on the user's own computer: images stay private
and cost nothing per picture, but it needs a capable graphics card and roughly 15 GB of downloads.
Say that in those words before asking anyone to install it, and only after `art-direction` §2 found
nothing already set up that fits.

- ComfyUI **portable** installed; `COMFYUI_ROOT` set to its folder (the one holding
  `python_embeded/` and `ComfyUI/`). `COMFYUI_URL` defaults to `http://127.0.0.1:8188`.
- The model files of **one profile**, chosen for this machine. Run `comfy.py hardware` first: it
  reads the graphics card and system RAM and lists the profiles that fit, best first, with which
  of their files are in place.

| Profile | Video memory | What it is | Prompting notes |
|---|---|---|---|
| `zimage-bf16` (untested) | 16 GB or more | The same model as `zimage-int8` at full precision, `z_image_turbo_bf16.safetensors` (12.3 GB, `diffusion_models`), with the same text encoder and VAE; about 17 GB to download | `references/prompting.md` |
| `zimage-int8` (default, tested) | 12 GB or more | Z-Image Turbo int8 (`z_image_turbo_int8_convrot.safetensors` in `diffusion_models`), `qwen_3_4b_fp8_mixed.safetensors` (`text_encoders`), `ae.safetensors` (`vae`); about 12 GB to download | `references/prompting.md` |
| `zimage-gguf` (untested) | 6–11 GB | The same model as a GGUF build, Q5_K_M (or Q4_K_M on 6 GB), plus a Qwen3-4B GGUF text encoder and the same `ae.safetensors`; needs the ComfyUI-GGUF custom nodes; about 8 GB | `references/prompting.md` |
| `sdxl-fast` (untested) | 4 GB or more | An SDXL checkpoint suited to the art direction, plus the DMD2 4-step LoRA; about 7 GB | `references/prompting-sdxl.md` |

Suggest the first profile `hardware` lists, say in one line why (the card, its memory), and say
plainly when a profile is untested: the first round with it is also a test of the profile. Below
4 GB, or with no NVIDIA card, suggest another image source instead (`art-direction` §2); ComfyUI
does run on AMD cards and Apple chips, but no profile here has been tried there.

`profiles.py` gives each profile's download source. The list is kept current by the SDLC's
maintainers: a profile never changes once released, newer ones are added beside it, and an old one
marked `superseded_by` is no longer suggested but keeps working for projects that use it.

**A model that isn't a profile.** If the user asks for one, check its family. A different file of
a profile's family (another SDXL checkpoint, another Z-Image build) works through `--ckpt`,
`--unet`, `--clip` and `--vae`; record the exact files in the style guide next to the profile
name. A family `comfy.py` can't build a graph for isn't supported here: say so, and suggest asking
the SDLC's maintainers for a profile. Never edit this skill's scripts from inside a project; the
installed plugin is replaced on every update.

If anything is missing, list what's missing with its source and size, and ask the user before
downloading anything (`art-direction`'s `scripts/image_sources.py` lists the missing model files).
For an untested profile, find the current files on Hugging Face and give their exact names and
sizes before asking.
If the user doesn't want a local install, go back to the sources `art-direction` §2 found. In
hands-off mode never install: use another source that is set up, or stop and say what's missing.

## 1. Decide the mode first

**Guided** (default): show every round to the user and let them choose and steer. Use it unless
the request clearly says otherwise.

**Unattended**: the user said so — "on your own", "don't wait for me", "unattended", "just come
back with the result", "let another agent review", or they are clearly away (a scheduled task,
a remote trigger). A critic picks each round instead of the user; read `references/critic.md`, which
also says when, inside a hands-off `art-direction` run, you pick seeds by its rubric instead.

If it's genuinely ambiguous (e.g. "make art for the three new crew" with no word on
involvement), ask once, in one line, and default to guided. State the mode you're using in your
first reply so the user can correct it.

## 2. Start-up

```bash
python <skill>/scripts/comfy.py status   # UP with free VRAM, or DOWN
python <skill>/scripts/comfy.py start    # only if DOWN; ~25 s, detached, log in COMFYUI_ROOT
```

- **Use the project's profile.** The style guide (`docs/art/art-direction.md`) names the profile
  its frames were made with; pass it as `--profile` on every `txt2img` and `img2img`. With no
  style guide yet, use the profile §0 chose. If this machine can't run the project's profile, say
  so and stop rather than switching: a different model draws a different look, so changing
  profile is a style-guide change (`art-direction` §2).
- `start` passes unknown flags on to ComfyUI: `--cuda-device N` when `hardware` says the largest
  card isn't the first, `--fp32-vae` on cards that return black images.
- The default profile needs ~11 GB of video memory. `status` splits usage
  into what ComfyUI itself holds (its models stay loaded between jobs — that is fine) and what
  other apps use. Only if **other apps** hold several GB (browsers, Electron apps, games) is there
  a problem: generation spills into system RAM and slows down. Tell the user which kinds of apps
  to close rather than killing anything.
- `comfy.py free` unloads the models when you're done, if the user needs the card back.
- If `start` fails, read the last lines of `comfy_server.log` in the ComfyUI folder.

## 3. Load the project's art rules before prompting

Art has to fit a project, so find its rules first — most of the quality comes from here:
- the style guide the `art-direction` skill saved (`docs/art/`): its chosen frames are image
  references for every new asset, and its prompt core starts every prompt;
- a project skill about art, which takes precedence over this file for anything
  project-specific (palette, canvases, reserved colours, naming, where assets live);
- art direction and contract docs, the palette file (`.gpl`), the palette tool's config (e.g.
  `pixelforge.toml` canvases);
- existing assets of the same kind — the new one must sit next to them.

Pull the few lines that matter (palette intent, reserved colours, canvas, tone) into your prompts
as concrete colours, light and materials. Take **hard rules** (reserved colours, budgets,
canvases, naming) from the tool config rather than the prose — prose can lag the config, and when
they disagree, follow the config and tell the user. If the project has no art rules, ask for
target size and palette, or produce unconstrained concepts and say so.

## 4. Where files go

Work outside the project, in `$COMFYUI_WORK/<project>/<asset>/` (default `~/comfyui-work`; call it
`$W`), one subfolder per round, with the prompt text saved beside its images so any result can
be reproduced.

**Never write generated art into the project** unless the user approves a specific result for
it. Then the project's own rules apply (branch, naming, lint), including any rule the project
sets about generated art.

## 5. Pick the route for the asset

| Asset | Route (details in `references/process.md`) |
|---|---|
| Character portrait / bust | concept painting rounds (last one on a flat backdrop) → img2img close-up if needed → pixel repaint → clean → meaning fixes |
| A set of states of one character | finish one state, derive the rest from it by low-denoise img2img (`process.md` §8) |
| Character sprite / sprite sheet | txt2img pixel sprite at 1024 → clean → meaning fixes → hand edits for extra poses → `frames`/`anim` |
| Prop, event marker, token | txt2img at an integer multiple of the canvas, subject size stated → clean |
| Style exploration | several style directions × 4 seeds → clean each → one board + an in-context composite |
| Icons / UI marks under ~32×32 | don't generate — have a code-writing agent place the pixels |
| Opaque backdrops | generate at an exact multiple, downscale by nearest, snap without keying |

Before writing prompts, read the profile's prompting notes (§0's table): `references/prompting.md`
for the Z-Image profiles, whose table of "wrote X, got Y" is the difference between one round and
four, or `references/prompting-sdxl.md` for `sdxl-fast`.

## 6. Guided rounds

Each round: generate (usually 4 seeds), build a review sheet with `pixel_post.py sheet` (add
`--actual` once it's pixel art), send it with `SendUserFile` when available, and ask the user to
pick one and say what to change — `AskUserQuestion` with the candidates as options works well.
Give your own read in a few lines (what worked, what missed, what you'd change next) so the user
is choosing, not auditing. Change one or two things per round and say which.

## 7. Done means

- never raw generator output: every asset is cleaned onto the palette and canvas, and each batch is
  checked for the generator's habits (lifelike skin where it doesn't belong, glossy highlights, a
  variant that changed colour but not shape);
- palette tool clean (lint passes), with the dry-run remap read before writing;
- colours checked by **meaning**, not just membership (`references/process.md` §5). For pixel art,
  reserve each signal colour to the asset paths that may use it, and lint that too;
- for pixel art, transformed only by whole numbers (scale ×2, ×3; mirror; shear or redraw instead of
  rotating), since anything else smears the pixels;
- judged at true size **and** composited on real game art at game scale;
- the user has seen it (guided) or received the unattended report (`references/critic.md`);
- honest limits stated — what a human artist would still touch up.

## Troubleshooting

- `no ... file matching` or `has no ... node` from `comfy.py` — the profile's files or custom
  nodes aren't installed; `comfy.py hardware` lists what each fitting profile still needs.
- `rejected:` from `comfy.py` — ComfyUI refused the graph; its message names the node and input.
- All-black or mush output — width/height below 512, VRAM exhausted (`free`, close apps), or a
  card that overflows in half precision (GTX 16-series): restart with `comfy.py start --fp32-vae`.
- The model ignores the background colour — regenerate; see `prompting.md`, "Backgrounds".
- A pixel-art LoRA for Z-Image exists in `models/loras`; it was tested and rejected (finer, not chunkier
  pixels; anime drift). Only use it if the user asks.
