Skip to content

Typical Lobby Workflow

Logan McNaughton edited this page Dec 28, 2024 · 5 revisions

Room Creation

  • A player sends a request_create_room message to the server.
  • The server replies with reply_create_room with the details about the room, and whether it was successful or not. If it was not successful the accept field will be non-zero and the message field will say why.
  • Once the room creation has succeeded, the player is moved into a "waiting room" for the game.

Joining a room

  • A player sends a request_get_rooms message to the server.
  • The server replies with a reply_get_rooms message. The message contains a list of existing rooms (a room will only show up if the game has not yet started, players can't join an in-progress game).
  • The frontend would display these rooms for the user, showing the room name, game name, etc.. allowing the user to select one of them.
  • When the user selects one, they are prompted to load their ROM.
  • The user would send a request_join_room message.
  • The server would reply with a reply_join_room message. If the accept field is 0, it was successful, otherwise, an error occurred. The message field will say what the error is.
  • If the join was successful, the player is moved into a "waiting room" for the game.

Waiting room

  • Frontend sends a request_motd message. Server replies with reply_motd, and the MOTD message is displayed somewhere for the players.
  • Frontend sends a request_players message. Server replies with reply_players, which contains the name of each player. reply_players is also sent automatically when someone leaves the room.
  • Players can send a request_chat_message. Server will reply to all players with a reply_chat_message, which the frontend would display.
  • Player 1 is able to send a request_begin_game message (no one else should be able to send this). Server will reply to all players with a reply_begin_game message, which signals everyone to close the wait room and start the emulator core.

Starting the game

Before running M64CMD_EXECUTE, the frontend needs to do the following:

if ((*CoreDoCommand)(M64CMD_NETPLAY_INIT, netplay_port, netplay_ip) == M64ERR_SUCCESS)
    DebugMessage(M64MSG_INFO, "Netplay: init success");
else
    // handle error
uint32_t reg_id = netplay_player_number;
if ((*CoreDoCommand)(M64CMD_NETPLAY_CONTROL_PLAYER, netplay_player_number, &reg_id) == M64ERR_SUCCESS)
    DebugMessage(M64MSG_INFO, "Netplay: registered for player %d", netplay_player_number);
else
    // handle error

The netplay_player_number can be determined by the list of players in the reply_players message. This message returns the name of each player, and which slot they belong in, for example:

[0] = "john"
[1] = "doe"
[2] = ""
[3] = ""

If this player is "doe", then netplay_player_number would be "2" (M64CMD_NETPLAY_CONTROL_PLAYER expects a number from 1-4).

After M64CMD_EXECUTE completes, you should run (*CoreDoCommand)(M64CMD_NETPLAY_CLOSE, 0, NULL);

A note on WebSockets

The WebSocket used to initiate the connection to the server must remain open and in use for the entire flow. For example, when a player creates a room, the same WebSocket is used while they are in the waiting room. The WebSocket can be closed once the game begins.