---
name: comfyui_build_rune_glyph_workflow
kind: function
lang: py
domain: ml
version: "1.0.0"
purity: pure
signature: "def comfyui_build_rune_glyph_workflow(glyph: str, *, glow: bool = True, style: str = \"arcane glowing rune\", checkpoint: str = \"IMG_dreamshaper_8.safetensors\", size: int = 512, seed: int = 0, lora: str | None = None, lora_strength: float = 1.0, negative: str | None = None, steps: int = 28, cfg: float = 7.0, sampler_name: str = \"dpmpp_2m\", scheduler: str = \"karras\", filename_prefix: str = \"rune_glyph\") -> dict"
description: "Construye el dict (API format) del workflow de UNA runa / glifo / sigilo magico 2D: simbolo arcano aislado — glifos runicos, circulos magicos, sigilos de invocacion, inscripciones brillantes — para hechizos, portales, marcas de conjuro y efectos de magia. Se genera AISLADO sobre fondo uniforme; glow=True (defecto) lo pone BRILLANTE sobre NEGRO puro, pensado para extraer alpha por luminancia con comfyui_matting_luma_to_alpha (conserva el resplandor para blend aditivo en el motor). NO inyecta Rembg (el matting de una runa brillante es luma-to-alpha, no un nodo). Compone comfyui_build_txt2img_workflow + comfyui_inject_lora (estilo arcano opcional). Hermano de comfyui_build_status_effect_icon/decal_overlay_workflow. Pura, sin red ni I/O. class_types verificados contra /object_info."
tags: [comfyui, ml, gamedev-2d, rune, glyph, sigil, magic, arcane, glow, alpha, luma, workflow]
uses_functions: [comfyui_build_txt2img_workflow_py_ml, comfyui_inject_lora_py_ml]
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
params:
  - name: glyph
    desc: "Descripcion del simbolo arcano a generar (ej. 'circular summoning rune', 'ancient norse rune', 'magic circle with glyphs', 'demonic sigil', 'elven inscription', 'protective ward symbol', 'fire spell glyph'). Se inserta en un prompt scaffold de runa aislada. No puede estar vacio."
  - name: glow
    desc: "Si True (defecto) genera la runa BRILLANTE sobre fondo NEGRO puro, pensada para extraer alpha por luminancia con comfyui_matting_luma_to_alpha (conserva el resplandor: blend aditivo en el motor). False = runa MATE/grabada sobre fondo plano, sin resplandor (recorte/inversion por el caller). keyword-only."
  - name: style
    desc: "Descriptor de estilo arcano que mantiene consistentes las runas de un set (ej. 'arcane glowing rune', 'fiery demonic sigil', 'icy blue magic circle', 'golden holy glyph', 'engraved stone rune'). Pasa el MISMO style + checkpoint + lora a todas las runas de un grimorio para coherencia visual. keyword-only."
  - name: checkpoint
    desc: "Checkpoint del servidor. 'IMG_dreamshaper_8.safetensors' (SD1.5, holgado en 8GB lowvram) por defecto; 'IMG_juggernaut_xl_v11.safetensors' para SDXL (mas VRAM, subir size a 768/1024). keyword-only."
  - name: size
    desc: "Lado del cuadrado en px (width = height = size). 512 SD1.5 por defecto. keyword-only."
  - name: seed
    desc: "Semilla del KSampler. Misma seed + mismos glyph/style -> mismo simbolo; variar seed da variantes del mismo tipo de runa. keyword-only."
  - name: lora
    desc: "LoRA de estilo arcano opcional en models/loras. None = sin LoRA. keyword-only."
  - name: lora_strength
    desc: "Fuerza del LoRA sobre model y clip. Se clampa a [0.0, 2.0]. keyword-only."
  - name: negative
    desc: "Prompt negativo. None usa el negativo por defecto pensado para una runa aislada (un simbolo arcano centrado, sin escena/objeto/texto legible/marco, fondo plano). keyword-only."
  - name: steps
    desc: "Pasos del KSampler. keyword-only."
  - name: cfg
    desc: "CFG del KSampler. keyword-only."
  - name: sampler_name
    desc: "Sampler del KSampler. keyword-only."
  - name: scheduler
    desc: "Scheduler del KSampler. keyword-only."
  - name: filename_prefix
    desc: "Prefijo del PNG en output/. keyword-only."
output: "dict en API format listo para comfyui_submit_workflow: base txt2img cuadrada con prompt scaffold de runa ('{glyph}, {style}, magic symbol, single isolated glyph, centered, glowing on a solid pure black background | on a plain flat background, occult sigil, game asset, ...') + el negativo refuerza el aislamiento (rechaza escena/objeto/texto legible/marco; con glow=False rechaza el resplandor) + LoRA de estilo opcional. NO lleva Rembg: con glow=True el PNG resultante se convierte a RGBA con comfyui_matting_luma_to_alpha (luma=alpha) en un paso posterior. UNA runa; variar seed da variantes del mismo tipo."
file_path: python/functions/ml/comfyui_build_rune_glyph_workflow.py
tested: true
test_file_path: python/functions/ml/comfyui_build_rune_glyph_workflow_test.py
tests: [test_golden_rune_glow_on_black_recipe, test_edge_glow_toggles_background, test_edge_glyph_and_style_reflected, test_edge_seed_and_size_propagate, test_edge_lora_injected_when_requested, test_edge_lora_strength_clamped, test_error_empty_glyph_raises, test_purity_no_global_mutation]
---

