Files
orni-attack/MIGRATION_PLAN.md
T
2026-05-20 07:58:24 +02:00

141 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Plan de migración Orni Attack → SDL3 GPU + física vectorial
Documento maestro de la rama `rewrite/physics-gpu`. Resumen del progreso y
qué queda. Si pierdes el contexto de la sesión, **léeme primero**.
## Visión
Modernizar la base técnica del juego antes de tunear jugabilidad:
1. Limpiar legacy (polares, mezcla catalán/inglés, header guards).
2. Adoptar formato 16:9 (1280×720).
3. Importar subsistemas robustos de AEEA (audio, *input deferido*).
4. Implementar física vectorial 2D con rigid bodies + colisiones elásticas.
5. **Migrar renderizado a SDL3 GPU sin fallback** ([memoria: project-no-sdl-fallback](./.claude/projects/-home-sergio-gitea-orni-attack/memory/project_no_sdl_fallback.md)).
6. Postprocesado y color.
El tuning de feeling se hace al final, post-GPU.
## Estado actual
Rama de trabajo: **`rewrite/physics-gpu`** (pusheada a Gitea).
Tag de seguridad: **`beta-3.0`** (snapshot de `main` antes de empezar).
| Fase | Estado | Commits |
|---|---|---|
| 0 — Limpieza de código muerto (primitives, polígonos, Bresenham, polares) | ✅ | `6cf990b` |
| 1a — `Punt → Vec2` con operadores modernos | ✅ | `cd38101` |
| 1b — Renames de entidades + métodos virtuales a camelBack | ✅ | `ae5cc1c` |
| 1c — Renames de escenas | ✅ | `5871d29` |
| 1d — Renames effects/stage_system/locales | ✅ | `7ee359b` |
| 1e — Pragma once + locales restantes + comentarios castellano | ✅ | `bf83f16` |
| (fix) — clave YAML `quadrat → cuadrado` post-sweep | ✅ | `56533ca` |
| 2 — Cambio a 1280×720 (16:9) | ✅ | `a4f6a55` |
| 3 — Import del subsistema de Audio desde AEEA | ✅ | `ed98ef6` |
| **4** — Input parcial AEEA | ⏭️ **saltado** (decisión usuario) | — |
| 5 — Infraestructura física (`RigidBody`, `PhysicsWorld`) | ✅ | `0fd9360` |
| 6a+b — `body_` en Entity + `world_` en GameScene | ✅ | `0574077` |
| 6c — Migrar Ship | ✅ | `2fe22ff` |
| 6d — Migrar Enemy | ✅ | `27242f5` |
| 6e — Migrar Bullet | ✅ | `9993b2d` |
| 7a — Infra GPU (shaders + wrappers, runtime dormido) | ✅ | `ba6fd00` |
| 7b+c — Swap atómico a SDL3 GPU + line_renderer al pipeline | ✅ | `fa7da4c` |
| 7d — Validación visual del usuario en hardware Vulkan | ✅ | — |
| 9a — Extraer `Systems::Collision` | ✅ | `896a899` |
| 9b — Extraer `Systems::ContinueScreen` | ✅ | `816bc02` |
| 9c — Extraer `Systems::InitHud` | ✅ | `a4942fc` |
| 9d — Descomponer `GameScene::update` (339→18 LOC) | ✅ | `808abb2` |
| **8 — Postprocesado + paleta de colores por entidad** | 🔲 **siguiente** | — |
| 10 — Tuning final de masa/restitución/damping | 🔲 | — |
| Mac/Metal — shaders MSL en build | 🔲 | — |
| 8 — Postprocesado, color, paleta por tipo | 🔲 | — |
| 9 — Refactor de GameScene (2.877 LOC → módulos) | 🔲 | — |
| 10 — Tuning final de masa/restitución/damping | 🔲 | — |
## Lo que queda inmediato (Fase 8 — postprocesado + paleta de colores)
Fase 7 y Fase 9 cerradas. Validación visual SDL3 GPU OK (`Backend GPU: vulkan`).
`GameScene.cpp` 1429 → 1015 LOC; `update()` 339 → 18 LOC, complexity baja a
< 10 por sub-paso. Tres sistemas extraídos a `source/game/systems/`:
- `Systems::Collision` (~210 LOC propios)
- `Systems::ContinueScreen` (~160 LOC propios)
- `Systems::InitHud` (~155 LOC propios)
**Fase 8 — siguientes pasos**:
1. Color por entidad (paleta semántica): naves blancas, balas verdes,
pentagons azules, quadrats rojos, molinillos magenta, debris hereda
color del padre. Hoy todo se pinta con el color global del oscilador
(`g_current_line_color`). Hay que pasar el color al `pushLine` desde
las entidades (cada entity expone un `getColor()`).
2. Postprocesado básico:
- Bloom/glow: render-to-texture al swapchain real con fragment shader
que aplique kernel separable de blur sobre los píxeles iluminados.
Requiere un pipeline extra y un par de texturas off-screen.
- Opcional: scanlines o leve aberración cromática para feel CRT.
**Fase 10** (tras 8): tuning de mass/restitution/damping con feedback
visual de los colores.
**Mac/Metal**: cuando vayamos a release de macOS, añadir compilación
de los shaders también a MSL (con `spirv-cross` o `glslangValidator`).
## Memoria del proyecto
Las preferencias y decisiones persistentes están en:
`~/.claude/projects/-home-sergio-gitea-orni-attack/memory/MEMORY.md` y los
archivos enlazados desde ahí. Léelos al empezar sesión nueva.
Resumen:
- **No fallback a SDL_Renderer** en Fase 7 — solo GPU o falla.
- **Naming**: `.clang-tidy` exige `CamelCase` tipos, `camelBack` métodos,
`lower_case_` miembros privados, `UPPER_CASE` constantes.
- **Costuras del título tras 16:9** son tuning artístico, no bug, post-Fase 10.
- **Push automático** tras cada commit en `rewrite/physics-gpu`.
- **Smoke test xvfb** (`timeout 5 xvfb-run -a ./build/orni 2>&1 | head -40`)
tras builds importantes para validar arranque.
## Convenciones técnicas
- **Lenguaje código**: inglés. **Lenguaje comentarios**: castellano. **Strings
de UI**: valenciano (preservados).
- **Coordenadas**: cartesianas (`Vec2`). Polares prohibidas (legacy).
- **Resolución lógica**: 1280×720. Constantes en `core/defaults.hpp`.
- **Audio**: import de AEEA. API: `Audio::get()->playSound/playMusic` con
crossfade y efectos.
- **Física**: `Physics::RigidBody` en `core/physics/rigid_body.hpp`,
`Physics::PhysicsWorld` en `core/physics/physics_world.hpp/.cpp`.
Entity tiene `body_` como member. Flujo tri-fase por frame en
`GameScene::update`:
1. `physics_world_.update(dt)` — integrar y resolver
2. `entity.postUpdate(dt)` — sincronizar mirror (center_, angle_)
3. Lógica del juego (input, AI, etc.) — aplica fuerzas/cambia velocity
## Cómo reanudar tras compactación
1. Lee este archivo.
2. Lee `MEMORY.md` (memorias persistentes).
3. `git log --oneline -20` para ver últimos commits.
4. `git status` para ver si hay trabajo en curso sin commitear.
5. Si la fase actual estaba a medias: continúa donde se quedó (este archivo
indica en qué fase estamos).
6. Tras cada commit, push automático: `git push origin rewrite/physics-gpu`.
## Configuración física actual (Fase 6e)
| Entidad | mass | radius (world) | restitution | linear_damping | angular_damping |
|---|---|---|---|---|---|
| Ship | 10.0 | 12 | 0.6 | 1.5 | 0.0 |
| Enemy Pentagon | 5.0 | 20 | 1.0 | 0.0 | 0.0 |
| Enemy Quadrat | 8.0 | 20 | 1.0 | 0.0 | 0.0 |
| Enemy Molinillo | 4.0 | 20 | 1.0 | 0.0 | 0.0 |
| Bullet | 0.5 | **0** (cinemática) | 0 | 0 | 0 |
| Wall (PLAYAREA bounds) | ∞ (estático) | — | — | — | — |
Nota: Bullet usa `radius=0` en el body físico para que no participe en las
colisiones del world (ni body-body ni bounds). El radio de gameplay
(`Defaults::Entities::BULLET_RADIUS = 3`) lo expone vía `getCollisionRadius()`
y lo consumen `check_collision` y la detección de salida del PLAYAREA en
`Bullet::update`.
Las paredes son implícitas: `physics_world_.setBounds(PLAYAREA)` en
`GameScene::init`. No son `RigidBody` separados, sino un AABB que rebota.