docs(capabilities): unifica tag gamedev en gamedev-2d + separa gamedev-engine

El doctor reportaba el dominio gamedev en doble FAIL: el tag plano `gamedev`
(44 funciones) como `ungrouped_candidate` y la pagina `gamedev-2d.md` como
`doc_orphan`. Causa raiz: el INDEX declaraba `[gamedev](gamedev-2d.md)` y el
auditor solo registra el slug cuando label==target, asi que ni casaba la
pagina ni declaraba el tag.

Al revisar las 44 funciones habia dos clusters reales bajo el mismo tag, asi
que se separan en dos grupos honestos:

- gamedev-2d (tag canonico): 31 builders de workflow ComfyUI + 5 de apoyo
  (post-proceso + puente a Godot) = 36. Se elimina el tag plano `gamedev` de
  los builders (ya tenian `gamedev-2d`) y se reemplaza por `gamedev-2d` en las
  de apoyo.
- gamedev-engine (grupo nuevo, pagina madre nueva): runtime de juego C++
  multiplataforma (SDL3 + sokol_gfx + miniaudio, Issue 0072b) = 8. Game loop,
  camara 2D, input unificado, sprite batch, setup render/audio, build wasm.

El tag plano `gamedev` queda eliminado (count 0). INDEX corregido: fila
gamedev-2d con label==target y conteo 36 + fila nueva gamedev-engine (8).

