Files
orni-attack/MIGRATION_PLAN.md
T
JailDesigner c50ca23135 Anadir MIGRATION_PLAN.md en raiz como referencia maestra
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>
2026-05-19 13:42:04 +02:00

6.4 KiB
Raw Blame History

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).
  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 🔲 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: setear body_.position y body_.velocity cartesiano a 140 px/s en dirección del shooter.
  • update(): detectar si salió del PLAYAREA con margen; si sí, desactivar().
  • postUpdate(): sincronizar center_ desde body_.position.
  • En GameScene: registrar bodies en init(), llamar postUpdate() en update().
  • Cuando un bullet se desactiva: body_.radius = 0 para 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 = 0 para 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 mass a 15-20 (más "anclado", menos empujable por enemies).
  • Enemies: reducir restitution a 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-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 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.