Lobby service questions

I’ve read over the Lobbies docs, and it has some features I want to add, but I’m not sure I can get the exact result I’m looking for based on what it says, so heres what I imagine and what I’m curious about.

Our game is going to support cloud rooms but also I just added peer-to-peer (p2p) support with help of this thread: Peer to peer with IP? and will also eventually want to support Steam Relay as well.

The idea is that p2p could always be the default option to keep costs minimal and scale into using cloud rooms relative to demand.

So really based on the docs, I feel like we might want 2 matchmaking services: 1 for cloud and 1 for p2p

We also already essentially have a "Lobby” state as you describe inside of our game rooms to start that helps players get the game started. Coherence has more features for that, so we could transition to using coherence’s lobby state rather than using our own over time, but the less friction at the start, the better.

To start, it’d be nice if the Lobby state could essentially just be a pass through to the game state and be able to close the game from the game state. It seems like using the coherence Lobby, the lobby must be closed to go to Game state.

The last thing is the docs mention that simulators are not supported for lobbies. We will definitely use simulators in our game.

Based on all of this, my questions are:

  • Is it possible to have 2 matchmaking services with their own lobbies, 1 for coherence cloud and 1 for p2p? Or possibly this could be done with a single service and some lobbies are marked as cloud and others are p2p and filtered/viewed based off of that?
  • Can Lobby step essentially be skipped and give the lobby-type controls (like closing/starting game) to be handled in Game state instead of Lobby?
  • Even though simulators cannot be used in Lobby api, does that have any effect on the way a room already is working; in that, currently our rooms have simulator auto connect when room is created? Would this be disrupted?

I’m also curious in the case any of these things above are not supported if there are any plans to support them in the future?

Thanks for your feedback

Hey, yes what you’re describing is possible and we have a few customers doing it this way. To clear some things up - lobbies can remain open even if the room they are associated with is closed. Lobbies are just a primitive we provide and you can really do anything you want with them.

For instance, Vampire Survivors uses our cloud lobbies API but dynamically matchmakes across p2p, console and steam. Lobbies support metadata at the lobby and player level, so you using that metadata you can coordinate however you’d like. You can update the lobby with information necessary to connect peer to peer and then the game client can go make that connection - never touching our cloud rooms.

So, to summarize - lobbies are not tied to rooms or any other environment within coherence. We provide conveniences since they are often used together, but lobbies can be completely self-contained. If you did not need real-time sync you could even create a complete game that “syncs” over lobby metadata.

To clarify about simulators - what we mean is that simulators themselves cannot interact with our lobbies as simulators are not considered “players” in our backend even though they are technically game clients. You can still use lobbies to match make and coordinate games that use simulators.

1 Like

Thank you for clearing that up.

I really just wasn’t sure what sort of integration assumptions makes about coherence because one of the things it says immediately on the docs for requirements is “To use Lobbies, you must have at least one Region enabled in the Project Settings section of your Online Dashboard.” But I guess this is just for saying where the lobby server will be located?

Also, since lobbies is part of the CoherenceBridge.CloudService.CloudRooms package, there is an implication that lobbies might be integrated with cloud rooms closely.

But, it sounds like by your description, lobbies is really just an added quality of life that you can add on top of whatever your network setup is with not a lot of assumption about how you might use them, in which case, it sounds like it will work for what we want as well.

Yes, you’re right - and good points about the SDK namespacing. I’ll bring this up with the SDK team

I’m working my way through this, and I am running into something I don’t understand.

It seems like the way the lobbies should work is a user will create a room, get the RoomData associated with it, then use that RoomData to create a lobby with CreateLobbyOptions.ForRoom(RoomData) thus creating a lobby associated with that room.

The problem is if I use the LobbySession to get that room data and join the room, the data is not there. There is no RoomData in the LobbySession, so I’m not sure how the room is supposed to be joined given that coherence uses RoomData.LoadEndpointFromData to join rooms.

I even looked in CreateLobbyOptions.ForRoom method itself and when passing in RoomData, it only seems to track room name, region, and sim slug. The ip to connect to is nowhere to be found, which seems like an issue to me.

I also tried to use lobby owner action StartGameSession with no callback to see if that would cause the room/RS to be auto-joined since this is what I understood the docs as saying this is the default way it works, but this did not work. Lobbies | coherence Documentation

I might be missing something, but from what I can see, the LobbySession does not have RoomData even when using CreateLobbyOptions.ForRoom and passing in RoomData.

Let me know if you can see something wrong with my approach here.

public static void CreateLobby(RoomData roomData)
{
    var lobbyOptions = CreateLobbyOptions.ForRoom(roomData, roomData.RoomName);

    instance.CloudLogin.Services.Lobbies.CreateLobby(lobbyOptions, OnLobbiesCreated);
}

//
public static void OnLobbiesCreated(RequestResponse<LobbySession> response)
{
    //
    if (response.Status != RequestStatus.Success)
    {
        Debug.LogWarning($"Lobby creation failed: {response.Exception.Message}");
        return;
    }

    instance.session = response.Result;
    instance.ownerSession = instance.session.LobbyOwnerActions;

    // instance.session.LobbyData.RoomData is NULL here

    instance.ownerSession.StartGameSession(OnGameSessionStarted);

    GetLobbies();
}

Hey, yes this is a misunderstanding and one we can be better about in our documentation. CreateLobbyOptions.ForRoom does not connect the lobby to the room in any way. Instead it’s just a convenience method to prefill the lobby options with the same options from the room.

