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

6.9 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 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.