Files
fn_registry/dev/issues/0072k-gamedev-demo-platformer.md
T

7.5 KiB

id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
id title status type domain scope priority depends blocks related created updated tags
0072k gamedev — demo plataformero `engine_demo` (referencia stack completo) pendiente feature
gamedev
multi-app alta
0072b
0072c
0072d
0072j
2026-05-10 2026-05-17
gamedev
cpp
demo

Objetivo

App cpp/apps/engine_demo/ que valida end-to-end que el stack funciona en las 4 plataformas: PC, Web, Android, iOS. Plataformero 2D simple, 1 nivel, con todas las features tipicas para servir como referencia y test de regresion del stack.

Por qué este demo

  • Sirve de test integrado del stack completo (runtime + assets + physics + crypto).
  • Es la referencia que cualquier dev nuevo lee para entender como ensamblar las funciones del registry en un juego completo.
  • Permite medir performance real (FPS, peso de bundle) en cada plataforma.
  • Acta como gate del CI: si engine_demo rompe, algo del stack rompio.

Features del juego

Feature Funciones del registry usadas
Player con sprite animado sprite_batch, anim_* (issue 0031), input_unified
Movimiento (left/right/jump) physics_body, physics_shape, input_unified
Tilemap nivel 1 tilemap_render, tilemap_compile, physics_shape_chain
Coins coleccionables sensores Box2D + physics_get_sensor_events
Enemy patrullando kinematic body + simple AI state machine
Trampas (spikes) sensor + game over
Goal flag sensor + level complete
HUD: score + lives ImGui o custom MSDF text
Menu principal ImGui o sprites + input
Pause menu ImGui
Sound effects audio_play_sound (jump, coin pickup, hit, win)
Background music audio_play_music
Shaders vistosos bg parallax + bloom post-process via gfx/shader_canvas
Save game local storage (PC) / localStorage (WASM) / getFilesDir() (Android/iOS)
Settings (volumen, controles) app_settings (ya en registry)
Splash screen + loading logo + barra

Features crypto opcionales (gated por flag de build):

  • Connect wallet button (sub-issue 0072e)
  • High score leaderboard firmado (sub-issue 0072f)
  • NFT skin del wallet conectado (0072f)

Estructura

cpp/apps/engine_demo/
  CMakeLists.txt
  app.md
  main.cpp                 # Entry point + game loop
  game.{cpp,h}             # Game state machine (menu/play/pause/gameover)
  player.{cpp,h}           # Player controller + animations
  enemy.{cpp,h}            # Simple AI
  level.{cpp,h}            # Tilemap loader + collision setup
  hud.{cpp,h}              # Score, lives, timer
  menus.{cpp,h}            # Title, pause, gameover, settings
  audio.{cpp,h}            # SFX/music coordinator
  crypto.{cpp,h}           # Wallet connect + leaderboard (#ifdef CRYPTO)
  android/                 # Android project (sub-issue 0072g)
  ios/                     # iOS project (sub-issue 0072h)
  web/                     # WASM shell.html + bridge.js (sub-issue 0072e)
  assets/                  # Source assets (.png, .wav, .ttf, .tmx)
    sprites/
    sounds/
    music/
    fonts/
    levels/
  build/                   # Output del asset_compiler (gitignored)

Asset budget

Limites para mantener el download inicial razonable:

Asset Limite
Sprite atlas (1024x1024) 200 KB PNG
MSDF font 50 KB PNG + 5 KB JSON
SFX (4 sonidos, ogg) 100 KB total
Music (1 track, ogg vorbis q=3) 1 MB
Tilemap binario (1 nivel) 30 KB
Total assets bundle ≤ 1.5 MB

WASM gzip + assets gzip total: ≤ 3.5 MB descargados.

Pipeline de build

bash/functions/pipelines/build_engine_demo_all.sh:

#!/usr/bin/env bash
set -euo pipefail

# 1. Compile assets
./build/cpp/apps/asset_compiler/asset_compiler bundle \
    --in cpp/apps/engine_demo/assets \
    --out build/engine_demo/assets.pak

# 2. Build PC
cmake --build build --target engine_demo -j