Construye el dict (API format) del workflow de UNA runa / glifo / sigilo magico 2D: un
simbolo arcano aislado (glifos runicos, circulos magicos, sigilos de invocacion,
inscripciones brillantes) para hechizos, portales, marcas de conjuro y efectos de magia.
La pieza se genera AISLADA sobre un fondo uniforme para poder extraer luego el canal
alpha por luminancia. Es el builder hermano de `comfyui_build_status_effect_icon_workflow`
/ `comfyui_build_decal_overlay_workflow`: mismo patron PURO (dict API format) que compone
funciones existentes del registry sin reescribir el grafo.

## Ejemplo

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

# Una runa de invocacion brillante sobre fondo negro, lista para submit + luma-to-alpha.
wf = comfyui_build_rune_glyph_workflow(
    "circular summoning rune",
    glow=True,
    style="arcane glowing rune",
    seed=11,
)
# Pipeline completo de una runa con alpha:
#   r = comfyui_submit_workflow(wf); comfyui_wait_result(r["prompt_id"])
#   png = comfyui_fetch_output_image(...)            # runa brillante sobre negro
#   rgba = comfyui_matting_luma_to_alpha(png, gamma=1.2, black_point=0.05)  # luma=alpha
# Un grimorio coherente: mismo style/checkpoint/(lora), variando glyph y seed.
#   for g in ["fire spell glyph", "ice ward sigil", "lightning rune"]:
#       wf = comfyui_build_rune_glyph_workflow(g, style="arcane glowing rune")
```

O lanzable directo con: `./fn run comfyui_build_rune_glyph_workflow` (imprime nodos + class_types del ejemplo).

## Cuando usarla

Cuando necesites simbolos arcanos para magia: el circulo magico que aparece bajo un
invocador, el glifo de un hechizo elemental, el sigilo grabado en un portal, la
inscripcion brillante de un arma encantada, las runas de proteccion en el suelo. La runa
se genera aislada y, si brilla, se extrae su alpha por luminancia para componerla en el
motor con un blend aditivo (el resplandor "encaja" encima del fondo del juego).

Flujo tipico despues de generar:

1. `comfyui_build_rune_glyph_workflow("circular summoning rune", glow=True)` -> dict.
2. `comfyui_submit_workflow` -> `comfyui_wait_result` -> `comfyui_fetch_output_image`
   (PNG de la runa brillante sobre negro).
3. `comfyui_matting_luma_to_alpha(png, gamma=..., black_point=...)` -> PNG RGBA donde la
   luminancia ES el alpha: resplandor=opaco, negro=transparente. Listo para blend aditivo.

Pasa el MISMO `style` + `checkpoint` + (`lora`) a todas las runas de un grimorio para que
combinen; varia `seed` y `glyph` para sacar el set (varios sigilos del mismo estilo).

**Elige este builder y NO `comfyui_build_status_effect_icon_workflow` cuando** quieres una
marca arcana translucida que emite luz e se inscribe en el mundo (suelo, portal, arma),
cuyo alpha sale del resplandor. Un icono de estado es un simbolo SOLIDO de UI con silueta
recortable por rembg, pequeño y legible a 16-32 px en el HUD: cosa distinta.

## Gotchas

- **glow=True esta pensado para luma->alpha, no es adorno**: la runa se genera brillante
  sobre NEGRO puro precisamente para que `comfyui_matting_luma_to_alpha` mapee el
  resplandor a alpha y conserve el halo y el degradado. Si extraes el alpha con un matting
  binario (rembg) pierdes el glow y la runa queda con borde duro recortado. Para una runa
  MATE/grabada (sin resplandor, alpha por recorte) usa `glow=False`.
- **NO inyecta Rembg a proposito**: a diferencia de los builders de sprite/prop/item/icon,
  este NO lleva 'Image Rembg (Remove Background)'. El SaveImage toma directo del VAEDecode
  (runa sobre fondo uniforme) y el matting es un paso posterior de disco.
- **Es una funcion pura**: solo arma el dict. La generacion real (GPU) la hacen
  `comfyui_submit_workflow` + `comfyui_wait_result` + `comfyui_fetch_output_image`; el
  alpha lo hace `comfyui_matting_luma_to_alpha`.
- **El fondo debe quedar NEGRO plano (con glow=True)**: si el style "glowing/arcane" se
  derrama en una niebla/textura de fondo, el alpha por luminancia recogera basura. El
  positivo fuerza "solid pure black background, flat backdrop, bright lines on black" y el
  negativo rechaza fog/smoke clouds + fondo texturizado/de otro color. Si aun asi sale
  niebla de fondo, sube `cfg` o haz reroll de `seed`.
- **Una runa NO es texto legible**: el modelo tiende a escribir letras reales si el glyph
  suena a palabra. El negativo rechaza "realistic text, readable words, latin alphabet,
  sentence" para empujar a un glifo arcano abstracto. Si quieres letras concretas de un
  alfabeto rúnico real, descríbelo en el `glyph` y relaja el negativo.
- **luma->alpha y el color del glow**: la luminancia Rec601 pesa el rojo a 0.299, asi que
  una runa ROJA (sigilo demoniaco) sale mas transparente que una blanca/azul con los pesos
  por defecto. Para runas rojas pasa a `comfyui_matting_luma_to_alpha` unos `luma_weights`
  con mas peso al rojo y sube `gamma`. Para runas blancas/doradas/azules (la mayoria de
  magia brillante) los pesos por defecto van perfectos.
- **SDXL pide mas VRAM y resolucion**: con `checkpoint="IMG_juggernaut_xl_v11.safetensors"`
  sube `size` a 768/1024; con IMG_dreamshaper_8 (SD1.5) deja 512 (holgado en 8GB lowvram). Si
  hay OOM, baja `size` o usa SD1.5.
