# Capability group: `gamedev` / `gamedev-2d` — assets 2D para Godot (generación + post-proceso + puente)

Cluster de funciones para producir y mover assets 2D de juego entre **ComfyUI**
(generación) y **Godot 4** (consumo). Tres capas:

1. **Builders de workflow 2D** (`gamedev-2d`, GPU): construyen el dict (API format)
   de los workflows ComfyUI para pixel-art, tiles seamless, isométrico, sprites de
   personaje y VFX en bucle. Son **puros** (no tocan GPU al construir); el coste GPU
   está al enviar con `comfyui_submit_workflow`.
2. **Post-proceso determinista** (`gamedev`, CPU): pixelizar, recortar a alpha.
3. **Puente de assets** (`gamedev`, CPU): coloca el resultado en un proyecto Godot
   con sus import settings.

Tags: `gamedev` (post-proceso + puente) y `gamedev-2d` (builders de workflow).
Filtro: `mcp__registry__fn_search query="" tag="gamedev-2d"`.

Documento hermano del grupo `comfyui` (generación genérica de imágenes/video/3D).
Diseño del puente: `docs/comfyui-godot-integration.md`. Planes origen: `reports/0135`
(pixelart), `reports/0139` (entornos/tiles/iso), `reports/0137` (personajes/sprites),
`reports/0140` (VFX), `reports/0143` (ronda 2b: builders).

## Builders de workflow 2D (`gamedev-2d`, puros — generación)

Construyen el dict API format listo para `comfyui_submit_workflow`. Cada uno compone
funciones existentes del registry (`comfyui_build_txt2img_workflow`, `comfyui_inject_*`,
`comfyui_build_ipadapter_workflow`) — no reinventan el grafo. class_types verificados
contra `/object_info` del server (8GB lowvram). Probados e2e en GPU: pixelart, seamless,
VFX (ver `reports/0143`).

| ID | Firma corta | Qué hace |
|---|---|---|
| `comfyui_build_pixelart_workflow_py_ml` | `(positive, negative=…, *, ckpt_name="juggernaut_xl_v11…", pixel_lora="pixel-art-xl…", use_lcm=True, …) -> dict` | Fase 1 pixel-art: SDXL + LoRA pixel-art-xl (+ LCM 8 steps). El pixel-perfect es post (`comfyui_pixelize_image`). |
| `comfyui_build_seamless_tile_workflow_py_ml` | `(positive, negative="", *, tiling="enable", copy_model="Make a copy", circular_vae=True, material_lora=None, …) -> dict` | Textura tileable: `SeamlessTile` (Conv2d circular) + `CircularVAEDecode`. Coste VRAM ≈0. |
| `comfyui_build_isometric_workflow_py_ml` | `(positive, negative=…, *, iso_lora="isometric_game_assets_sd15…", grid_image=None, …) -> dict` | Asset iso 2:1: LoRA iso + ControlNet grid opcional. |
| `comfyui_build_sprite_sheet_workflow_py_ml` | `(subject, *, ref_image=None, pose_skeleton=None, char_lora=None, transparent=True, …) -> dict` | UN sprite de personaje: IPAdapter-FaceID + LoRA + ControlNet OpenPose (Advanced, end<1) + Rembg. Varias poses → sheet. SD1.5. |
| `comfyui_build_vfx_spritesheet_workflow_py_ml` | `(prompt, *, motion_model="mm_sd_v15_v2.ckpt", num_frames=16, closed_loop=True, lora=None, …) -> dict` | N frames AnimateDiff loop sobre negro (insumo de luma→alpha). 8GB: 16f@512² revienta, usar ≤8f@512² o bajar resolución. |

## Funciones de post-proceso y puente (`gamedev`, CPU)

| ID | Firma corta | Qué hace |
|---|---|---|
| `comfyui_pixelize_image_py_ml` | `(src, dst, *, downscale=8, colors=16, palette=None, dither=False, upscale_back=True) -> dict` | Pixel-perfect: downscale nearest + cuantización a N colores o paleta fija (game-boy/pico-8/nes). Fase 2 pixelart. Impura (I/O). |
| `comfyui_matting_luma_to_alpha_py_ml` | `(image_path, *, out_path=None, gamma=1.0, black_point=0.0, premultiply=False, luma_weights=(.299,.587,.114)) -> dict` | Frame VFX sobre negro -> RGBA usando luminancia como alpha (translúcidos con additive blend). Impura (I/O). |
| `comfyui_export_asset_to_godot_py_pipelines` | `(asset_path, kind, godot_project, *, name=None, reimport=True, godot_bin=None) -> dict` | Copia el asset a `res://assets/<dir>/` por `kind` + escribe `.import` + filtro Nearest si pixelart + reimport headless. Pipeline impuro. |
| `godot_map_asset_dir_py_core` | `(kind) -> str` | Mapea `kind` -> subcarpeta de `res://assets/`. Pura. |
| `godot_clean_asset_name_py_core` | `(filename, *, override=None) -> str` | Normaliza el nombre `<prefijo>_NNNNN_.<ext>` a snake_case seguro para `res://`. Pura. |

