feat(gamedev): sistema de style presets reutilizable (gameboy/ghibli/pixel-art-retro)
Calidad por ESTILO en vez de por tipo: un dev fija el look del juego una vez y todos los assets salen coherentes. Diseño (A) datos puros + helper, no pipeline monolítico (issue 0087, crecer por composición). - comfyui_get_gamedev_style_preset(name=None): recetas curadas o catálogo. gameboy (sin LoRA, post pixelize paleta game-boy 4 tonos), ghibli (degrada a watercolor_style_sd15 gratis instalado, sin LoRA Ghibli gated), pixel-art-retro (reutiliza pixel-art-xl SDXL + juggernaut + post pixelize 16 colores). Extensible. - comfyui_apply_style_preset(preset, subject): traduce a kwargs **spread-ables para cualquier builder de sujeto + size/transparent/post. Pura, no muta. - 16 tests offline verdes. Validado e2e GPU: mismo 'knight character' en 3 estilos visiblemente distintos (4 vs 78552 vs 16 colores). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
---
|
||||
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.)
|
||||
Reference in New Issue
Block a user