Releases: MauricioPerera/game-protocol
Release list
v2.18.0 - pagina del protocolo (ES/EN/PT) + auditoria de datos
[2.18.0] — 2026-07-09
Release aditivo sobre 2.17.0 (bump minor, SPEC §7.0): la página del
protocolo en GitHub Pages con soporte ES/EN/PT, y una auditoría de datos que corrige 4
inconsistencias documentales (conteo de perfiles en demos.html/CONTRIBUTING.md,
perfiles faltantes en llms.txt, hints faltantes en tools/rule-hints.js) y agrega un
test que gatea la cobertura de hints a futuro. La versión del protocolo sigue en 0.1.
Added — página del protocolo (GitHub Pages) + soporte ES/EN/PT
index.htmlpasa de "listado de demos" a landing explicativa: el problema (datos
mezclados con lógica), la idea (un archivo, dos lectores — front-matter + doc), el
pipeline real (lint→export→ consumir, con el fallback embebido), un snippet real
demonster-rpg, los 14 perfiles con badge para los puro-datos, y 4 razones concretas
de por qué importa. Publicada en GitHub Pages: https://mauricioperera.github.io/game-protocol/- El listado de demos existente se preserva intacto en
demos.html(mismo contenido,
mismas rutas relativas), ahora linkeado desde el nav/footer de la nueva home. - Soporte multi-idioma (ES/EN/PT) en ambas páginas: selector en el nav, detección por
navigator.language(fallback ES) persistida enlocalStoragebajo la clave
compartidagp-lang— el idioma elegido se mantiene al navegar entreindex.htmly
demos.html. 71 claves traducidas enindex.html, 24 endemos.html; el código real
deGAME.md(tokens del protocolo) no se toca, solo la prosa explicativa. - README actualizado con los links a la página y a los demos.
Fixed — auditoría de datos del protocolo
demos.htmldecía "9 perfiles de referencia desde la spec" en los 3 idiomas
mientrasindex.html(mismo sitio) dice correctamente "14 perfiles" — corregido.llms.txtlistaba 12 de los 14 perfiles reales — se agregansudokuy
peg-solitaire(ambos puro-datos, comoquiz/shooter).tools/rule-hints.jsle faltaban 23 hints de reglas reales (verificado contra
test/conformance.js): papers-please, crafting, platformer, voxel y la familia
grids(scene-rowsentre otras) quedan cubiertas. Nuevo test en
conformance.jsgatea que todo rule-id real tenga hint, para que el gap no
vuelva a aparecer en silencio. De paso, 5 hints ya existentes que estaban mal
etiquetados bajo el comentario "roguelike" quedan reordenados a su sección real.CONTRIBUTING.mddecía quetest/buildGame-content.jscubre "9 perfiles" —
corregido a los 14 reales.CHANGELOG.md(este archivo) estaba desactualizado respecto aHEAD.
v2.17.0 - familias grids/refs cross-coleccion + roguelike a lo grande
[2.17.0] — 2026-07-08
Release aditivo sobre 2.16.0 (bump minor, SPEC §7.0): dos frentes
independientes. En el core, la familia declarativa grids y el agregado
cross-colección en refs cierran la tercera etapa de reglas puras-de-datos (SPEC §11),
migrando los 4 perfiles que duplicaban esta lógica en JS. En roguelike, mecánicas
100% data-driven (llaves/puertas, jefe, progresión, permadeath), un solo generador
compartido entre los dos motores, mazmorra en mundo continuo 3D con minimapa, y guardado
persistente. La versión del protocolo sigue en 0.1.
Added — familias declarativas grids + agregado cross-colección en refs (SPEC §11, segunda y tercera etapa)
- Familia
gridsdeclarativa en el core:{ rule, emptyRule?, collection|singleton, shape?: { singleton, rowsField?, colsField? }, legend?: { rule, tileTarget, palField?, palMax? } }— valida filas de mapa/escena de ancho uniforme (autoconsistente contra la
primera fila, o contra una forma fija externa comoplatform.rows/.colsvíashape) y
resuelve cada símbolo delegend/fillcontra tiles+paleta, sin ejecutar código de perfil. - 4 perfiles migrados (mismos rule-ids, cero cambio de comportamiento observable):
adventure/dungeon(scene-rows/scene-dims/scene-legend-ref, autoconsistente) y
monster-rpg/tower-defense(map-dims/map-legend-ref, forma fija víaplatform) —
la misma lógica estaba duplicada en JS en los 4. refs[].targetacepta agregado cross-colección:arrayField(+itemField) además
decollection— el set válido se junta escaneando un array anidado en TODAS las
entradas de la colección, no soloObject.keys. Cubre "algún X entre N filas otorga el
valor Y" como dato en vez de código a mano.dungeon.warp-lockmigrado:warp.lockedexige un item que ALGÚNpickup, en
CUALQUIER escena, otorgue — antes unSetarmado a mano enruleScenes, ahora una
entrada declarativa derefs.- SPEC §6.1/§11 actualizado (grids + agregado cross-colección documentados; queda como
"tercera etapa" de reglas puras-de-datos — lo que sigue enruleses lógica genuinamente
no reducible a forma declarativa sin volverse un DSL).test/profile-descriptor.jscubre
las formas nuevas del descriptor (31 chequeos, de 28). Suite sin regresiones: mismas 136
reglas, 190 casos de conformidad, mutation audit 20/20.
Added — roguelike a lo grande: mecánicas por datos, un solo generador, mundo continuo
- Mecánicas nuevas 100% data-driven en el perfil
roguelikey su ejemplo:
llaves y puertas cerradas (generator.lockChance/keyChance+ tileskey/
lockedDoor; cerraduras mutuas entre salas; la llave abre AMBOS lados de forma
permanente), jefe custodiando el cofre (boss: tile/hp/damage — bloquea la
victoria hasta caer), progresión por experiencia (progression.killsPerAtk/
maxBonus: el ataque sube con las bajas) y permadeath declarativo
(progression.permadeath). 3 reglas nuevas de perfil (generator-chance,
boss-fields,progression-fields) → 136 reglas. - Solvencia por construcción: toda sala conserva ≥1 salida SIN cerrar, y como el
cofre aparece donde exploras (generación perezosa), nunca queda tras una puerta
cerrada — las llaves abren atajos y zonas extra. Verificado como invariante por BFS
ennpm test. - Un solo generador, dos motores POR CONSTRUCCIÓN: el visor 2D
(examples/roguelike.html) deja de duplicar la generación y pasa a importar la
misma lógica pura (game3d-logic.mjs) que usa game3d — renderer fino sobre
funciones testeadas.build-standaloneaprende a inlinear imports relativos de
módulos ESM (+2 chequeos) y el standalone sigue autocontenido. - game3d, mazmorra en mundo continuo: las salas se añaden contiguas a la escena
al explorar (comparten muro fronterizo, sin celdas duplicadas) y los pisos se
apilan físicamente en vertical — la cámara viaja con el jugador. Minimapa 3D
del grafo explorado (cubos por sala, pisos apilados, conexiones cerradas en rojo,
escaleras en azul) renderizado en una segunda pasada. Guardado automático de la
run en localStorage (rgSave/rgLoadpuros y testeados; N = nueva partida; el
guardado se limpia al ganar o caer en permadeath) y estadísticas de run en los
overlays (salas, bajas, caídas, profundidad máxima). - +17 chequeos en
npm testy CI (171 de lógica): solvencia por BFS, cerraduras
y llaves generadas, unlock que abre ambos lados, jefe que bloquea/daña/cae,
levelup con tope, permadeath → gameover, save/load ida y vuelta, y el bot
explorador ONLINE que gana jugando (rutea por el grafo conocido, toma salidas
inexploradas y derrota al jefe antes del cofre). - Verificado en navegador en ambos motores: el 2D con la lógica compartida
(puerta cerrada/llave con los textos del GAME.md) y game3d con guardado +
restauración tras recargar, nueva partida con N y victoria del explorador por
eventos de teclado reales — misma firma de run que el test de Node (6 salas,
1 baja, prof. 5): mismo mundo otra vez. - Nota: añadir tiradas al generador cambia los mundos respecto a v2.16.0 — la
paridad garantizada es entre motores, no con releases anteriores.
v2.16.0 — visor advance-wars: los 14 perfiles con runtime
Release aditivo sobre 2.15.0 (bump minor, SPEC §7.0): el visor
advance-wars completa el tablero — los 14 perfiles del repo tienen runtime en
game3d. Donde el perfil solo modela arte, el runtime no inventa gameplay: esa es la
tesis del protocolo aplicada hasta el final. La versión del protocolo sigue en 0.1.
Added — runtime advance-wars en game3d (visor): los 14 perfiles con runtime
- Runtime
advance-wars(14º y último perfil con runtime): visor 3D del arte
extraído — desfile de las unidades 4bpp sobre la rejilla que declaraplatform
(12×10), cámara orbital, cursor con flechas, Enter coge/suelta (recolocación con
bloqueo por ocupación) e inspección en el HUD (nombre, dimensiones, paleta). - Honestidad por diseño: este perfil modela solo arte (PALETTES + UNITS; sus
reglas son unit-dims/unit-palette-ref/unit-tiledata-range) — no hay vocabulario de
gameplay (stats, daño, terreno, mapa), así que el runtime no inventa combate:
gameplay as data significa que sin datos no hay gameplay (SPEC §8). El propio HUD
lo dice. Si se quisiera batalla real, el camino es extender perfil+ejemplo con
tokens de gameplay. - Lógica pura en
game3d-logic.mjs(awDecode/awInit/awCursor/awAct,
+16 chequeos ennpm testy CI): decode 4bpp de las 4 unidades reales validado
contra su paleta (color a color), errores en unidad inexistente/tileData roto,
desfile dentro de la rejilla sin solapes, topes de cursor, coger/soltar con bloqueo. - Verificado en navegador: boot, coger en vacío bloqueado, inspección de
INFANTRY, soltar sobre TANK bloqueado y recolocación a (0,0) — todo con eventos de
teclado reales. - Con esto, los 14 perfiles del repo tienen runtime en game3d.
v2.15.0 — runtime roguelike en game3d
Release aditivo sobre 2.14.0 (bump minor, SPEC §7.0): el artefacto
roguelike ya generado se vuelve jugable en game3d con la generación portada tal
cual del visor 2D — el mismo GAME.md produce el mismo mundo procedural en ambos
motores, verificado en vivo. La versión del protocolo sigue en 0.1.
Added — runtime roguelike en game3d
- Runtime
roguelike(13º perfil jugable): mazmorra procedural 3D — salas
reconstruidas al cruzar puertas (misma planta) y escaleras ▲▼ (otro piso), enemigos
patrullando, ítems y cofre como billboards del TILE_ART, parpadeo de
invulnerabilidad, flechas + Espacio. - La generación es un PORT EXACTO del visor 2D (
examples/roguelike.html): mismo
mulberry32, mismo hash de coordenadas, mismas reglas de puertas/escaleras mutuas y
cofre en la primera sala a profundidad ≥maxDepth. El mismo GAME.md produce el
mismo mundo en ambos motores — verificado en vivo: la ruta al cofre del test de
Node y la del navegador coinciden sala a sala. - Lógica pura en
game3d-logic.mjs(rgGenRoom/rgEnter/rgInit/rgMove/
rgAttack/rgPatrol, +16 chequeos ennpm testy CI): determinismo, invariantes
por BFS sobre ~100 salas generadas (toda sala tiene salida; puertas y escaleras
mutuas; cofre único a profundidad ≥ maxDepth), combate con hp del ENEMY_POOL,
caída con respawn en el origen, pociones con tope y armas que solo mejoran
(ITEM_POOL), y el cofre GANADO jugando movimiento a movimiento (BFS de salas +
caminado real, 39 acciones). - Verificado jugando en navegador: bot por eventos de teclado reales hasta el
overlay de victoria con elWIN.textdel GAME.md.
v2.14.0 — runtime crafting en game3d
Release aditivo sobre 2.13.0 (bump minor, SPEC §7.0): el artefacto
crafting ya generado se vuelve jugable en game3d — meta derivada de los datos
(recetario completo), ganada y perdida en Node con conservación exacta por material.
La versión del protocolo sigue en 0.1.
Added — runtime crafting en game3d
- Runtime
crafting(12º perfil jugable): el artefacto ya generado corre en
game3d sin tocar core ni datos — taller DOM (materiales con teclas 1..N, estación
con M, recetas con A..Z coloreadas por disponibilidad, objetos e inventario) sobre
fragua 3D (yunque y brasas que laten), overlays de victoria/derrota. - Lógica pura en
game3d-logic.mjs(crInit/crGather/crMove/crCraft,
+12 chequeos ennpm testy CI): stack por MATERIALS, estación e inputs por
RECIPES, valor por outputValue. Recetario completado y perdido en Node;
conservación exacta por material (recolectado − consumido = inventario); craftear
sin estación / en la equivocada / sin materiales →blocked; stack se detiene
en el tope declarado. - Semántica del motor documentada (SPEC §8): la meta es completar el recetario
(craftear cada receta ≥1 vez — derivada de los datos, sin números inventados) con
presupuesto deCR_ACTIONS = 30acciones; recolectar/moverse/craftear cuestan 1;
derrota al agotarlas. - Verificado jugando en navegador: craft en vacío bloqueado, recolección por
teclas, cambio de estación y recetario completo hasta el overlay de victoria
(valor 90, 22 acciones sobrantes).
v2.13.0 — runtime platformer en game3d
Release aditivo sobre 2.12.0 (bump minor, SPEC §7.0): el artefacto
platformer ya generado se vuelve jugable en game3d — geometría procedural salvable
por construcción y verificada por test contra PHYSICS, con partida ganada por bot en
Node. La versión del protocolo sigue en 0.1.
Added — runtime platformer en game3d
- Runtime
platformer(11º perfil jugable): el artefacto ya generado corre en
game3d sin tocar core ni datos — vista lateral 3D con cámara que sigue al jugador,
suelo coloreado portileset, enemigos por hp, bandera engoal.x, parpadeo de
invulnerabilidad; ←/→ corre y Espacio/↑ salta (teclas mantenidas). Expone
step()/heldpara pilotar desde harnesses. - Lógica pura en
game3d-logic.mjs(pfJumpReach/pfLevelGeom/pfInit/pfTick,
+16 chequeos ennpm testy CI): física por ticks desde PHYSICS (gravity/jump/
runSpeed), pisotón (KOOPA aguanta 2, hp desde ENEMIES), daño lateral con
invulnerabilidad, caída al hueco con respawn, niveles encadenados hasta la victoria.
Partida ganada por bot en Node (2 niveles) y perdida por contacto repetido. - Semántica del motor documentada (SPEC §8): los niveles no declaran geometría, así
que el suelo son segmentos con huecos por LCG determinista salvables por
construcción — y el test lo verifica contra PHYSICS: hueco máximo ≤ 60% del
alcance de salto derivado (12.2 unidades con los datos del ejemplo). - Verificado jugando en navegador: partida completa pilotando las teclas
mantenidas del propio runtime hasta el overlay con elTEXT.windel GAME.md.
v2.12.0 — runtime tower-defense en game3d
Release aditivo sobre 2.11.0 (bump minor, SPEC §7.0): el artefacto
tower-defense ya generado se vuelve jugable en game3d — simulación por ticks sin
azar, ganada y perdida en Node, con tablero 3D completo. La versión del protocolo
sigue en 0.1.
Added — runtime tower-defense en game3d
- Runtime
tower-defense(10º perfil jugable): el artefacto ya generado corre en
game3d sin tocar core ni datos — tablero 3D completo (rejilla 12×8, camino, torres
como cilindros por tipo, enemigos como esferas por blindaje), cursor con flechas,
construir con 1..N, vender con S (asellRatio), oleadas con Espacio, overlays de
victoria/derrota. El runtime exponestep()para pilotar ticks desde harnesses. - Lógica pura en
game3d-logic.mjs(tdPath/tdPos/tdInit/tdBuild/tdSell/
tdStartWave/tdTick, +11 chequeos ennpm testy CI): simulación por ticks sin
azar (spawns por count/gap, targeting al enemigo más avanzado en rango, daño por
DMG_CHART[dmgType][armor]). Partida ganada y perdida en Node: 4 rifles
centrales superan las 2 oleadas (15/15 abatidos, 0 fugas) y sin torres se pierde;
conservación verificada en cada tick (aparecidos = muertos + fugados + vivos);
venta afloor(cost·sellRatio); construir sobre el camino o sin oro →blocked. - Semántica del motor documentada (SPEC §8): el ejemplo no declara
MAPS, así que el
camino es una ruta en S fija sobre 12×8; 30 ticks ≈ 1 s (speed = celdas/s, rate =
disparos/s, gap en ticks); recompensa y luego interés al limpiar la oleada. - Verificado jugando en navegador: torres construidas con teclado real, intento
ilegal sobre el camino rechazado, 2 oleadas pilotandostep()hasta el overlay de
victoria (oro final 186, vidas 20/20).
v2.11.0 — runtime papers-please en game3d
Release aditivo sobre 2.10.0 (bump minor, SPEC §7.0): el artefacto
papers-please ya generado se vuelve jugable en game3d — sin tocar core ni datos, con
la evaluación por RULES verificada contra las decisiones declaradas del ejemplo. La
versión del protocolo sigue en 0.1.
Added — runtime papers-please en game3d
- Runtime
papers-please(9º perfil jugable): el artefacto ya generado
(examples/papers-please.generated.js) corre en game3d sin tocar core ni datos —
ventanilla DOM (documentos del solicitante como fichas) sobre fondo 3D (muro
fronterizo y barrera que se alza al aprobar), teclas A/D, cita de la regla violada
en cada veredicto, renta al cierre del día y overlays de victoria/despido. - Lógica pura en
game3d-logic.mjs(ppEval/ppInit/ppEntrant/ppDecide,
+14 chequeos ennpm testy CI): los 4 tipos de regla (require-document,
ban-country, require-field-match, not-expired) evaluados desde datos. Oráculo de
autoría: la evaluación por RULES reproduce ladecisiondeclarada de los 4
solicitantes. Partida completa ganada y perdida en Node con contabilidad
verificada (money = aciertos×salary − fallos×penaltyFee − días×rent). - Semántica del motor documentada (SPEC §8): fecha de corte
PP_TODAY = 1983.01
paranot-expired, derrota al 3er error,moneycomo marcador (puede ser negativo). - Verificado jugando en navegador: turno completo con error deliberado (multa),
cita de regla, renta por día y overlay de victoria con la contabilidad exacta.
v2.10.0 — Senku (peg-solitaire) + sudoku, ambos puro-datos
Release aditivo sobre 2.9.0 (bump minor, SPEC §7.0): dos géneros
nuevos de punta a punta sin tocar el core — el Senku real (perfil puro-datos
peg-solitaire, tableros solubles por construcción, soluciones rejugadas en npm test)
y el perfil sudoku, nacido de un malentendido del nombre y conservado como género
propio. La versión del protocolo sigue en 0.1.
Added — perfil peg-solitaire (puro-datos) + Senku
profiles/peg-solitaire.json(14º perfil, cuarto puro-datos): senku/solitario de
clavijas — tableros como 7 filas de 7 caracteres (_fuera,opeg,.hueco),
goalpor enum (clear= dejar 1 peg |center= dejarlo en el centro),
difficultypor enum yplayer.startpor broken-ref. Límite documentado: la forma
7×7 y el alfabeto de los strings no caben en las familias declarativas (dims exige
matrices de arrays) — los validapegChecken la simulación y ennpm test(tercer
caso para SPEC §11: validadores de patrón/longitud de string).examples/senku.GAME.md(+ generated): 3 tableros solubles por construcción
— B1 y B2 generados por movimientos inversos desde un único peg (LCG determinista),
B3 es el inglés clásico (32 pegs, hueco central, goal center) resuelto por el solver
DFS del generador en 4 ms. Ni una celda escrita a mano. Lint 0/0 a la primera.- Lógica pura en
game3d-logic.mjs(pegCheck/pegInit/pegMoves/pegMove,
+21 chequeos ennpm testy CI): los 3 tableros reales validados y sus soluciones
rejugadas hasta la victoria (B3: 31 saltos con el último peg en el centro),
conservación (pegs = iniciales − saltos en cada paso), saltos ilegales bloqueados,
derrota por bloqueo y derrota específica degoal: center. - Runtime
peg-solitaireen game3d (8º perfil jugable): tablero DOM 7×7 sobre
fondo 3D, flechas + Enter/Espacio (elegir peg y saltar) + Escape, overlays de
victoria/derrota. Verificado jugando en navegador.
Added — perfil sudoku (puro-datos) + Sudoku
- Nacido de una interpretación errónea de «senku» (es el solitario de clavijas, no el
sudoku); el trabajo quedó completo y verificado, así que se conserva como perfil
propio con el juego renombrado aexamples/sudoku.GAME.md. profiles/sudoku.json(13º perfil, tercer puro-datos): puzzles como strings de
81 caracteres (gridcon.+solution),difficultypor enum,player.start
por broken-ref ybalance(lives/hints). Límite documentado: longitud/patrón de los
strings y la consistencia grid↔solution no caben en las familias declarativas —
las validasudokuChecken la simulación de referencia y ennpm test(segundo caso
concreto para SPEC §11: validadores de patrón/longitud de string).examples/sudoku.GAME.md(+ generated): 3 puzzles generados por script con
verificación de unicidad (backtracking + conteo de soluciones; easy 40 / normal 32
/ hard 27 pistas) — ni un dígito escrito a mano. Lint 0/0 a la primera.- Lógica pura en
game3d-logic.mjs(sudokuCheck/sudokuInit/sudokuSet/
sudokuHint, +14 chequeos ennpm testy CI): los 3 puzzles reales validados
(consistencia + validez por filas/columnas/cajas), victoria rellenando la solución,
derrota al agotar vidas, pistas dadas inmutables, hint con descuento. - Runtime
sudokuen game3d (7º perfil jugable): tablero DOM 9×9 sobre fondo 3D,
flechas + dígitos + H para pista, overlays de victoria/derrota. Verificado jugando
en navegador: pista inmutable, fallo que descuenta vida, hint, y tablero resuelto
hasta el overlay de victoria. - README: 128 → 133 reglas (reconteo por script tras ambos perfiles).
v2.9.0 — shooter: perfil puro-datos + Neon Swarm + simulación testeada en Node
Release aditivo sobre 2.8.1 (bump minor según SPEC §7.0): un género nuevo de punta a punta sin tocar el core — la tesis del protocolo, ejecutada otra vez, ahora con simulación verificable. La versión del protocolo sigue en 0.1.
Added — shooter: perfil puro-datos + Neon Swarm + simulación testeada + runtime
profiles/shooter.json(12º perfil, segundo puro-datos): arena shmup vertical —ships,weapons,enemiesconbehavior(enum chaser/drifter),waves,powerups(heal/rapid/shield),arenacontinua ybalance. 4 refs con mensajes por defecto, 14 bounds, 2 enums — cero funciones,dataOnly: true. Límite documentado:boundsno alcanza campos dentro de arrays (spawns[].count/gap— primer caso concreto para los "agregados anidados" de SPEC §11).- Neon Swarm: 2 naves, 2 armas, 4 enemigos, 5 oleadas, 3 powerups. Lint 0/0 a la primera.
- Simulación pura (
shooterInit/shooterTick+ LCG engame3d-logic.mjs): determinista, un tick = un frame — el juego entero se gana y se pierde en Node dentro denpm test(+9 chequeos): victoria de la IA sobre las 5 oleadas, derrota sin input, invariante de conservaciónkills+leaked+lost == spawns(que cazó un hueco de contabilidad real al escribirlo), rapid a mitad de cooldown, shield y heal con tope. - Runtime
shooteren game3d: render Three.js de la simulación (input mantenido, HUD, overlays). Verificado además sobre el estado vivo del navegador: victoria con 920 pts y conservación exacta (46+5+4=55). Nota operativa: el RAF pausa en pestañas ocultas — los harnesses pilotan los ticks directamente. - Conformance 179 casos (+13), 16 pares de ejemplos, 12 hints nuevos, 128 reglas, 12 perfiles; footer de index y nota SPEC §6 sin enumeraciones (principio anti-drift).
Changelog completo: CHANGELOG.md