Files
orni-attack/MIGRATION_PLAN.md
T
JailDesigner 9993b2d98c Fase 6e: migrar Bullet al sistema de fisica vectorial
Las balas pasan a ser cinematicas dentro del PhysicsWorld:
- body_.setMass(0.5), radius=0 (no colisionan fisicamente)
- disparar() setea body_.position + body_.velocity cartesiana (140 px/s)
- update() detecta salida del PLAYAREA via body_.position y desactiva
- postUpdate() sincroniza center_ desde body_.position
- desactivar() detiene el body para evitar deriva mientras inactiva

GameScene registra los bodies en init() y llama postUpdate(). El gameplay
sigue gestionando colisiones bullet-enemy/bullet-ship con check_collision
(el radio gameplay es BULLET_RADIUS=3, expuesto via getCollisionRadius).

Renames a camelBack (clang-tidy): get_owner_id->getOwnerId,
get_grace_timer->getGraceTimer.

MIGRATION_PLAN.md actualizado: Fase 6e cerrada, Fase 7 (SDL3 GPU) siguiente.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:50:17 +02:00

6.3 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 (este commit)
7 — Migración a SDL3 GPU (sin fallback) 🔲 siguiente
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 7)

Migración del renderizado a SDL3 GPU sin fallback.

Fase 6e completada: las balas son cinemáticas dentro del PhysicsWorld (radius=0 en el world → no colisionan físicamente, solo gameplay-level via check_collision). Body con mass=0.5, restitution=0, damping=0. disparar() setea body_.position + body_.velocity cartesiana; update() detecta salida de PLAYAREA y desactiva; postUpdate() sincroniza center_ desde body. Smoke test xvfb pasa sin errores.

Decisión técnica del proyecto: no fallback a SDL_Renderer (memoria). La fase 7 reemplaza completamente el pipeline actual de SDL_Renderer (SDL_RenderLine, SDL_RenderGeometry) por SDL3 GPU.

Tareas previstas Fase 7:

  • Sustituir SDL_Renderer* por SDL_GPUDevice* en SDLManager.
  • Setup de swapchain + shaders básicos (vertex + fragment) para líneas vectoriales.
  • Migrar Rendering::render_shape a un pipeline GPU que reciba vertex buffers.
  • Postprocesado mínimo (Fase 8): bloom/glow, paleta por tipo de entidad.

Fase 10 (tuning) queda pendiente para después de SDL3 GPU + postpro. El usuario prefiere terminar la migración técnica antes de tunear feel.

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.