---
name: comfyui_apply_style_preset
kind: function
lang: py
domain: ml
version: "1.0.0"
purity: pure
signature: "def comfyui_apply_style_preset(preset: dict, subject: str, *, style: str | None = None, negative: str | None = None) -> dict"
description: "Traduce un STYLE PRESET gamedev (de comfyui_get_gamedev_style_preset) + un subject del usuario a lo que necesita un builder de sujeto del grupo gamedev-2d: el subject combinado con el prefijo/sufijo del estilo, los kwargs comunes (style, checkpoint, lora, lora_strength, negative) listos para **spread, la resolucion y el recorte recomendados (size, transparent) y la spec de post-proceso (post, p.ej. pixelize) que el caller aplica al PNG. Asi el mismo estilo se aplica a CUALQUIER builder (item_icon, enemy_creature, prop_object, ...) y al pipeline comfyui_generate_asset_pack_oneshot sin acoplar firmas. Pura, sin red ni I/O; no muta el preset."
tags: [comfyui, ml, gamedev-2d, style, preset, theme]
uses_functions: [comfyui_get_gamedev_style_preset_py_ml]
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
params:
  - name: preset
    desc: "Receta de estilo (dict de comfyui_get_gamedev_style_preset). Debe traer los campos del preset (se valida que esten). No se muta."
  - name: subject
    desc: "Lo que el usuario quiere generar (ej. 'knight character', 'health potion'). Se combina con el prefijo/sufijo del estilo. No puede estar vacio."
  - name: style
    desc: "Override puntual: si se pasa, sustituye al style del preset. None usa el del preset. keyword-only."
  - name: negative
    desc: "Negativo extra del caller; se MERGEA (sin duplicar) con el negativo del estilo, no lo reemplaza. None = solo el del estilo. keyword-only."
output: "dict con: name (estilo aplicado), subject (combinado con prefijo/sufijo), builder_kwargs ({style, checkpoint, lora, lora_strength, negative} para **spread en el builder), size (resolucion recomendada), transparent (recorte recomendado), post (post-proceso CPU: {'pixelize': {...}} o {})."
tested: true
tests: ["golden gameboy: subject combina suffix (8-bit), builder_kwargs con las 5 claves comunes, checkpoint dreamshaper, lora None, post pixelize paleta game-boy", "golden contrato: los builder_kwargs hacen **spread en comfyui_build_item_icon_workflow sin TypeError y el LoRA del preset aparece en el grafo", "edge style override sustituye el del preset", "edge negative se mergea con el del estilo (no se pierde photorealistic) y deduplica", "edge no muta el preset de entrada", "error subject vacio -> ValueError", "error preset incompleto -> ValueError"]
test_file_path: "python/functions/ml/comfyui_apply_style_preset_test.py"
file_path: "python/functions/ml/comfyui_apply_style_preset.py"
---

## Ejemplo

```python
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_get_gamedev_style_preset import comfyui_get_gamedev_style_preset
from ml.comfyui_apply_style_preset import comfyui_apply_style_preset
from ml.comfyui_build_enemy_creature_workflow import comfyui_build_enemy_creature_workflow

# 1. Elegir estilo + aplicarlo a un subject
preset = comfyui_get_gamedev_style_preset("gameboy")
ap = comfyui_apply_style_preset(preset, "knight character")

# 2. Construir el workflow con cualquier builder de sujeto (kwargs por **spread)
wf = comfyui_build_enemy_creature_workflow(
    ap["subject"], size=ap["size"], transparent=ap["transparent"], **ap["builder_kwargs"]
)
# 3. Generar (submit/wait/fetch) y, si el estilo lo pide, post-proceso:
#   if ap["post"].get("pixelize"):
#       comfyui_pixelize_image(raw_png, dst_png, **ap["post"]["pixelize"])
```

O lanzable directo con: `./fn run comfyui_apply_style_preset` (aplica pixel-art-retro a "knight character").

## Cuando usarla

Justo despues de elegir un estilo con `comfyui_get_gamedev_style_preset`, para convertir
esa receta en los argumentos exactos de un builder. Es el puente entre "que estilo quiero"
y "como lo paso a item_icon/enemy_creature/prop_object/...". El mismo `ap` sirve para
generar N assets distintos en el MISMO estilo (varia solo el `subject`). Para overrides
puntuales sin tocar el preset, usa `style=`/`negative=`.

## Gotchas

- Devuelve `builder_kwargs` con EXACTAMENTE las 5 claves comunes a los builders de SUJETO
  (`style`, `checkpoint`, `lora`, `lora_strength`, `negative`). Builders que NO las acepten
  todas (p.ej. `seamless_tile`, `parallax_background` no tienen `transparent`/`lora` igual)
  exigen filtrar las claves; este helper esta pensado para los builders de sujeto cuadrado.
- `size` y `transparent` van FUERA de `builder_kwargs` (son recomendaciones del estilo): el
  caller los pasa explicitos o decide otros. `transparent=False` en los presets de demo es
  para que el look (paleta/pintura) cubra todo el frame; para un sprite con alpha pon
  `transparent=True` (el recorte es ortogonal al estilo).
- El `post` NO se aplica solo: el caller debe llamar `comfyui_pixelize_image(raw, dst,
  **ap["post"]["pixelize"])` tras descargar el PNG si `ap["post"].get("pixelize")`. Sin eso,
  estilos como gameboy/pixel-art-retro no sellan su grid/paleta.
- Es **pura**: no llama a ningun builder ni toca la GPU; solo arma kwargs. No muta el
  `preset` de entrada (lo que devuelve es independiente).

## Capability growth log

(v1.0.0 — sin cambios todavia.)
