---
name: comfyui_walk_cycle_oneshot
kind: pipeline
lang: py
domain: pipelines
version: "1.0.0"
purity: impure
signature: "def comfyui_walk_cycle_oneshot(character: str, *, frames: int = 4, size: int = 32, colors: int = 16, fps: int = 8, checkpoint: str = 'IMG_dreamshaper_8.safetensors', ref_image: str | None = None, server: str = '127.0.0.1:8188', dest_dir: str = '~/ComfyUI/output', seed: int = 0, pose_method: str = 'auto', controlnet_strength: float = 0.7, engine: str = 'pixeloe', palette=None, fmt: str = 'webp', **gen_kwargs) -> dict"
description: "Pipeline one-shot: de un prompt de personaje a una animacion de walk cycle en pixel-art (sprite sheet + GIF/WEBP en loop). Genera N frames frame-by-frame dirigidos por pose (ControlNet OpenPose con esqueletos del walk cycle, o fase del paso por prompt como fallback), con seed fija para identidad consistente y Rembg para alpha, y pixeliza cada frame a un grid duro size x size RGBA. Materializa el caso 1 de la investigacion de animacion de sprites (report 0217): personaje = frame-by-frame pose-driven, NUNCA modelos de video. Compone render_openpose_walk_skeletons + comfyui_build_sprite_sheet_workflow + submit/wait/fetch + comfyui_pixelize_sprite_png + assemble_animated_sprite. Impuro: red + GPU + disco. No-throw, salta frames que fallan."
tags: [gamedev-2d, comfyui, pixelart, sprite, animation, walk-cycle, controlnet, openpose, launcher]
uses_functions: ["render_openpose_walk_skeletons_py_ml", "comfyui_build_sprite_sheet_workflow_py_ml", "comfyui_submit_workflow_py_ml", "comfyui_wait_result_py_ml", "comfyui_fetch_output_image_py_ml", "comfyui_pixelize_sprite_png_py_ml", "assemble_animated_sprite_py_ml"]
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: ["os", "sys"]
params:
  - name: character
    desc: "Prompt del personaje (ej. 'pixel art knight, full body, side view'). No vacio. La identidad se mantiene entre frames con seed fija."
  - name: frames
    desc: "Numero de frames del ciclo (>=2, recomendado 4-8). 4 = las 4 fases canonicas contact-L / passing / contact-R / passing."
  - name: size
    desc: "Lado del grid pixel-art final por frame en pixeles (32 sprites pequenos, 64 personajes con mas detalle)."
  - name: colors
    desc: "Numero de colores de la paleta libre por frame (cuantizacion MEDIANCUT) cuando palette es None."
  - name: fps
    desc: "Cadencia de la animacion en frames por segundo (duration = 1000/fps ms por frame)."
  - name: checkpoint
    desc: "Checkpoint SD1.5 (ControlNet OpenPose + IPAdapter-FaceID solo instalados en SD1.5; default 'IMG_dreamshaper_8.safetensors')."
  - name: ref_image
    desc: "Imagen de cara de referencia en el input/ del servidor para IPAdapter-FaceID (segunda ancla de identidad). None = solo seed + prompt."
  - name: server
    desc: "host:port del servidor ComfyUI (sin esquema). Default 127.0.0.1:8188."
  - name: dest_dir
    desc: "Directorio donde guardar frames + sprite sheet + animacion (se expande ~)."
  - name: seed
    desc: "Semilla FIJA del KSampler para TODOS los frames (identidad estable entre poses)."
  - name: pose_method
    desc: "'openpose' (esqueletos OpenPose -> ControlNet, control exacto), 'prompt' (fase del paso descrita en el prompt, sin esqueletos) o 'auto' (intenta openpose, cae a prompt si el render falla)."
  - name: controlnet_strength
    desc: "Fuerza del ControlNet OpenPose (0.7 da buen control sin aplastar el estilo). Solo aplica en modo openpose."
  - name: engine
    desc: "Motor de downscale del pixelizado: 'pixeloe' (contrast-aware, conserva silueta) o 'nearest'."
  - name: palette
    desc: "None (paleta libre a colors), nombre builtin ('pico-8','nes','game-boy') o lista de hex. Fija ignora colors."
  - name: fmt
    desc: "Formato de la animacion: 'webp' (recomendado, alpha real) o 'gif' (alpha binario)."
