Regicide empezó como mi proyecto final de Programación: un juego de cartas en JavaFX, hecho en cuatro días, con las partidas en JSON y las estadísticas en CSV. Solo funcionaba en mi ordenador. Ahora está en la web, en regicide.leosoftware.dev, con un servidor que lleva la partida, cuentas de usuario, clasificación y versión en español e inglés.
La partida vive en el servidor
Las reglas están en Spring Boot. El navegador muestra el estado y envía la jugada; el servidor la valida, la resuelve y devuelve el estado nuevo. El navegador nunca conoce el orden del mazo, así que no se puede hacer trampa desde él.
Cada turno es una máquina de estados con tres fases: atacar, defenderse y fin de partida. Atacas con una carta o con varias del mismo número; si el enemigo sobrevive, te defiendes descartando hasta cubrir su daño. Los enemigos son las figuras de la baraja, y ganas al vaciar el castillo.
Los palos tienen poderes
Los corazones recuperan cartas del descarte, los tréboles doblan el daño, los diamantes roban y las picas bajan el ataque del enemigo, salvo si el enemigo es del mismo palo, así que cada ataque obliga a pensar. Dos comodines permiten cambiar la mano entera.
Jugadas en tiempo real por WebSocket
Las jugadas van por WebSocket con STOMP: la conexión queda abierta y el estado nuevo llega al momento, solo a quien lo pidió. El login y la clasificación son una API REST.
Cuentas y despliegue propio
Se puede jugar como invitado o con cuenta. Con cuenta, la partida se guarda en cada jugada y se retoma desde cualquier dispositivo. Las contraseñas van con Argon2id y se comprueban contra filtraciones conocidas, y los tokens JWT se invalidan al cerrar sesión. El esquema de PostgreSQL cambia solo con migraciones de Flyway. Todo corre con Docker Compose en una máquina de Oracle Cloud, con Caddy para el HTTPS.
Lo que aprendí: decidir qué hace cada parte
En JavaFX todo vivía en el mismo programa. Al pasarlo a la web tuve que decidir qué hace el servidor, qué hace el navegador y dónde se guarda cada cosa. Los tests juegan partidas enteras con semilla fija contra el servidor arrancado, y gracias a eso pude cambiar cada parte sin romper las demás.
