Galeria y Persistencia - vykymoon/rpg-character-creator GitHub Wiki

Galería (GalleryController · gallery.fxml)

Es la pantalla inicial (la abre MainApp). Lista los personajes guardados y reúne todas las acciones.

Botón Método Qué hace
Jugar ▶ onPlay Abre el modo un jugador con el personaje seleccionado
Multijugador LAN onPlayMultiplayer Cierra el menú y abre GameApp (LAN)
Iniciar Servidor onStartServer Arranca el servidor LAN en un hilo aparte
Ver detalle onViewDetail Ventana modal sin decoración con la ficha completa y sonido (open_detail.wav)
Eliminar onDelete Pide confirmación y borra por id
Refrescar onRefresh Vuelve a leer la lista
Clonar plantilla onCloneTemplate Abre la pantalla de plantillas NPC
+ Crear nuevo personaje onCreateNew Inicia el wizard

Si no hay personaje seleccionado, las acciones que lo necesitan muestran el aviso "Selecciona un personaje de la lista primero."

Cada fila de la lista muestra el avatar de la raza (48 px), el nombre y un subtítulo; si la lista está vacía aparece "Aún no tienes personajes. ¡Crea el primero!".

Persistencia (dao/)

Interfaz

public interface CharacterDAO {
    void save(Character character);
    Optional<Character> findById(String id);
    List<Character> findAll();
    void delete(String id);
    boolean existsByName(String name);
}

Implementación JSON (CharacterDAOJson)

  • Archivo: src/main/resources/data/characters.json, ruta relativa al directorio de trabajo (Paths.get("src","main","resources","data","characters.json")).
  • Se crea automáticamente ([]) si no existe, junto con sus carpetas.
  • Formato: arreglo JSON, con Gson en modo pretty printing, UTF-8.
  • Estrategia: cada operación lee todo el archivo y, si modifica, lo reescribe completo.
    • save: elimina cualquier personaje con el mismo id y agrega el nuevo (funciona como crear o reemplazar).
    • delete: filtra por id y reescribe.
    • existsByName: compara trim() + minúsculas.
  • Los errores de E/S se convierten en RuntimeException con la ruta afectada.
  • Se puede pasar otra ruta con el constructor CharacterDAOJson(Path).

Forma de un personaje guardado

{
  "id": "b7c1…-uuid",
  "name": "Aria",
  "race":           { "id": "elfo", "name": "Elfo", "baseStrength": 3, "…": "…" },
  "characterClass": { "id": "mago", "name": "Mago", "bonusIntelligence": 6, "…": "…" },
  "skills":  [ { "id": "bola_de_fuego", "name": "Bola de Fuego", "manaCost": 15, "…": "…" } ],
  "outfits": [ { "id": "robe_mage", "name": "Túnica de Mago", "slot": "armadura", "…": "…" } ],
  "strength": 3, "dexterity": 9, "intelligence": 12, "vitality": 5
}

Se guardan copias completas de raza, clase, habilidades y vestuario (no solo ids).

Clonación de plantillas NPC (Prototype)

Pantalla TemplateGalleryController · template_gallery.fxml:

  1. Muestra las plantillas de CharacterPrototype.withDefaultTemplates() como "Nombre (Raza / Clase)".
  2. El usuario elige una y escribe un nombre nuevo.
  3. Valida: plantilla elegida, nombre no vacío y nombre no duplicado.
  4. prototype.clone(key) → setName → characterDAO.save. El clon recibe un id nuevo, por lo que es un personaje independiente.
  5. Vuelve a la galería.

Cambiar el motor de persistencia

Para usar SQLite u otro almacén:

  1. Crear CharacterDAOSqlite implements CharacterDAO.
  2. Sustituir new CharacterDAOJson() por la nueva clase en GalleryController, Step5SummaryController y TemplateGalleryController.

No hay que tocar CharacterBuilder ni las pantallas.

Ojo con la ruta relativa

Como characters.json depende del directorio de trabajo y vive en src/main/resources, no funciona como recurso dentro de un .jar empaquetado. Es válido para desarrollo con mvn javafx:run; para distribución habría que moverlo a una carpeta de usuario (por ejemplo ~/.rpg-creator/).

⚠️ **GitHub.com Fallback** ⚠️