# 3. Build WASM
bash bash/functions/pipelines/build_wasm_cpp_pipelines.sh engine_demo

# 4. Build Android (si hay NDK)
[ -n "${ANDROID_NDK_HOME:-}" ] && \
    bash bash/functions/pipelines/build_android_cpp_pipelines.sh engine_demo

# 5. Build iOS (si hay mac)
[ "$(uname)" = "Darwin" ] && \
    bash bash/functions/pipelines/build_ios_cpp_pipelines.sh engine_demo

# 6. Reporte
echo "── Sizes ──"
ls -lah build/engine_demo/

e2e_checks completos

e2e_checks:
  - id: build_pc
    cmd: "cmake --build build --target engine_demo -j"
    timeout_s: 300
  - id: self_test
    cmd: "./build/cpp/apps/engine_demo/engine_demo --self-test"
    timeout_s: 60
  - id: build_wasm
    cmd: "bash bash/functions/pipelines/build_wasm_cpp_pipelines.sh engine_demo"
    timeout_s: 600
  - id: wasm_size_budget
    cmd: "test $(stat -c%s build/wasm/engine_demo.wasm.gz) -lt 2097152"  # 2MB
  - id: assets_size_budget
    cmd: "test $(stat -c%s build/engine_demo/assets.pak) -lt 1572864"  # 1.5MB
  - id: replay_test
    cmd: "./build/cpp/apps/engine_demo/engine_demo --replay tests/replay_level1_complete.bin"
    timeout_s: 60
  - id: ops_audit
    ref: "fn-recopilador:apps/engine_demo"

Replay determinista

Para validar que el stack es determinista (importante por crypto leaderboards), grabar inputs de una run completa del nivel y poder reproducirla:

// --record output.bin → graba InputState cada frame
// --replay input.bin → reproduce inputs, asserta que el final state es identico

Funcion: cpp/functions/gamedev/replay_record.{cpp,h,md} + replay_play.{cpp,h,md}.

Si el replay diverge, hay un bug de determinismo en alguna funcion del stack. Es nuestro test de regresion mas potente.

Niveles

1 solo nivel built-in para mantener simple. Si el editor (0072i) esta listo, el nivel se hace ahi y se exporta. Si no, se hace a mano en Tiled (formato .tmx).

Visual style

Pixel art simple para mantener tamaño bajo. Paleta limitada (PICO-8 o similar). Background con gradiente shader animado (no PNG → ahorra KB).

Shaders incluidos:

  • Background gradient + parallax
  • Player squash/stretch on jump (vertex shader simple)
  • Coin sparkle (sprite + shader noise)
  • Bloom post-process (fullscreen pass) — opcional, toggle en settings
  • CRT-effect overlay — opcional, toggle en settings

Crypto features (gated)

Build flag CRYPTO=1 activa:

  • Boton "Connect Wallet" en main menu.
  • Leaderboard mostrando top 10 firmados.
  • Si conectado wallet con NFT skin, usa la imagen del NFT como sprite del player.

Sin CRYPTO=1, el juego es totalmente jugable sin wallet (importante: NO gating del juego basico).

Criterio de exito

  • Jugable en PC (Win + Linux), navegador moderno (Chrome + Firefox), Android device, iOS device.
  • Mismo binario base + plataforma layer especifica.
  • Replay grabado en PC reproduce identico en WASM (test de determinismo).
  • Tamaños dentro de budget en todas las plataformas.
  • FPS estable ≥60 en hardware modesto.
  • Crypto features funcionan en navegador con MetaMask.
  • CI corre e2e_checks y bloquea regresiones.

No-objetivos

  • Multiple niveles. Solo 1 para demo.
  • Multiplayer.
  • Save/load con cloud sync.
  • Achievements / Steam integration.
  • Mas que un genero. Plataformero por encajar bien con todas las features.

Riesgos

  1. Determinismo cross-platform-ffast-math o diferencias de floor/ceil pueden romperlo. Auditar flags por plataforma.
  2. Audio latency mobile — pruebas reales en device. Si > 80ms, evaluar AAudio backend en Android.
  3. Performance en device viejo — target Android 7+ y iPhone 6S+. Profile en hardware modesto.