Communication between matches?

We are evaluating Nakama for a new project. One of the key features is the ability to have players in a large social space, then move to mini-games. When in a mini-game, they do not interact with anyone outside that match. But players still in the social space might see some of their actions within the mini-game. You saw this feature in games like Toontown, or Wizard 101, where the minigames played out in the social space geometry, but each mini-game was standalone, restarted its state, and excluded other players from interfering.

So the question is, how we might achieve this in Nakama. From what I’ve seen, the idea might be to use authoritative matches, and have match_loop in a mini-game do two things: 1) send updates to all joined players, 2) send a copy of (some) updates to the social space “match” so spectators can see movement and visual effects (but not interfere).

To accomplish this, the mini-game loop would need to insert messages into the social space match. I assume it is possible to find the social space match (it is a singleton, so we could store a reference to it somewhere). But is there a way to insert messages that are not being sent from a client? There are two ways to do that a) send directly to the “presences” in the social space. This might be disallowed, because we are in the mini-game loop, not the social space loop. So there is no dispatcher to use. b) send to the match somehow so that those messages are then picked up in the next social space loop, where they could be broadcast to players in the social space.

Is any of this possible? Is there a different/better way to approach this?

@DarrinWest These are great questions. How large is the social space for players in the game? Is this somewhere that all players in the game can receive events/realtime messages from and push messages to (with whatever gameplay they contain)?

From what I’ve seen, the idea might be to use authoritative matches, and have match_loop in a mini-game do two things: 1) send updates to all joined players, 2) send a copy of (some) updates to the social space “match” so spectators can see movement and visual effects (but not interfere).

This approach works well if the game design of your multiplayer mini-games includes “spectator mode” in some way. It fits well because most of the messages that’ll flow through the match will be observed by all (though you can restrict who you send messages to from within the match handler and from game clients).

Is any of this possible? Is there a different/better way to approach this?

A second way to approach the problem is to use our streams API to create a stream for the “social space” and have players join and leave that as they want to observe events in that space. Match handlers could also broadcast straight to that stream.

https://heroiclabs.com/docs/advanced-streams/

This gives you maximum flexibility to create the rules around the social space and what messages are distributed to all players subscribed to the stream. Would this fit the requirements for your game design?

The social space might be quite large, and would need to support all concurrently connected users. Yes, players would interact in realtime there, see each others’ movement and actions. It would be more efficient if we broke that space into areas of interest using some kind of interest management. That would prevent clients from being overwhelmed by the volume of updates from far away players. It looks like Streams could be used for this as well. I’m assuming that Streams are efficient enough for positional updates, and are not limited to just chat-level volumes.

I’m a big fan of pub/sub semantics for distributed systems, so I can see how Streams could be used to implement that and solve several problems at once:

  1. partitioning of the large social space for message delivery efficiency
  2. allowing data from various mini-games to reach nearby spectators (without them joining the mini-game match)
  3. possibly also for containing mini-game data, partitioned by match, or by team within match, etc.

I’ll need to read up on the rules of using Streams. E.g. does each consumer receive messages in the same order?

Thanks for your quick reply, btw.

1 Like

@DarrinWest It has been on my mind for a while to write a small Go library that uses Nakama streams to implement interest management. I agree it’s a great fit for the use case. We use streams in Nakama to power realtime multiplayer, chat, status events, in-app notifications, etc.

I’ll need to read up on the rules of using Streams. E.g. does each consumer receive messages in the same order?

Yes, messages dispatched onto the stream will be observed in order by game clients unless WebRTC or rUDP is used and the message is marked as unreliable in which case it may not be observed at all (best effort) or observed out of sequence. (These constraints are not guaranteed if you create your own goroutine pools to dispatch messages from onto streams but in these cases I’d assume the concurrency is expected.)

Happy to help. :slight_smile:

Is there documentation on the current availability of those options? From what I can tell from the Unity library it seems only to do Websockets currently (or I’m missing a flag someplace I need to enable…)

I can see the unreliable flag for broadcasting and some older discussions on rUDP on Gitter and whatnot, but it seems like maybe it was removed?

Is there documentation on the current availability of those options?
…
I can see the unreliable flag for broadcasting and some older discussions on rUDP on Gitter and whatnot, but it seems like maybe it was removed?

The documentation has fallen behind a bit. These features are in use with customers that use socket adapters for our SDKs which are not yet open-source. It’s difficult to get good feedback and performance results without collaboration on these features.

In the meantime you can build out against the open-source socket adapter.