How to create a Unique Lobby Room Name

Hi I’m new to Nakama, I would like to ask how to have a Unique Lobby Room Name in Nakama wherein if it’s created with that name, other players wouldn’t be able to create a room with that name. I already tried using CreateMatchAsync and it seems that you can create matches with same matchName that are not unique.

I was thinking to make an authorative or rpc for create match and send the name as payload and use nk.MatchList to check whether there is a match with that name so it wouldn’t create it but i’m concern if using or calling nk.MatchList always to create room with unique name will affect signafically the performance as it need to always filter a room name. I was thinking also using StorageWrite to save the room name and query it to check if it exist already but I’m not sure what approach is better.

I want to have a unique name so a player can have a choice to just input the room name in a text field on a the client side to join a match since MatchID are very long to be inputted also.
Any suggestion how to do this properly?

Hi thanks for the response, I was wondering if using nk.MatchList and just filtering the label would be much better option like this:

func RpcCreateRoomTest(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
	logger.Debug("RpcCreateRoom Called")

	limit := 1
	authoritative := true
	label := ""
	minSize := 1
	maxSize := 4
	query := "+label.isPrivate:false +label.roomName:Heroes"

	if matches, err := nk.MatchList(ctx, limit, authoritative, label, &minSize, &maxSize, query); err != nil {
		logger.WithField("err", err).Error("Match list error.")
		return "", err
	} else {
		if len(matches) > 0 {
			logger.Info("Can't create room with roomName Heroes")
		} else {
			// Create Room withm roomName Heroes
			isPrivate := false

			var data map[string]interface{}
			if payload != "" {
				if err := json.Unmarshal([]byte(payload), &data); err != nil {
					logger.Error("error unmarshaling payload: %v", err)
					return "", err
				}
			}

			if val, ok := data["isPrivate"]; ok {
				isPrivate = val.(bool)
			}

			params := map[string]interface{}{
				"isPrivate": isPrivate,
				"roomName":  "Heroes",
			}

			matchId, err := nk.MatchCreate(ctx, "LobbyMatch", params)
			if err != nil {
				logger.Error("Failed to create a room: %v", err)
				return "", err
			}

			response := map[string]interface{}{
				"matchId": matchId,
			}

			bytes, err := json.Marshal(response)
			if err != nil {
				logger.Error("error marshaling response: %v", err)
				return "", err
			}

			return string(bytes), nil
		}
	}
	return "", nil
}

Hello @Shuin,

Using the label as you are is the simpler and perfectly valid approach. I doubt you’ll ever run into performance issues.

1 Like