“Join a Friend” matchmaker

I am looking to create a “MMO” style game (roughly 500-1000 CCU), but with these users spread out across various servers.

Some details:

  • using Unity.
  • there are “worlds” which are just unity scenes.
  • each unity instance has a different world/scene loaded due to how Unity works.
  • each unity instance will hold 50 min 100 max users.

When you start the game, you go to a default “world”, but from the menu you can also ask to “join a friend”, in which case the you need to get:

  1. The address for the server is on.
  2. The scene that the user is currently in to load the appropriate scene on the client.

How can I get the scene information, is it best to have each player store their current scene or can the matchmaker somehow identify this during a request.

How do I then matchmake myself to a friend who is already in a session?

Hi @keiranlovett welcome :wave:

Some details:

  • using Unity.
  • there are “worlds” which are just unity scenes.
  • each unity instance has a different world/scene loaded due to how Unity works.
  • each unity instance will hold 50 min 100 max users.

This sounds like you want to use a “session-based multiplayer model” with headless Unity instances for your game. This works well for 3D physics intensive games where you can leverage the full physics support in the game engine to handle collisions, ray tracing, etc, etc. You could host with GameLift, Agones, or similar tools for this purpose.

The challenge with this model is you’d want to maintain a manifest of the available shards and how to connect to them. Usually the specifics around how this works depends on the service or tools you use to manage the server fleet. In what ever way you obtain this information you’ll end up with some kind of instance IDs which can be used to “address” the shard.

How do I then matchmake myself to a friend who is already in a session?

You can have the player share the instance ID they’re on as a status update. These can then be subscribed to by users in their friends list. Whenever the player enters an instance they’d update their status with that specific instance ID.

Have a look at status updates and let me know if you’d like me to describe it in more detail: https://heroiclabs.com/docs/social-status/


I could be completely wrong with the approach you want to use because it depends on the specific details of the MMO whether you even need the headless Unity instances or could instead represent “rooms” with the Nakama Authoritative Multiplayer Engine. If you’d like to discuss that approach instead let me know. :slight_smile:

1 Like

Thanks @novabyte,

I’m certainly using headless unity instances for the bulk of networking while Nakama will manage authentication and user messaging.

So far looking at GameLift but no solid decisions made yet. Is there a way for Nakama to store an inventory of shards and other information?

I had missed the user status! This looks like the perfect method for getting instance IDs.

I have hit another hurdle though I can make this a separate question if so, but for now will ask here too.

We want to have the unity headless servers do an authentication check. Is there any way to have a headless instance validate a players account and a metadata value? From my understanding the headless instance would need to also be authenticated with Nakama for any API requests to be triggered.

Is there a way for Nakama to store an inventory of shards and other information?

Sure, you can store that in a local cache on the Nakama node or if you want to persist it (which may not be recommended if you use GameLift) then you can also use a system-owned storage object.

We want to have the unity headless servers do an authentication check. Is there any way to have a headless instance validate a players account and a metadata value? From my understanding the headless instance would need to also be authenticated with Nakama for any API requests to be triggered.

This is a good question. There’s a few different ways to solve this use case:

  1. Have the game client send its session token to the Unity headless instance and you can store that in the datastructure you use for the connected players in the instance. This way you can submit requests to Nakama on behalf of the player as an authenticated user.
  2. You could use server to server (S2S) RPC functions which can be called with the Unity client in your headless instance that executes whatever logic you want to write for the player to any of the APIs in Nakama.
  3. You could generate a JWT token in the same way that Nakama does for the user on the server-side within the headless Unity instance so you can submit the request on behalf of the player. There’s two ways to tackle this approach:
    1. Use a S2S RPC function to call authenticate_token_generate with the right inputs. This will have Nakama construct the JWT token (session) which can then be managed in the headless instance. Have a look at these docs in the function reference: https://heroiclabs.com/docs/runtime-code-function-reference/#authenticate
    2. You could build a JWT token with a C# library and use the same --session.encryption_key as the signing key for the JWT so that Nakama sees it as a valid token. This could be error-prone if we change the token encoding strategy in the future though.

I think I would use a mixture of option (2) and (3.1) to solve the use case. Use a small S2S RPC function to create a session token for the user and then use that from the headless Unity instance for each player to submit scores, update storage objects, etc. This way you don’t worry if the token format changes in the future, you don’t trust the client to send its session token to the server, and you can control the lifetime of the session token used by the headless Unity instance separately to the game client one.

Hope that helps.

1 Like

@novabyte I know this is less in Nakama’s wheelhouse, but we’re a bit confused as to the best approach to take integrating Nakama with AWS GameLift. Heroic Labs has been great help so far!

As this is an online persistent world we’re assuming at minimum there should be one server that Nakama matchmakes players into until a soft cap is met, then spin up and distribute players accordingly between them.

This then gives us a few follow up questions:

A) Would there then be a match for each AWS instance?
B) Can Nakama matchmaker handle a persistent “match” with 100-500 people?
C) It would be best to use Nakamas matchmaker to handle instancing over AWS GameLifts own matchmaker system?

@keiranlovett This is a good question we’ve helped a bunch of studios with the integration between AWS GameLift and Nakama. This includes a couple of games with huge IP that you’ll see in the market this year I’m sure. :grinning_face_with_smiling_eyes:

A) Would there then be a match for each AWS instance?
B) Can Nakama matchmaker handle a persistent “match” with 100-500 people?
C) It would be best to use Nakamas matchmaker to handle instancing over AWS GameLifts own matchmaker system?

I would suggest you’ll probably not want to use the Matchmaker for this coordination between AWS GameLift instances and players because while the Nakama Matchmaker knows about the live matches which run across the cluster of Nakama servers it doesn’t know anything about the instances that are live in GameLift.

While it’s not strictly speaking necessary to achieve the matchmaker placement it can be quite useful with FlexMatch otherwise there’s always a disconnect between the connected players to an AWS instance and the knowledge in the Nakama Matchmaker. There’s workarounds and strategies you can use but its tricky.

What we usually recommend is to use RPC functions in Nakama to drive the search for matches via the AWS FlexMatch service and have the function handle the search criteria, input validation, and whatever cached state you want to maintain in between matchmaking searches. You can also use this approach to drive the creation of new instances (or pre-warm a new instance) in GameLift when the current open-world instance is near to your 500 player count limit.

The combination of Nakama and AWS GameLift together for the coordination of the game world instances that are headless Unity or Unreal engine binaries works very well. Hope that helps.