output: "dict {ok, frames:[paths], spritesheet_path, animation_path, size, n_frames, seed, pose_method_used, skipped:[idx], error}. ok=True si se produjo la animacion con >=1 frame. n_frames puede ser < frames si alguno fallo (se salta y se sigue)."
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/pipelines/comfyui_walk_cycle_oneshot.py"
---

## Ejemplo

```python
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from pipelines.comfyui_walk_cycle_oneshot import comfyui_walk_cycle_oneshot

# Requiere el servidor ComfyUI vivo en 127.0.0.1:8188 (GPU).
res = comfyui_walk_cycle_oneshot(
    "pixel art knight, full body, side view",
    frames=4, size=32, colors=16, fps=8, seed=42,
    dest_dir="/tmp/comfy_walk_cycle",
)
print(res["ok"], res["n_frames"], res["animation_path"], res["pose_method_used"])
# -> True 4 /tmp/comfy_walk_cycle/walk_cycle.webp openpose
```

## Cuando usarla

Cuando quieras una animacion de un personaje en pixel-art (caminar, correr) lista
para un juego 2D, en un solo paso: das el prompt del personaje y recibes el sprite
sheet + el GIF/WEBP en loop. Es la promocion a pipeline (issue 0087) de la receta
del caso 1 del report 0217 — el camino correcto para sprites limpios de personaje
con alpha, frente a AnimateDiff o modelos de video (que ensucian el alpha y no
clavan la pose). Para una sola pose estatica usa `comfyui_pixelart_real_oneshot`;
para varias vistas direccionales (8-way) usa
`comfyui_build_directional_sprite_workflow`.

## Gotchas

- **Server vivo + GPU**: requiere ComfyUI en `server` con la GPU libre. El report
  recomienda `POST /free` antes de cargas pesadas de modelo. Cada frame reusa el
  mismo checkpoint, asi que el modelo solo se carga una vez.
- **Poses OpenPose**: en modo `openpose` los esqueletos se escriben en el `input/`
  del servidor (asume server local; para un server remoto haria falta subirlos con
  `POST /upload/image`). Si el ControlNet no produce variacion de piernas
  reconocible, usa `pose_method="prompt"`: a 32x32 el detalle de pose se simplifica
  y la fase del paso por prompt + seed fija da un walk reconocible.
- **Identidad**: la `seed` es FIJA para todos los frames — esa es la ancla de
  identidad. Cambiar la seed entre frames rompe la consistencia del personaje.
  `ref_image` (IPAdapter-FaceID) es una segunda ancla opcional; sobre un sprite de
  cuerpo entero pequeno aporta sobre todo paleta/ropa (ver report 0217).
- **No-throw, salta frames**: si un frame falla (red, GPU, build) se anade a
  `skipped` y la animacion se monta con los que queden. ok=False solo si NINGUN
  frame sale.
- **Loop suave**: con `frames=4` el ciclo (contact-L, passing, contact-R, passing)
  ya cierra el bucle — el frame siguiente al ultimo vuelve a la primera fase.
- **WEBP vs GIF**: `fmt="webp"` conserva alpha real (lossless); `fmt="gif"` solo
  tiene alpha binario (1 bit). Para sprites con transparencia, usa WEBP.

## Capability growth log

- v1.0.0 (2026-06-28) — version inicial. Caso 1 del report 0217 promovido a
  pipeline one-shot: walk cycle pixel-art con poses OpenPose (o fallback prompt),
  seed fija para identidad, Rembg para alpha, pixelizado a NxN RGBA, sprite sheet +
  WEBP/GIF en loop.
