---
name: comfyui_build_world_map_workflow
kind: function
lang: py
domain: ml
version: "1.0.0"
purity: pure
signature: "def comfyui_build_world_map_workflow(region: str, *, map_style: str = \"fantasy cartography, aged parchment\", checkpoint: str = \"IMG_juggernaut_xl_v11.safetensors\", width: int = 768, height: int = 768, hires: bool = False, 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\", upscale_by: float = 1.5, hires_denoise: float = 0.4, upscale_model: str = \"4x_foolhardy_Remacri.pth\", filename_prefix: str = \"world_map\") -> dict"
description: "Construye el dict (API format) del workflow de UN mapa de mundo / mapa de nivel ilustrado 2D: lamina cartografica estilo fantasy (continente, region, mazmorra, reino) en vista cenital, con marcas/regiones rotuladas y borde ornamental, para la pantalla de mapa del juego. Genera SOLO la ilustracion (las marcas interactivas, los iconos pinchables y el texto fiable los pone el motor). Cuadrado por defecto (768x768), hires opcional. Compone comfyui_build_hires_fix_workflow (si hires) o comfyui_build_txt2img_workflow + comfyui_inject_lora (estilo opcional). Hermano de comfyui_build_splash_art/parallax_background_workflow. Pura, sin red ni I/O. class_types verificados contra /object_info (8GB lowvram)."
tags: [comfyui, ml, gamedev-2d, world-map, level-map, cartography, illustration, workflow]
uses_functions: [comfyui_build_txt2img_workflow_py_ml, comfyui_build_hires_fix_workflow_py_ml, comfyui_inject_lora_py_ml]
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
params:
  - name: region
    desc: "Descripcion de la region a cartografiar (ej. 'a fantasy kingdom with mountains, forests and a coastline', 'a dark dungeon with branching corridors', 'a desert continent with an oasis and ruins'). Se inserta en un prompt scaffold de mapa cartografico cenital. No puede estar vacio."
  - name: map_style
    desc: "Tratamiento cartografico que define el look del mapa (ej. 'fantasy cartography, aged parchment', 'hand-drawn ink map', 'old nautical chart', 'painted region map, vibrant'). Pasa el MISMO map_style + checkpoint + lora a varios mapas para coherencia visual del juego. keyword-only."
  - name: checkpoint
    desc: "Checkpoint del servidor. 'IMG_juggernaut_xl_v11.safetensors' (SDXL, mejor detalle de costa/relieve/ornamento) por defecto; en 8GB lowvram con hires puede ser pesado: usa 'IMG_dreamshaper_8.safetensors' (SD1.5) y/o hires=False si la GPU se queda corta (OOM). keyword-only."
  - name: width
    desc: "Ancho del lienzo en px. 768 por defecto (cuadrado). Para un mundo apaisado (banda continental ancha) sube width. keyword-only."
  - name: height
    desc: "Alto del lienzo en px. 768 por defecto (cuadrado). Para un mapa en columna (torre/mazmorra vertical) sube height. keyword-only."
  - name: hires
    desc: "Si True encadena la 2a pasada de detalle (UltimateSDUpscale + Remacri, re-difusion por tiles) sobre la base (costas/montañas/ornamento mas finos). False (defecto) deja la imagen tal cual sale del VAEDecode: mas rapido para iterar. keyword-only."
  - name: seed
    desc: "Semilla del KSampler (y de la pasada hires). Misma seed + misma region -> mismo mapa. keyword-only."
  - name: lora
    desc: "LoRA de estilo opcional en models/loras (ej. 'SD15_cartography.safetensors', 'SDXL_old_map.safetensors'). None = sin LoRA. Encadena la identidad visual del mapa del juego. 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 lamina cartografica (vista cenital plana, sin perspectiva 3D / foto / personaje en primer plano). keyword-only."
  - name: steps
    desc: "Pasos del KSampler (y de la pasada hires). keyword-only."
  - name: cfg
    desc: "CFG del KSampler (y de la pasada hires). keyword-only."
  - name: sampler_name
    desc: "Sampler del KSampler. keyword-only."
  - name: scheduler
    desc: "Scheduler del KSampler. keyword-only."
  - name: upscale_by
    desc: "Factor de ampliacion de la pasada hires sobre la base (1.5 -> 768x768 pasa a 1152x1152). Solo si hires=True. keyword-only."
  - name: hires_denoise
    desc: "Fuerza de re-difusion de la pasada hires (0.4 por defecto: anade detalle sin alterar el trazado del mapa). Solo si hires=True. keyword-only."
  - name: upscale_model
    desc: "Modelo de upscale en models/upscale_models/ que usa la pasada hires ('4x_foolhardy_Remacri.pth'). Solo si hires=True. keyword-only."
  - name: filename_prefix
    desc: "Prefijo del PNG en output/. keyword-only."