## Ejemplo end-to-end con builder (Fase 1 GPU → Fase 2 CPU → Godot)

Flujo completo pixel-art: construir workflow → generar en ComfyUI → pixel-perfect → Godot.

```python
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_build_pixelart_workflow import comfyui_build_pixelart_workflow
from ml.comfyui_submit_workflow import comfyui_submit_workflow
from ml.comfyui_wait_result import comfyui_wait_result
from ml.comfyui_fetch_output_image import comfyui_fetch_output_image
from ml.comfyui_pixelize_image import comfyui_pixelize_image

# 1. Construir (puro) + 2. generar (GPU)
wf = comfyui_build_pixelart_workflow("isometric tiny house, pixel, 32x32 style", use_lcm=True, seed=42)
pid = comfyui_submit_workflow(wf)["prompt_id"]
outs = comfyui_wait_result(pid, timeout=300)
fn = next(img["filename"] for o in outs.values() for img in o.get("images", []))
raw = comfyui_fetch_output_image(fn, dest_dir="/tmp")["out_path"]
# 3. pixel-perfect (CPU) -> 4. export Godot (ver ejemplo de abajo)
px = comfyui_pixelize_image(raw, "/tmp/house_pixel.png", downscale=8, colors=16)
```

VFX: `comfyui_build_vfx_spritesheet_workflow(prompt, num_frames=8)` → submit → fetch N frames
→ `comfyui_matting_luma_to_alpha` por frame → montar sheet RGBA con `Image.alpha_composite`
(NO `comfyui_build_grid`, que aplana el alpha).

## Ejemplo canónico de post-proceso

Flujo: crudo generado en ComfyUI -> pixelizar -> exportar a Godot con Nearest.

```python
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_pixelize_image import comfyui_pixelize_image
from ml.comfyui_matting_luma_to_alpha import comfyui_matting_luma_to_alpha
from pipelines.comfyui_export_asset_to_godot import comfyui_export_asset_to_godot

OUT = os.path.expanduser("~/ComfyUI/output")
PROJ = os.path.expanduser("~/gamedev/projects/crossy_road")

# 1. Pixelizar un sprite crudo (SDXL+pixel-art-xl) a 16 colores
px = comfyui_pixelize_image(f"{OUT}/hero_00001_.png", "/tmp/hero_pixel.png",
                            downscale=8, colors=16)

# 2. Exportarlo a Godot como pixelart (carpeta sprites/, filtro Nearest, reimport)
exp = comfyui_export_asset_to_godot("/tmp/hero_pixel.png", "pixelart", PROJ)
print(exp["dest_res_path"], exp["pixelart_filter_set"], exp["reimported"])

# Rama VFX: frame de humo sobre negro -> RGBA -> carpeta vfx/
rgba = comfyui_matting_luma_to_alpha(f"{OUT}/vfx_loop_00007_.png", gamma=1.2, black_point=0.04)
comfyui_export_asset_to_godot(rgba["out_path"], "vfx", PROJ)
```

## Fronteras (qué NO cubre)

- **Montaje de spritesheet dedicado** (grid RGBA + JSON sidecar para Godot/Unity):
  no hay función propia todavía — el ejemplo VFX monta con `Image.alpha_composite`
  inline. `comfyui_build_grid` NO sirve (aplana el alpha sobre fondo oscuro). Pendiente
  de R4 (plan `reports/0140` F2).
- **Pipelines one-shot** (build → submit → wait → fetch → post en una call) para
  pixelart/sprite/VFX: pendientes. Hoy se encadena a mano (ver ejemplos). Candidatos a
  promoción a pipeline (issue 0087) cuando el patrón se repita.
- **Sprite turnaround multi-vista** (orquestar N poses con identidad fija + juez):
  el builder `comfyui_build_sprite_sheet_workflow` produce UN frame; la orquestación
  multi-pose es pipeline pendiente (plan `reports/0137` T2).
- **Paletas lospec por red** (`load_lospec_palette`): no incluido. `pixelize` usa
  paletas fijas embebidas (game-boy/pico-8/nes) o lista de hex, sin HTTP.
- **TileSet / SpriteFrames `.tres`**: Godot no los deriva solos; `export_asset_to_godot`
  copia la textura y avisa, pero no genera el recurso (paso manual o futura función).

## Prerequisitos / notas

- **Godot CLI** para el reimport headless: autodetectado en PATH y en
  `~/godot/Godot_v4.7-stable_linux.x86_64`. Si falta, `export_asset_to_godot` deja el
  `.import` escrito y lo anota (no falla).
- **Filtro Nearest (Godot 4)**: se setea global en `project.godot`
  (`default_texture_filter=0`), no por `.import`. La función lo asegura para pixelart.
- CPU-only: Pillow + numpy del venv del registry. Cero VRAM, cero red.
