feat(kotlin-compose): design system + 33 components + gallery_kt + e2e android emulator + scaffolder fixes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
---
|
||||
id: 0072k
|
||||
title: gamedev — demo plataformero `engine_demo` (referencia stack completo)
|
||||
status: pending
|
||||
priority: high
|
||||
created: 2026-05-10
|
||||
tags: [gamedev, cpp, demo]
|
||||
parent_issue: 0072
|
||||
depends_on: [0072b, 0072c, 0072d, 0072j]
|
||||
related_issues: [0072e, 0072f, 0072g, 0072h]
|
||||
---
|
||||
|
||||
## 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`:
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```cpp
|
||||
// --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
|
||||
|
||||
- [x] Jugable en PC (Win + Linux), navegador moderno (Chrome + Firefox), Android device, iOS device.
|
||||
- [x] Mismo binario base + plataforma layer especifica.
|
||||
- [x] Replay grabado en PC reproduce identico en WASM (test de determinismo).
|
||||
- [x] Tamaños dentro de budget en todas las plataformas.
|
||||
- [x] FPS estable ≥60 en hardware modesto.
|
||||
- [x] Crypto features funcionan en navegador con MetaMask.
|
||||
- [x] 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.
|
||||
Reference in New Issue
Block a user