output: "dict en API format listo para comfyui_submit_workflow: base (hires-fix si hires, txt2img si no) con prompt scaffold de mapa ('map of {region}, {map_style}, top-down cartographic view, illustrated game world map, labeled regions, decorative border, ...') + LoRA de estilo opcional. UNA lamina; atlas coherente -> llamar por region con mismo map_style/checkpoint/lora. Las marcas interactivas, los iconos pinchables y el texto fiable los pone el motor, no este workflow."
tested: true
tests: ["golden plain: clases CheckpointLoaderSimple/KSampler/VAEDecode/SaveImage; region + 'fantasy cartography, aged parchment' + 'top-down cartographic view' + 'illustrated game world map' + 'labeled regions' + 'decorative border' en prompt; base cuadrada 768x768; sin UltimateSDUpscale (hires=False default); SaveImage <- VAEDecode", "edge hires=True: encadena UltimateSDUpscale/UpscaleModelLoader con upscale_by reflejado; UltimateSDUpscale.batch_size=1", "edge dims: width=1024/height=576 reflejados (mundo apaisado)", "edge map_style en prompt", "edge lora: LoraLoader con strength, KSampler.model <- LoraLoader", "edge lora_strength clamp a [0,2]", "error region vacio -> ValueError", "determinismo"]
test_file_path: "python/functions/ml/comfyui_build_world_map_workflow_test.py"
file_path: "python/functions/ml/comfyui_build_world_map_workflow.py"
---

## Ejemplo

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

# Mapa de mundo ilustrado de un reino fantasy en vista cenital cartografica.
# En 8GB lowvram va holgado con SD1.5 (IMG_dreamshaper_8) sin hires; SDXL+hires es mas pesado (puede OOM).
wf = comfyui_build_world_map_workflow(
    "a fantasy kingdom with mountains, forests and a coastline",
    map_style="fantasy cartography, aged parchment",
    checkpoint="IMG_dreamshaper_8.safetensors",
    hires=False,
    seed=7,
)
# Atlas coherente: mismo map_style/checkpoint para varios mapas del juego, varia solo region.
#   for r in ["the northern ice provinces", "the central trade kingdoms", "the southern jungles"]:
#       wf = comfyui_build_world_map_workflow(r, map_style="fantasy cartography, aged parchment",
#                                             checkpoint="IMG_dreamshaper_8.safetensors", seed=7)
#       comfyui_submit_workflow(wf)  # -> comfyui_wait_result -> comfyui_fetch_output_image
# Las marcas interactivas, los iconos pinchables y el "estas aqui" los compone el motor sobre la lamina.
```

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

## Cuando usarla

Cuando necesites la ILUSTRACION de la pantalla de mapa del juego: una lamina
cartografica cenital de un continente, una region, un reino o una mazmorra, con el
aspecto de un atlas/pergamino fantasy (regiones rotuladas, borde ornamental, rosa de
los vientos). Pasa el MISMO `map_style` + `checkpoint` + (`lora`) a todos los mapas del
juego para que combinen visualmente; varia solo `region`. Deja `hires=False` para
iterar rapido y ponlo a `True` para una lamina con detalle fino de costas y relieve.
Las marcas de ubicacion interactivas, los iconos pinchables, las rutas y el texto
fiable los pone el motor de juego SOBRE la ilustracion — este builder NO los pinta.

## Gotchas

- **Genera SOLO la ilustracion del mapa, no marcas interactivas ni texto fiable**: la
  difusion dibuja marcas/etiquetas DECORATIVAS (parte del look cartografico) pero NO
  garantiza ni la ortografia ni posiciones usables como datos. Los puntos de interes
  pinchables, las rutas dinamicas y el "estas aqui" los compone el motor sobre la
  lamina. Si quieres labels nitidos, mejor que los ponga el motor.
- **Vista cenital plana, no perspectiva 3D**: el negativo por defecto rechaza "photo /
  3d render / realistic perspective / vanishing point / first person / character /
  person" para mantener la lamina cartografica. Si pasas un `negative` propio sin esos
  terminos puedes acabar con una escena 3D en vez de un mapa.
- **Cuadrado por defecto (768x768)**: una pantalla de mapa suele encuadrar la region
  completa. Para un mundo apaisado (banda continental ancha) sube `width`; para un mapa
  en columna (torre/mazmorra vertical) sube `height`.
- **SDXL + hires es pesado en 8GB lowvram**: el default `IMG_juggernaut_xl_v11` con
  `hires=True` re-difunde por tiles y puede dar OOM o ir muy lento. Si la GPU se queda
  corta: baja a `checkpoint="IMG_dreamshaper_8.safetensors"` (SD1.5), deja `hires=False`, o
  reduce `width/height`. Probado e2e en GPU con SD1.5 sin hires (ver report 0166).
- **hires requiere UltimateSDUpscale + Remacri**: si el server responde HTTP 400 "node
  type not found: UltimateSDUpscale", falta el custom node; usa `hires=False`. El
  `upscale_model` ('4x_foolhardy_Remacri.pth') debe existir en `models/upscale_models/`.
- **Coherencia del atlas = mismos parametros**: si cambias `map_style`/`checkpoint`/
  `lora`/`seed` entre mapas, dejan de combinar. Fija esos y varia solo `region`.
- Es una funcion **pura**: solo arma el dict. La generacion real (GPU) la hacen
  `comfyui_submit_workflow` + `comfyui_wait_result` + `comfyui_fetch_output_image`.