Verificacion: `fn index` + `fn doctor capabilities` -> ambos grupos OK
(declared_in_index=yes, doc_exists=yes, sin issues); `gamedev` plano = 0.
Solo se modifico el campo `tags` de los .md, ningun archivo de codigo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-27 02:40:50 +02:00
parent 8a4cc323a3
commit a27dcc028c
47 changed files with 136 additions and 50 deletions
+2 -1
View File
@@ -14,7 +14,8 @@ Indice de grupos de capacidades del registry. Cada grupo agrupa >=3 funciones qu
| Grupo | N | Que cubre |
|---|---|---|
| [gamedev](gamedev-2d.md) | 20 | Assets 2D para Godot: 15 builders de workflow ComfyUI (pixelart/seamless/iso/sprite/topdown/card/enemy/prop/VFX..., tag `gamedev-2d`) + 5 de apoyo: post-proceso (pixelize, luma->alpha) + puente de assets a Godot 4 (.import + reimport headless) |
| [gamedev-2d](gamedev-2d.md) | 36 | Assets 2D para Godot via ComfyUI: 31 builders de workflow (pixelart/seamless/iso/sprite/topdown/card/enemy/prop/structure/foliage/trap/projectile/decal/particle/rune/weather/badge/skill-tree/dialogue/icon/portrait/VFX...) + 5 de apoyo: post-proceso (pixelize, luma->alpha) + puente de assets a Godot 4 (.import + reimport headless). Tag canonico `gamedev-2d` (antes `gamedev`, ya unificado) |
| [gamedev-engine](gamedev-engine.md) | 8 | Runtime de juego C++ multiplataforma (PC + WebAssembly): SDL3 + sokol_gfx + miniaudio. Game loop fixed-timestep, camara 2D, input unificado (teclado/gamepad/touch), sprite batch, setup de render/audio y build a wasm. Grupo hermano de `gamedev-2d` (este ejecuta el juego, aquel genera los assets) |
| [registry](registry.md) | 17 | Auditoria y monitorizacion del propio registry: copied-code, uses-functions, unused, proposals, telemetria |
| [systemd](systemd.md) | 14 | Generar, instalar, restart y status de unit files systemd via SSH (deploys a VPS) |
| [ssh](ssh.md) | 19 | Operar hosts remotos via SSH: config, conn, ejecutar comandos, port-forward, deploys con SCP/rsync |
+8 -5
View File
@@ -1,4 +1,4 @@
# Capability group: `gamedev` / `gamedev-2d` — assets 2D para Godot (generación + post-proceso + puente)
# Capability group: `gamedev-2d` — assets 2D para Godot (generación + post-proceso + puente)
Cluster de funciones para producir y mover assets 2D de juego entre **ComfyUI**
(generación) y **Godot 4** (consumo). Tres capas:
@@ -7,11 +7,14 @@ Cluster de funciones para producir y mover assets 2D de juego entre **ComfyUI**
de los workflows ComfyUI para pixel-art, tiles seamless, isométrico, sprites de
personaje y VFX en bucle. Son **puros** (no tocan GPU al construir); el coste GPU
está al enviar con `comfyui_submit_workflow`.
2. **Post-proceso determinista** (`gamedev`, CPU): pixelizar, recortar a alpha.
3. **Puente de assets** (`gamedev`, CPU): coloca el resultado en un proyecto Godot
2. **Post-proceso determinista** (CPU): pixelizar, recortar a alpha.
3. **Puente de assets** (CPU): coloca el resultado en un proyecto Godot
con sus import settings.
Tags: `gamedev` (post-proceso + puente) y `gamedev-2d` (builders de workflow).
Tag único del grupo: `gamedev-2d` (los 31 builders de workflow + las 5 funciones de
apoyo de post-proceso y puente). El tag plano `gamedev` quedó deprecado y unificado a
`gamedev-2d`. El **runtime de juego C++** (el motor que ejecuta el juego: game loop,
cámara, input, render por lotes, audio) vive en el grupo hermano `gamedev-engine`.
Filtro: `mcp__registry__fn_search query="" tag="gamedev-2d"`.
Documento hermano del grupo `comfyui` (generación genérica de imágenes/video/3D).
@@ -62,7 +65,7 @@ VFX (ver `reports/0143`).
| `comfyui_build_rune_glyph_workflow_py_ml` | `(glyph, *, glow=True, style="arcane glowing rune", checkpoint="dreamshaper_8…", size=512, seed=0, lora=None, …) -> dict` | UNA **runa / glifo / sigilo mágico** (glifos rúnicos, círculos mágicos, sigilos de invocación, inscripciones brillantes) para hechizos, portales, marcas de conjuro y efectos de magia: símbolo arcano **aislado** sobre fondo uniforme (`{glyph}, {style}, magic symbol, single isolated glyph, centered, glowing on a solid pure black background, occult sigil, arcane inscription, no scenery, game asset…`) → txt2img cuadrado + LoRA estilo opcional. **`glow` elige el camino a alpha**: `glow=True` (defecto) = runa BRILLANTE sobre **NEGRO puro**, **sin Rembg** (recortaría el halo del resplandor), insumo de **`comfyui_matting_luma_to_alpha`** (luma=alpha, **blend aditivo** en el motor — conserva el glow); `glow=False` = runa MATE/grabada sobre fondo plano (el negativo rechaza `glow/neon/bloom`), recorte/inversión por el caller. El negativo rechaza `realistic text/readable words/latin alphabet` (un glifo arcano, **no letras reales**) + fondo texturizado/niebla. **DISTINTO de `status_effect_icon`** (símbolo SÓLIDO de UI, recorte Rembg, legible a 16-32 px en el HUD): la runa es una marca translúcida que **emite luz** e se inscribe en el mundo. Grimorio coherente = mismo `style`/`checkpoint`/`lora`, varía `glyph`/`seed`. ⚠️ luma Rec601 penaliza el rojo → para runas rojas (sigilo demoníaco) pasar `luma_weights` con más peso al rojo + subir `gamma`; runas blancas/azules/doradas van con pesos por defecto. Probado e2e en GPU con SD1.5 — `circular summoning rune` glow seed 11 512×512, círculo de invocación brillante sobre **negro puro** (esquinas luma 0.00, dark 83%, runa 3.4% brillante, max 255) apto luma→alpha (`prompt_id 701d149a`, `reports/0172`). SD1.5. |
| `comfyui_build_title_lettering_workflow_py_ml` | `(text, *, letter_style="epic fantasy metallic", checkpoint="juggernaut_xl_v11…", width=1024, height=512, transparent=True, seed=0, lora=None, …) -> dict` | EL texto/logo de **título** de un juego (el nombre del juego o una palabra) renderizado con un **tratamiento de lettering** (metálico, tallado en fuego/piedra/madera, neón, cristal, oro), formato **apaisado** (`width>height`, 1024×512 por defecto), fondo plano recortable a alpha (`the word "{text}" as a game logo, {letter_style} lettering, stylized typography, centered, plain background…`) → txt2img apaisado + LoRA estilo opcional + Rembg (alpha). El **negativo NO rechaza texto** (el lettering es el sujeto) y empuja contra el ruido textual (`extra letters/jumbled text/deformed letters`). El VALOR es el ESTILO del lettering, **NO** la fidelidad tipográfica: ⚠️ la difusión renderiza texto de forma imperfecta — letras de más, deformadas o mal escritas; mitigar con palabras CORTAS en MAYÚSCULA, **re-roll de seeds** (`comfyui_batch_generate`), SDXL > SD1.5 para texto, o pintar el texto real con una fuente en el motor. **Una palabra que es un objeto concreto (DRAGON) → el modelo dibuja el objeto, no las letras** — usar palabras abstractas o reforzar `letter_style`. Marca coherente = mismo `letter_style`/`checkpoint`/`lora`, varía solo `text`. Recorte por **Rembg** (logo sólido), no luma→alpha. Probado e2e en GPU: `DRAGON`/`fire engraved` SD1.5 1024×512 → ilustró dragones rojos (alpha OK, confirma el gotcha de palabra-objeto, `prompt_id 6f3920b7`); `AETHER`/`epic fantasy metallic` SDXL 768×384 → **logo de texto metálico dorado** legible con ortografía imperfecta + alpha (`prompt_id 2a7fe8ba`, `reports/0165`). SD1.5/SDXL. |
## Funciones de post-proceso y puente (`gamedev`, CPU)
## Funciones de post-proceso y puente (`gamedev-2d`, CPU)
| ID | Firma corta | Qué hace |
|---|---|---|
+82
View File
@@ -0,0 +1,82 @@
# Capability group: `gamedev-engine` — runtime de juego C++ multiplataforma (PC + WebAssembly)
Cluster de primitivas C++ que forman el núcleo de un runtime de juego 2D portable a
escritorio (Windows/Linux/macOS) y navegador (WebAssembly via emscripten). Stack:
**SDL3** (ventana + input + GL context) + **sokol_gfx** (render) + **miniaudio**
(audio). Nacido del Issue 0072b.
A diferencia del grupo hermano `gamedev-2d` (generación de *assets* 2D con ComfyUI y
puente a Godot), este grupo es el **motor que ejecuta el juego**: el bucle de
simulación, la cámara, el input, el render por lotes y el audio. No genera arte; lo
consume en tiempo de ejecución.
Tag: `gamedev-engine`. Filtro: `mcp__registry__fn_search query="" tag="gamedev-engine"`.
## Funciones del grupo
| ID | Firma corta | Qué hace | Pureza |
|---|---|---|---|
| `game_loop_cpp_gamedev` | `loop_run(SDL_Window*, const LoopCfg&) -> void` | Game loop fixed-timestep estilo Glenn Fiedler ("Fix Your Timestep"): desacopla `on_fixed_update` (dt fijo) de `on_render` (factor de interpolación), acumulador con cap anti spiral-of-death. Branch automático desktop (while loop) vs `__EMSCRIPTEN__` (`emscripten_set_main_loop`). | impure |
| `input_unified_cpp_gamedev` | `input_begin_frame(InputState&); input_process_event(InputState&, const SDL_Event*)` | Snapshot unificado de input por frame para SDL3: mapea teclado (WASD+flechas), ratón, gamepad y touch a botones lógicos (left/right/up/down/action_a..y/start/back) y ejes analógicos, con flags `*_pressed` de rising edge limpio. | impure |
| `camera_2d_cpp_gamedev` | `world_to_screen / screen_to_world(Camera2D, Vec2) -> Vec2; visible_world_rect(Camera2D) -> Rect; view_proj_matrix(Camera2D, float[16])` | Cámara ortográfica 2D pura (pos centro, zoom, rotación, viewport): conversiones world↔screen, AABB visible y matriz view-projection 4×4 column-major lista para cualquier renderer. Fast-path sin trig si `rotation==0`. | pure |
| `sokol_setup_cpp_gfx` | `make_environment() -> sg_environment; make_swapchain(int w, int h) -> sg_swapchain` | Builders puros para inicializar sokol_gfx sobre un GL context creado por SDL3 (no por sokol_app): `sg_environment` con defaults RGBA8 + depth/stencil y `sg_swapchain` del default framebuffer del contexto activo. | pure |
| `sprite_batch_cpp_gfx` | `sprite_batch_create(int cap=4096) -> SpriteBatch; sprite_batch_begin/draw/end` | Batched textured quad renderer sobre sokol_gfx: begin/draw/end con auto-flush por cambio de atlas o capacidad llena. Vertex layout pos+uv+color, alpha blending estándar, GLSL 330 / GLES 300. Base de plataformeros, top-down y UI sprites. | impure |
| `audio_engine_cpp_gamedev` | `engine_init() -> Engine; engine_shutdown(Engine&); engine_set_volume(Engine&, float)` | Lifecycle del engine de audio basado en miniaudio (single-header, public domain): inicializa device default, master volume, libera recursos. Cross-platform (WASAPI/ALSA/CoreAudio y WebAudio bajo emscripten). Única TU que define `MINIAUDIO_IMPLEMENTATION`. | impure |
| `audio_play_cpp_gamedev` | `sound_load(Engine&, const char*) -> Sound; sound_play/stop/set_volume/destroy(Sound&); play_sound_oneshot(Engine&, const char*, float)` | Reproducción de audio sobre `fn::audio::Engine`: carga con streaming desde disco (wav/mp3/flac/ogg), play/stop/volumen por sonido, y helper fire-and-forget para one-shots sin handle. | impure |
| `build_wasm_cpp_app_bash_infra` | `build_wasm_cpp_app(app_name, [--no-budget-check]) -> void` | Compila una app C++ del registry (`cpp/apps/<name>`) a WebAssembly via emscripten. Produce `build/wasm/<name>/<name>.{html,js,wasm,wasm.gz}`. Falla si el gzip supera 2 MB (budget). | impure |
## Ejemplo canónico (esqueleto de un juego 2D)
Las primitivas se componen así dentro del `main()` de una app C++ del registry. Cada
identificador (`fn::game_loop`, `fn::input`, `fn::camera2d`, `fn::gfx`, `fn::audio`)
proviene de la función homónima del registry; la app solo aporta la lógica de juego.
```cpp
// 1. Ventana + GL context con SDL3, sokol_gfx encima (sokol_setup)
sg_setup(...); // usa make_environment() del registry
auto swap = fn::gfx::make_swapchain(W, H);
auto batch = fn::gfx::sprite_batch_create(4096);
auto audio = fn::audio::engine_init();
fn::audio::play_sound_oneshot(audio, "assets/music.ogg", 0.6f);
// 2. Estado de cámara e input
fn::game::Camera2D cam{ .pos = {0,0}, .zoom = 1.0f, .viewport = {W, H} };
fn::input::InputState in{};
// 3. Game loop fixed-timestep: simulación e interpolación desacopladas
fn::game::LoopCfg cfg{
.on_event = [&](const SDL_Event* e){ fn::input::input_process_event(in, e); },
.on_fixed_update = [&](float dt){ /* mover entidades usando in.left_pressed... */ },
.on_render = [&](float alpha){
fn::gfx::sprite_batch_begin(batch);
// draw sprites con cam.view_proj_matrix(...) como transform
fn::gfx::sprite_batch_end(batch);
},
};
fn::game::loop_run(window, cfg);
// 4. Distribuir a navegador: build_wasm_cpp_app "<app>" -> build/wasm/<app>/
```
## Fronteras (qué NO cubre)
- **Generación de assets** (sprites, tiles, VFX): es el grupo hermano `gamedev-2d`
(ComfyUI → post-proceso → Godot). Este grupo solo los *renderiza* en runtime.
- **Física / colisiones / ECS**: no incluidos. El `on_fixed_update` recibe el dt fijo;
la simulación la pone la app.
- **TileSet / mapas / escenas**: no hay sistema de niveles; `sprite_batch` dibuja quads
sueltos.
- **App end-to-end consumidora**: a fecha de hoy estas primitivas son el núcleo del
runtime (Issue 0072b) pero **no hay todavía una app C++ que las componga end-to-end**
(varias están marcadas `pendiente-usar`). El ejemplo de arriba es el esqueleto
previsto, no un binario validado. Cuando exista la primera app, su `app.md`
declarará estas IDs en `uses_functions` y servirá de validación e2e.
## Prerequisitos / notas
- **SDL3** para ventana + input + GL context; **sokol_gfx** (vendored en `cpp/vendor/`)
para render; **miniaudio** (single-header) para audio.
- Target nativo: GLSL 330. Target WebAssembly (emscripten): GLES 300 — `sprite_batch`
emite ambos shaders.
- `build_wasm_cpp_app` exige el SDK de emscripten en el entorno y respeta un budget de
2 MB gzip por defecto (`--no-budget-check` para saltarlo).