I’d suggest starting with a lobby and then using that lobby to start a room using the StartGameSession convenience method.

Alternatively you can store the RoomData as json in the lobby metdata and use the normal Room APIs to have players in the lobby join the room.

We’re having discussion internally on how we can better identify that Lobbies are not tied to Rooms and clear up misunderstandings like this. Not your fault - we can do better at signalling the use cases.

The reason I was not getting a connection to the room is because I did not have the bridge set to Main account. I saw in the docs now that this is required for the auto-connection to happen, so that is at least a solution for that.

However, that does bring up more questions.

With this automatic connection being made, it seems more like we’re really just passing in a name and region, cloud is making a room, and then RoomData can be received from LobbyService.OnPlaySessionStarted event.

When I do a callback for this event, the RoomData parameter is as I’d expect, but when I look into LobbyService.RoomData for same lobby, it still is null. I would expect that this value would be the same value as in the callback parameter. That just seems intuitive to me.

Regardless though, the docs talk about how to join room if you join the lobby after the game session has already started in this way

        if (lobbySession.LobbyData.RoomData is { } room && CoherenceBridgeStore.TryGetBridge(gameObject.scene, out var bridge))
        {
            // The Lobby has an ongoing Game Session, so we reconnect to the Room using the CoherenceBridge
            bridge.JoinRoom(room);
        }

I’m failing to see when lobbySession.LobbyData.RoomData will ever be anything but null for this to even be possible to use bridge to join.

The other part of this is that if the auto-connect part of this is really only looking at region and then creating a room in that region and passing back the data, then it doesn’t seem like it can be used for P2P. There is no way I can see that you can pass RoomData, and thus IP, for a locally created RS.

You did suggest just adding the RoomData as lobby metadata, which before I started working on this I was already expecting to be how I’d end up doing it, but when I saw CreateLobbyOptions.ForRoom I thought “Oh perfect, they already thought of this”, but as you say, it doesn’t really work like that.

For now, I will end up using this metadata solution because it works for both P2P and cloud, which is what we want.

Since you’re talking about it internally, I’ll just give my 2 cents as someone who has used coherence a while now.

I am very familiar with using RoomData when creating, joining, fetching rooms. If we’re creating a lobby for a room, there should be a RoomData available at all times at least after LobbyService.OnPlaySessionStarted is invoked. It seems to be implied that this should be happening by the docs, but I can’t see when LobbyService.RoomData is ever not null.

For our actual case, it would be useful to use CreateLobbyOptions.ForRoom and if RoomData has an actual host/IP, it can be assumed lobby does not need to create room and anyone in lobby will have access to the same RoomData that’s passed in. If RoomData has no host/IP, then it could automatically create in cloud. This would support P2P without having to use metadata.

Yeah, looking more closely I think this is a bug that doesn’t set the room data on the lobby correctly. I’ve brought this up with teh SDK team to look into it

1 Like

Running into another issue here.

When I do use LobbyOwnerSession.StartGameSession to create the room, there is no automatic simulator connection like there is when I create the room directly.

Is there something I have to do to get this to work? I tried entering the simulator slug as the simPayload parameter in StartGameSession, but this didn’t resolve the issue.

EDIT (adding another issue):

I’m able to add attributes to a lobby just fine. I can see them in the developer portal as well, which is nice.

However, when I do FindLobbies and get back the LobbyData, they never have any attributes, so I can’t use the lobby metadata as we discussed above.

I even tried using RefreshLobby to see if that’d help, but the attributes always come back with count 0.

Let me investigate - what is your project ID? I’ll look at the logs to see what might have happened

projectID: cevgfrdbo1hlhbllpep0

room 4369152 is an example of a room that was created by lobby, but no sim was created.

Can you share how you’re creating the lobby? There’s a SimulatorSlug option on the CreateLobbyOptions- are you setting that to your slug?

1 Like

so this helped and now it works by changing SimulatorSlug directly

Do you have any thoughts on what might be causing the attributes in the lobby to not show with FindLobbies?

instance.ownerSession.AddOrUpdateLobbyAttributes(new List<CloudAttribute>() { new("ip", instance.createdRoomData.Host.Ip) }, null);

I can see this attribute added from the dev portal, but not when using LobbiesService.FindLobbies

Ah, attributes are private by default - you can set isPublic to true to have them available to other players CloudAttribute

1 Like

perfect, thank you :grin:

This is kind of a bug report, but is also how I fixed it and is related to all of this, so I put it here.

It seems like now LobbyData.RoomData will show if room is autocreated with LobbyOwnerSession.StartGameSession (maybe this was fixed internally since we talked about it?)

I tried using the method suggested in docs to join room

    if (lobbySession.LobbyData.RoomData is { } room && CoherenceBridgeStore.TryGetBridge(gameObject.scene, out var bridge))        
{          
// The Lobby has an ongoing Game Session, so we reconnect to the Room using the CoherenceBridge
            bridge.JoinRoom(room);        
}

However, the LobbyData.RoomData seems to be missing authToken and the connection is never made when running above code.

To fix this, I used RoomData from LobbyService.OnPlaySessionStarted event to add authToken as a lobby attribute. When someone wants to join, they can use LobbyData.RoomData and add the authToken provided from the lobby attribute, then bridge.JoinRoom works; which verifies it’s the missing authToken that’s preventing the connection.