Arquitectura General - vykymoon/rpg-character-creator GitHub Wiki

La aplicación tiene dos estilos de organización que conviven, porque el proyecto creció en dos etapas:

  1. Corte 1 (creador de personajes): organización por patrón/función (ui, builder, factory, singleton, prototype, dao, model).
  2. Modo LAN: organización por capas hexagonales (domain, application, adapters).

Vista general

flowchart TB
    subgraph UI["ui/ (JavaFX)"]
        Main[MainApp] --> Gallery[GalleryController]
        Gallery --> Wizard[Step1..Step5 + WizardSession]
        Gallery --> Template[TemplateGalleryController]
        Gallery --> Play[PlayController]
        Gallery --> GameApp[GameApp - LAN]
        Play --> Battle[BattleController]
    end
    subgraph Core["Núcleo del creador"]
        Builder[builder/CharacterBuilder]
        Proto[prototype/CharacterPrototype]
        Catalog[singleton/CatalogManager]
        Factories[factory/*Factory]
        Model[model/*]
        DAO[dao/CharacterDAO]
    end
    subgraph Game["game/ (un jugador)"]
        GPlayer[Player, GameMap, InputHandler, Command]
    end
    subgraph LAN["LAN (hexagonal)"]
        Adapters[adapters/server + client]
        App[application/GameSessionService]
        Domain[domain/GameMap, MovementRules, PlayerState]
    end
    Wizard --> Builder --> Model
    Wizard --> Catalog --> Factories --> JSON[(data/*.json)]
    Gallery --> DAO --> Chars[(characters.json)]
    Template --> Proto
    Play --> GPlayer
    GameApp -->|WebSocket| Adapters --> App --> Domain
    GameApp -.lee.-> Chars

Paquetes (com.proyecto.rpg)

Paquete Responsabilidad
ui Controladores JavaFX, navegación entre pantallas, carga de sprites, MainApp y GameApp
model Entidades del dominio del creador: Character, Race, CharacterClass, Skill, Outfit y la regla CatalogRestriction
builder CharacterBuilder: construcción paso a paso y validación
prototype CharacterPrototype: plantillas de NPC clonables
singleton CatalogManager: catálogo cacheado en memoria
factory Factories que convierten los JSON del catálogo en objetos del modelo
dao Persistencia: interfaz CharacterDAO e implementación JSON
game Modo un jugador: movimiento continuo, comandos, zona de encuentro
domain (LAN) Mapa por celdas, reglas de movimiento, estado de jugador
application (LAN) GameSessionService, fuente de verdad del servidor
adapters (LAN) Servidor y cliente WebSocket

Nota: hay dos clases llamadas GameMap. game.GameMap (modo un jugador) trabaja con píxeles (double); domain.GameMap (LAN) trabaja con celdas (int) y terreno. No comparten código.

Flujo de datos principal

  1. CatalogManager (Singleton) carga los 4 catálogos JSON mediante las Factories.
  2. El wizard lee el catálogo, filtra según raza/clase y acumula las elecciones en WizardSession.
  3. Al confirmar, CharacterBuilder valida y construye el Character, y CharacterDAO lo guarda en characters.json.
  4. La galería lee los personajes con el DAO y permite verlos, eliminarlos, clonarlos o jugarlos.
  5. Jugar abre el modo un jugador con el Character elegido; Multijugador LAN lee characters.json de forma independiente (CharacterLoader) y manda al servidor solo nombre, raza, clase e ítems.

Navegación entre pantallas

SceneNavigator.goTo(stage|event, fxmlPath, controller) carga un FXML, le asigna el controlador ya instanciado (con sus dependencias por constructor) y reemplaza la raíz de la escena. Por eso los controladores no declaran fx:controller en el FXML: se inyectan por código.

Decisiones de arquitectura destacadas

Decisión Motivo
Catálogos en JSON en vez de enum + switch Agregar contenido sin recompilar (principio Abierto/Cerrado)
CharacterDAO como interfaz Poder cambiar JSON por otro motor sin tocar la UI (Inversión de Dependencias)
Un controlador por paso del wizard Responsabilidad única por pantalla
Servidor autoritativo en LAN (ADR-001) Una sola fuente de verdad; los clientes no pueden decidir el estado
WebSocket + JSON Protocolo simple, depurable y sin dependencias pesadas

Más detalle en Patrones de Diseño y SOLID.