Documento que resume el estado de la migracion (rama rewrite/physics-gpu), las fases completadas con sus commits, lo que queda inmediato y donde estan las decisiones persistentes (memoria del proyecto). Para sobrevivir compactaciones de contexto y permitir reanudar la migracion en sesiones futuras sin perder el hilo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.4 KiB
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:
- Limpiar legacy (polares, mezcla catalán/inglés, header guards).
- Adoptar formato 16:9 (1280×720).
- Importar subsistemas robustos de AEEA (audio, input deferido).
- Implementar física vectorial 2D con rigid bodies + colisiones elásticas.
- Migrar renderizado a SDL3 GPU sin fallback (memoria: project-no-sdl-fallback).
- 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 | 🔲 siguiente | — |
| 7 — Migración a SDL3 GPU (sin fallback) | 🔲 | — |
| 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 6e)
Migrar Bullet al PhysicsWorld. Es la entidad más simple:
- Constructor:
body_.setMass(0.5),radius = BULLET_RADIUS = 3,restitution = 0(NO rebotan, salen del PLAYAREA y se desactivan),linear_damping = 0. init()resetea body_.disparar()/spawn: setearbody_.positionybody_.velocitycartesiano a140 px/sen dirección del shooter.update(): detectar si salió del PLAYAREA con margen; si sí,desactivar().postUpdate(): sincronizarcenter_desdebody_.position.- En GameScene: registrar bodies en
init(), llamarpostUpdate()enupdate(). - Cuando un bullet se desactiva:
body_.radius = 0para no estorbar. - Edge case importante: las balas NO deben rebotar contra las naves de los
jugadores. Las colisiones físicas las hace el world automáticamente. Para
evitarlo:
- Opción A: dejar que el world resuelva el impulso, pero la lógica de gameplay (en GameScene) detecta el hit y desactiva el bullet antes de que se vea visualmente el rebote (1 frame de margen).
- Opción B: hacer que
body_.radius = 0para las balas, así no colisionan físicamente, y solo las colisiones de gameplay (check_collision en GameScene) las gestionan. - Recomendado: Opción B. Las balas físicamente no necesitan colisión del world — son cinemáticas. Solo el gameplay las usa.
Tras 6e, hacer Fase 10 (tuning): ajustar masas, restitución, damping según feel. Probablemente:
- Ship: subir
massa 15-20 (más "anclado", menos empujable por enemies). - Enemies: reducir
restitutiona 0.85 (rebote más natural, sin "pelota"). - Probar collision con friendly fire / nave-enemy en debris ahora que ambos tienen body real.
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-tidyexigeCamelCasetipos,camelBackmétodos,lower_case_miembros privados,UPPER_CASEconstantes. - 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/playMusiccon crossfade y efectos. - Física:
Physics::RigidBodyencore/physics/rigid_body.hpp,Physics::PhysicsWorldencore/physics/physics_world.hpp/.cpp. Entity tienebody_como member. Flujo tri-fase por frame enGameScene::update:physics_world_.update(dt)— integrar y resolverentity.postUpdate(dt)— sincronizar mirror (center_, angle_)- Lógica del juego (input, AI, etc.) — aplica fuerzas/cambia velocity
Cómo reanudar tras compactación
- Lee este archivo.
- Lee
MEMORY.md(memorias persistentes). git log --oneline -20para ver últimos commits.git statuspara ver si hay trabajo en curso sin commitear.- Si la fase actual estaba a medias: continúa donde se quedó (este archivo indica en qué fase estamos).
- Tras cada commit, push automático:
git push origin rewrite/physics-gpu.
Configuración física actual (Fase 6d)
| Entidad | mass | radius | 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 | (pendiente Fase 6e) | 3 | 0 | 0 | 0 |
| Wall (PLAYAREA bounds) | ∞ (estático) | — | — | — | — |
Las paredes son implícitas: physics_world_.setBounds(PLAYAREA) en
GameScene::init. No son RigidBody separados, sino un AABB que rebota.