Listing Client Relayed Multiplayer Matches w/ Labels and Passwords

Before reading, please note that CRM stands for Client Relayed Multiplayer

Hello, I’m developing a game with Godot and Nakama SDK. I’m aiming to create a similar game to Haxball, so it’s a very simple game and it fits well with P2P ( the original game does what I want to with WebRTC P2P )

I’m using the Client Relayed Multiplayer system and was wondering if its possible to add passwords and labels to these type of matches.

Making a bit of research in our forum I discovered this isn’t possible with CRM. So I wanted to know from you guys what would be the best approach for implementing this system without having to give up on the Client Relayed method. ( My goal is to make a p2p game at first. )

I was thinking on creating another server to store matches and their details ( Label, Password, MatchId ) using some type of database like Redis. So, through requests within Godot and my custom server, I would let the player create his room normally with the CRM model, then, the match id will be sent to my custom server, there I’ll make proper validations and set the player’s room with its details in my Redis DB.

Afterwards, another player will make one request to my server, searching for rooms, I’ll list all rooms labels and the match id so the player can join ( if theres not a password set. if theres one, the player will need to send a valid password in order to receive the match id to join it through the CRM )

What I want to know is:

  1. Is my current approach valid? Will it work?
  2. Is there a feature in Nakama that already does what I’m aiming for? ( BESIDE AUTHORITATIVE MP )
  3. Any other suggestion? Any other approaches?

Versions: Nakama 3, Linux & Docker, Godot 4 SDK

Hello @Suero, I think this approach works, but you do not need a separate server for these things, you can just use Nakama’s custom RPCs and the Storage Engine.

Have a look at our project template to see how to use these features.

Hope this helps.

1 Like

Hello, sorry for reviving this old post, but is it possible to create an match with nakama server runtime but like if it was client relayed and store its informations (such as pass, name, max players) somewhere?

I want to create a Lobbies system, where ppl can define password, lobby name and lobby size, but my game is p2p so I need it to be client relayed at the moment.

The problem is that apparently I have to set alot of things to an Server authoritative match work like a Client Relayed one, for example, when I create the room with my custom RPC I don’t receive the host match presence, which I was receiving automatically while creating using socket.create_match_async ( client relayed function )

Also, is it possible to use send_match_state_async functions normally in a server authoritative and broadcast these states to all players?

Hello @Suero, we have a guide on how to create a lobby system with authoritative matches.

For relayed, have a look at I want to create an match with password and no one cant join without password.

There’s a problem, which is that I can’t pass more arguments when using the join match function in Nakama Godot SDK, also, I think the example is still for authoritative matches as the match has metadata.

Metadata is supported for relayed matched so this must be a limitation in the Godot SDK, please consider opening an issue in its repository.

1 Like

Apparently, I can pass metadata to join a match, but not to create a new one, are you still sure I can attach metadata to create an relayed match?

Also, the link about creating relayed matches w/ password you sent don’t teach how to create this match, so I would need to create it through hooks on the runtime. and I think that when you create a match using Nakama Typescript Runtime, you can only create server authoritative methods with the nk.createMatch function, which doesn’t seems to support creation for relayed matches (?)

# Create a multiplayer match on the server.
# @param p_name - Optional name to use when creating the match.
# Returns a task to represent the asynchronous operation.
func create_match_async(p_name : String = ''):
    return await _send_async(NakamaRTMessage.MatchCreate.new(p_name), NakamaRTAPI.Match).completed
# Join a multiplayer match by ID.
# @param p_match_id - The ID of the match to attempt to join.
# @param p_metadata - An optional set of key-value metadata pairs to be passed to the match handler.
# Returns a task which resolves to a multiplayer match.
func join_match_async(p_match_id : String, p_metadata = null):
    var msg := NakamaRTMessage.MatchJoin.new()
    msg.match_id = p_match_id
    msg.metadata = p_metadata
    return await _send_async(msg, NakamaRTAPI.Match).completed

anyways, I created the issue.

Apologies @Suero, I wrongly assumed metadata was missing as a param in the Godot SDK for MatchJoin.

If match create is called from the server side runtime, then the match will be authoritative, if it’s called from the client it’ll be relayed.

Let me clarify - you can set up password protected relayed matches as follows:

After you create the relayed match (named relayed matches should work best), create a storage object where you store a hash of the match password. You can use the name or id of the match as the key.

Have the users joining the match through Match Join set the name (or id) and password in the metadata of the request. Have a before hook (as described in the linked thread) on match join that checks the hash of the incoming password against the storage object and only allows join if there’s a match.

Don’t forget to remove these storage entries once they’re no longer relevant.

I will close the issue as the API is correctly implemented in the SDK, I apologize again for the misunderstanding.

Hope this helps.

Hello, thanks for answering.

I only see this working if the password is randomly set or something like that, I need a way to the user to pass his own password and name of the match ( The already existing name for matches doesn’t work to me, as it’s more like an alternative id to the room than a real match name. ) .

Actually, I could use the random password form with no problems, but, I want my rooms to have more metadata such as name, match size (2v2,4v4,etc.), lobby host.

I don’t see a way to have these metadata with relayed matches on a simple way with the current methodology, so, I think using Server Authoritative matches but adapting them to work as P2P is enough and goes to my objective more effectively, no?

You could use storage objects + storage search, but yes, ultimately authoritative matches are the better choice. you can have almost no logic in the match handlers and just forward messages to all parties. If you want an example of a simple match handler, have a look at our project template.

1 Like