Gestión de sesiones de juego

Un servicio de sesión centralizado que es dueño del ciclo de vida de cada partida — estado, tiempo transcurrido e identidad — para que ningún subsistema tenga que duplicarlo.

Para qué sirve este sistema

Todos los juegos tienen una partida. Empieza, puede pausarse y reanudarse, y termina en fallo o en éxito. El problema es que cada subsistema que necesita saber algo sobre ese ciclo de vida — el HUD, el contador de puntuación, el sistema de checkpoints, el controlador de música — tiende a rastrearlo por su cuenta con sus propios booleanos y variables de temporizador.

Game Session en Serenity es el único lugar donde vive el ciclo de vida de una partida. Mantiene el GameSessionStatus actual, el tiempo transcurrido y un GameSessionId estable, y expone un GameSessionSnapshot inmutable para cualquier sistema que necesite leer ese estado sin modificarlo.

El problema en Unity

En un proyecto Unity sin un agregado de sesión, la pregunta '¿está la partida activa en este momento?' se responde de forma diferente en cada sistema. El HUD comprueba un flag estático. El temporizador comprueba si Update está ejecutándose. El sistema de checkpoints comprueba un booleano de escena. Pueden desincronizarse. Una pausa desde un sistema no detiene el temporizador en otro. El tiempo transcurrido se acumula durante la carga porque nadie es dueño del inicio y el fin.

El problema de fondo es que no existe una identidad canónica de partida. Reiniciar una partida implica localizar cada sistema que almacenó algo y notificarlo individualmente. Añadir un nuevo sistema que necesita el estado de sesión significa decidir de nuevo de dónde leerlo.

Cómo lo aborda Serenity

IGameSessionService centraliza esa coordinación. Expone Status, ElapsedTime y SessionId como propiedades de solo lectura y dirige las transiciones mediante métodos explícitos: StartSession, Pause, Resume, GameOver y Complete. El enum GameSessionStatus captura cada estado válido — NotStarted, Playing, Paused, GameOver y Completed — para que la lógica de transición sea inequívoca.

GetSnapshot devuelve un GameSessionSnapshot: un struct inmutable de solo lectura que contiene la identidad de sesión, el estado actual, el tiempo transcurrido y un snapshot de puntuación en ese momento. El HUD, la interfaz y cualquier otro consumidor de solo lectura llaman a GetSnapshot y obtienen una imagen coherente de la partida sin tocar estado mutable.

Cómo encaja en Serenity

Game Session vive en el namespace Serenity.GameSession y sigue la estructura por capas de la foundation. La capa de Dominio define el enum GameSessionStatus, el value object GameSessionId, la entidad GameSessionState y el value object GameSessionSnapshot. La capa de Aplicación expone IGameSessionService. La capa de Instalación proporciona GameSessionInstaller, que conecta el servicio con la pipeline de inicialización junto con una dependencia ITimerService para el seguimiento del tiempo transcurrido.

Game Session coopera con el agregado Timer a través de ConfigureTimer: el servicio toma la propiedad del ciclo de vida del temporizador — inicializar, iniciar, pausar, reanudar, detener — para que el temporizador refleje siempre el estado de sesión con exactitud. También coopera con Score (el snapshot incluye un ScoreSnapshot), con Checkpoint para la integración de puntos de guardado, con Game Mode para el contexto y con el Event Dispatcher para publicar señales de ciclo de vida a los subsistemas interesados.

Flujo de trabajo práctico

  1. Extiende GameSessionInstaller en tu proyecto para crear y registrar la implementación de IGameSessionService.
  2. Llama a ConfigureTimer antes de StartSession para asignarle a la sesión su temporizador de tiempo transcurrido.
  3. Llama a StartSession con un GameSessionId — usa GameSessionId.NewGuid() para identidades generadas automáticamente.
  4. Dirige las transiciones mediante los métodos del servicio: Pause, Resume, GameOver o Complete según dicten las reglas del juego.
  5. Llama a Tick en cada frame para que la sesión avance el temporizador mientras el estado sea Playing.
  6. Lee el estado de sesión desde cualquier subsistema mediante GetSnapshot — el GameSessionSnapshot devuelto es un struct inmutable seguro para pasar a cualquier parte.

Qué incluye

  • Interfaz de servicio de sesión IGameSessionService con las propiedades Status, ElapsedTime y SessionId
  • Métodos de ciclo de vida explícitos StartSession, Pause, Resume, GameOver y Complete
  • Enum GameSessionStatus que cubre NotStarted, Playing, Paused, GameOver y Completed
  • Modelo de lectura inmutable GameSessionSnapshot con identidad, estado, tiempo transcurrido y puntuación
  • Value object GameSessionId con generación automática mediante NewGuid y semántica de igualdad estable
  • Propiedad del temporizador mediante ConfigureTimer — el servicio inicia, pausa y detiene el temporizador automáticamente
  • Clase base GameSessionInstaller para conectar el servicio con la pipeline de inicialización
  • Cooperación con Score, Checkpoint, Game Mode y el Event Dispatcher a través de interfaces compartidas

Cuándo usarlo

  • Proyectos donde varios sistemas mantienen su propia versión de 'la partida está activa' y acaban desincronizados.
  • Juegos que necesitan un tiempo transcurrido fiable que se pause y reanude con la sesión en lugar de ejecutarse de forma continua.
  • Bases de código que quieren una identidad de sesión estable para que reiniciar una partida signifique crear una nueva sesión, no localizar estado almacenado en caché.
  • Cualquier proyecto donde el HUD o la interfaz necesiten un snapshot coherente e inmutable del estado de sesión sin acoplarse a los internos mutables.

Sistemas relacionados

Usa Serenity cuando quieras un único lugar que sea dueño de la partida — para que pausarla, reanudarla y terminarla se propague automáticamente a cada sistema que lee de la sesión, en lugar de requerir actualizaciones manuales coordinadas.

Volver a la página principal