Asynchronous game creation - leave a game in the lobby

Hey guys. Is it possible to create a game asynchronously? I want player "cat" to be able to create a game, send a first turn, close the app. Some time later, I want player "dog" to join any existing game, find the game "cat" created, and continue that game.

Using the sandbox demo, it seems both players need to be online at the same time, so they can see the same game in their lobby, join it and then from there it's visible in their Saved Games. This is not really Asynchronous play, as initiation needs to be done concurrently.

Did I miss something in the docs? How can I have a game created by "cat" persist in the lobby for some time after it's created but left by that player?


  • There is a Typed Lobby that kind-of supports your case.
    You can create rooms in a lobby with LobbyType.AsyncRandomLobby. That lobby won't list rooms (at all) but keeps rooms for random matchmaking, even when the last/only player inside is inactive.
    You need to find games either by name or by OpJoinRandomRoom(..., asyncTypedLobby, ...).

    Hope that helps.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi Tobias,

    I thought LobbyTypes are depecrecated/obsolete and we should only use the TypedLobby.Default as in the Memory game and Sandbox demos.

    How long does Rooms created in an AsyncRandomLobby persist after all players left or became inactive. Is it related to the RoomOptions.EmptyRoomTtl field ? If sol please can you tell me what's the max value limit in milliseconds ?

    What effect does not sending list of games to the other LoadBalancingPeer operations other than the one you mentioned (OpJoinRandomRoom(..., asyncTypedLobby, ...)) ?

    The OpJoinRandomRoom overload method in LoadBalancingPeer that accepts TypedLobby expect it to have a ! How to handle that manually ?
  • The lobby types are not obsolete. They are still needed, because they define how a lobby behaves (default, allowing sql-like filtering and "async").
    Initially, most methods had 2 parameters for the lobby: string lobbyName and LobbyType lobbyType. Now, there is a TypedLobby class and you should use that. It combined name and type of a lobby into one value, which is a lot cleaner and easier to handle.
    So the methods with the 2 parameters are obsolete but TypedLobby is not. And TypedLobby.Default is just the default lobby with no name and type "default".

    The time before a room gets removed from the async lobby is fixed to 1 hour. It's not affected by EmptyRoomTtl. We weren't sure yet which requirements real games will have, so we had to pick a value or fear flooding of the lobby.

    > What effect does not sending list of games to the other LoadBalancingPeer operations other than the one you mentioned (OpJoinRandomRoom(..., asyncTypedLobby, ...)) ?
    There is no other effect. You can still join the lobby but it won't give you the list of rooms. This type of lobby should be used with OpJoinRandomRoom. Of course, you can still join any room by name (with invitations). can be anything you make it. Use some constant name like "async" or so. Otherwise, you can forget about it.
  • Thanks Tobias. That seems to work, just wondering what best practice is?
    Do I need to always create rooms in this AsyncRandomLobby lobby? And therefore always try and join a game in that lobby if the player is just asking for a random match?

    > There is a Typed Lobby that kind-of supports your case.
    Kind of? Is there anything else sensible I need to watch out for?
  • >> There is a Typed Lobby that kind-of supports your case.
    > Kind of? Is there anything else sensible I need to watch out for?

    Sorry. This must be confusing from your point of view. I used the "kind of", because that lobby never provides the list of rooms available. So you can't show a list and let a user select a (random) room. Of course, the player can select something like "map", if you want to allow them some filtering for OpJoinRandomRoom()...

    If you want rooms to stay available for random matchmaking after the (only) player becomes inactive, then yes, you need to use the AsyncRandomLobby. You can use one or multiple of those - as you need. The other types of lobbies will however not keep rooms without active player.
  • Thanks again. I *think* I should be ok with the Random thing, I just want people to be able to start a game and then have someone randomly pick it up later. I might introduce some filtering based on a simple level system later on. It's a simple game, similar to Letterpress, so it's just important that games are available. Also, if games can't move from the Random Lobby to the normal one, a game that has been started will NEVER be visible in ANY lobby, right?

    Ideally, I'd like for users to be able to browse available games, maybe with some info of how good the opponent is. At the moment, I can only start a game with a random unknown person, and given that those rooms aren't visible anywhere, I'm always starting a game without knowing who it's with. I guess I can ALSO show rooms in the online lobby, but then two people need to be online at the same time, and that kinda defeats the whole purpose of async play, imho.

    The other feature I don't quite understand (maybe because there's no demo of it) is how friends might work. I'd like to start a game, then have my friends *easily* join it. That is, I don't really want them having to type in a unique room name that they would have to SMS/mail to each other.

    Is there a friends list? Can I hook up to FB and issue a challenge? Out the box with minimal hassle?

    Sorry for all the questions! Didn't see anything in the docs or forums about this stuff yet. thanks.,
  • JohnTube
    JohnTube ✭✭✭✭✭

    I'm having the same requirement : creating games with friends. I'm sorry to tell you that there is no ootb solution and the "minimal hassle" does not exist in all cases. my approach is the following : OpCreateRoom() and force the visibility to false in the RoomOptions so that no other player can join it "randomly". Save the RoomName (game id) and send it to your friend and he can call OpJoinRoom() with that RoomName then close it.

    You need other services like PlayFab that provide "friends system". One more thing : the players do not need to know anything about the inner working of the game like the game id, it must be transparent and handled internally like saving/caching invitations/challenges (the Ids of the games started with friends) in the cloud.
  • That's what I was suspecting. It's not really a complete solution for my needs then, friends lists, rooms that are persistent for more than 1 hour (that's kinda useless, most games early on will die in the ether) are an absolute basic requirement for this kind of thing. TurnBased without this feels very incomplete.

    Looks like I'll be looking for an alternative. Thanks guys.
  • Amir: You worry that at the low CCU at release won't find matches? What timing would be OK for you when you say 1 hour is too short?
    I think I said so in a mail: This 1h setting is arbitrary. We can change it but need your input.

    To have accounts and friends, you would use FB or PlayFab or some other middleware. PlayFab not only allows you to have friends, afaik it also enables you to use push notifications to invite them easily. That means you don't have to manually type a room name. You just use a suitable messaging system and send the invite to a friend.

    Friend invites are not limited by the lobby's (current) 1h limit for idle games.

    Photon is really focusing on the networking and communication. There is no way we can re-implement community features, payment, push notifications and whatnot to your likes. We think it's even better to not try to re-implement the wheel. Many developers are quite happy to re-use FB, PlayFab, Game Center or even their own community.
  • JohnTube
    JohnTube ✭✭✭✭✭
    After reading this relatively old topic, I just want to check if EmptyRoomTTL has no use with AyncRandomLobby ! I mean it's useless in this case.
  • No - it still can makes sense.

    You can see "EmptyRoomTTL" as way to manage how often your service should be called to save the state.

    0 or low values mean your service will be called very often (as often as it ends up without active players)
    higher values decrease the likelihood of your service being called. (only if room is without active players for the EmptyRoomTTL time)
  • JohnTube
    JohnTube ✭✭✭✭✭
    I got it (@Philip : I'm just leaving an ack. as I read your answer the day you post it).

    - EmptyRoomTTL ==> when all players left / became inactive the Photon server will wait "EmptyRoomTTL" time THEN triggers the GameClose webhook (if configured) and deletes the Room instance from memory.
    - LobbyType.AsyncRandomLobby ==> will keep the "NotFull" (ActorCounter < MaxPlayers) and Open and Visible Rooms available for [random] matchmaking 1Hour after all players left / became inactive.