Skip to content

2. Sessions

Georg Friedrich Schuppe edited this page Feb 14, 2022 · 3 revisions

GGRS mainly operates through one of three sessions; each providing different functionalities:

  • P2PSession: Communicate with other remote sessions; send and receive inputs to synchronize your game between clients. All Clients participating in the game create their own session and connect to each other in a peer-to-peer fashion.
  • SpectatorSession: Uses another P2PSession as a host in order to receive confirmed game inputs without contributing to the game input itself. If you want clients to spectate games, this is the session to use.
  • SyncTestSession: Used mainly for debugging purposes, this session simulates a configurable amount of rollbacks each frame. This is a great way to test if your game updates deterministically. The SyncTestSession will compare checksums between original and resimulated gamestates and raise an error if something went wrong.

GGRSConfig

GGRS is generic over the inputs you provide, the state you save and the address you use to distinguish peers. First, you will need to construct a struct defining all those types.

pub struct GGRSConfig;
impl Config for GGRSConfig {
    type Input = MyInput;                 // Copy + Clone + PartialEq + bytemuck::Pod + bytemuck::Zeroable
    type State = MyState;                 // Clone
    type Address = SocketAddr;            // Clone + PartialEq + Eq + Hash
}

SessionBuilder

For all sessions, you will have to construct them through the SessionBuilder. You can use the builder to construct any session type. When constructing the SessionBuilder with SessionBuilder::new(), all settings are set to default values, but you can change them using the appropriate setters.

let mut sess_build = SessionBuilder::<GGRSConfig>::new()
  .with_num_players(NUM_PLAYERS)
  .with_max_prediction_window(MAX_PREDICTION)
  .with_fps(FPS)?
  .with_input_delay(INPUT_DELAY);
  //... and so forth

P2PSession

A P2PSession communicates with other P2PSessions and P2PSpectatorSessions. They send and receive inputs to synchronize your game between clients. All Clients participating in the game create their own session and connect to each other in a peer-to-peer fashion. You need specify the players participating in the game, exactly as many as you defined through num_players.

let local_port = 7001
let remote_addr: SocketAddr = "127.0.0.1:7002".parse()?;
let socket = UdpNonBlockingSocket::bind_to_port(local_port)?;

let mut sess = SessionBuilder::<GGRSConfig>::new()
  .with_num_players(2)
  .add_player(PlayerType::Local, 0)?
  .add_player(PlayerType::Remote(remote_addr), 1)?
  .start_p2p_session(socket)?;

Optionally, define any spectators you wish to add. The spectator_handle should be greater or equal to num_players.