Discovering peers from Apple TV app

I have an idea for a game where the Apple TV app acts as the host and discovers nearby iOS apps that can join the game. Each iOS app needs to be able to have the user draw, tap, etc and have all the events be delivered in real time to the Apple TV where the effects will be rendered immediately (imagine a co-op game played in your lounge room where guests user their own devices to control aspects of the UI on the shared Apple TV screen)

MPC is discontinued and DeviceDiscoveryUI is limited to only a single iOS device so I’m trying to figure out the best way to do the P2P networking.

Reading/watching videos suggests that using GKMatchMaker and friends seems like it might suffer from latency problems (because everything has to go via Game Centre - or does it?) plus I’m not sure how I’d deal with the fact that the owner of the Apple TV is likely to signed into the same game centre id on both the Apple TV and their own devices to which would mean they wouldnt be able to play because the host can’t invite “themselves” on another device (or can it?)

Soooo… I’m looking for suggestions on how best to move forward. I’ve read https://developer.apple.com/documentation/technotes/tn3151-choosing-the-right-networking-api which is very useful but there’s no clear suggestion that would work.

Using the Network for the real time messaging seems doable but dealing with discovery / invites seems like a massive pain that I’d prefer to use built-in libraries if possible.

Any suggestions would be gladly received. Thanks a lot

Answered by DTS Engineer in 821669022

So, let me actually start here:

Using the Network for the real time messaging seems doable but dealing with discovery / invites seems like a massive pain that I’d prefer to use built-in libraries if possible.

I'm not sure what you're referring to here, as the Network.framework actually handles all of this pretty well. The sample "Building a custom peer-to-peer protocol" actually demonstrates exactly how to build a full p2p game and supports macOS, iOS, watchOS, and tvOS. The tvOS app does use DeviceDiscoveryUI, but I believe that was ONLY done to show how DeviceDiscoveryUI could be integrated with the Network.framework. I've pinged Quinn to double check, but I think the iOS discovery code would work fine on tvOS.

One quick tip here- when starting with a project like this, I would actually leave p2p support turned "off", except for when I was trying to test or validate specific details. In my experience, until your network code is working correctly, the p2p layer just adds an additional layer of unnecessary complexity that gets in the way of forward progress. Indeed, when possible I actually prefer to connect devices over ethernet so that I can focus entirely on the software/connection layer without worrying about the hardware/wifi layer. What I've found here is that most p2p issues that come up in development are either:

  • Software layer problems which the p2p layer has magnified or complicated.

  • "Glitches" in the p2p layer caused by unreasonable scenarios your end users are unlikely to ever run into.

As an example, years ago, I had an issue where extended debugging cycles of connect-> crash, connect-> disconnect-> connect-> crash, connect->..., would eventually cause p2p WiFi to stop connecting, requiring a device reboot. While that was as system bug, the reality is that if any user is having your app crash multiple times a minutes, p2p WiFI not working isn't the main issue.

Covering a few details:

MPC is discontinued

Strictly speaking, this is not correct. The API is not deprecated and should work fine. Having said that, tn3151 has good guidance on it and I wouldn't recommend it for what you're describing.

Reading/watching videos suggests that using GKMatchMaker and friends seems like it might suffer from latency problems (because everything has to go via Game Centre - or does it?)

A few things here:

  • The GKMatch API can basically be thought of as MultipeerConnectivity + remote play. The APIs have a similar design, inherited from a common ancestor.

  • GKMatchMaker will actually do p2p networking using "startBrowsingForNearbyPlayers(handler:)". Using that API, it basically works "the same" as MPC.

On this point here:

(because everything has to go via Game Centre - or does it?)

For remote play, the sequence works something like this:

  1. All clients connect to the server and the server creates "a match" between those clients.

  2. The server sends all clients the connection data for all other clients.

  3. The clients start connecting to each other by both communicating through the server and by directly connecting to each other.

  4. Very shortly after the GKMatch "starts", clients drop their server connections, relying entirely on direct connection.

The VAST majority of connection issues actually come from #4, as it's VERY difficult (basically, impossible*) to establish reliable connections between "everyone" on the internet. Critically, these failures are generally not random, as they're almost always caused by problems with the underlyng network (for example, "double NAT"). They're also not something that an app can easily diagnose or explain to a user.

*Notably, this is the reason the vast majority of "modern" network games rely on a client/server architecture, as that architecture generally works fine even on networks that are pretty badly "broken".

In any case, my summary of all this is that GKMatch can be a great option in an app that "fits" it's gameplay model, as it gives you "reasonable" remote play support for "free".

However, looking at your case:

plus I’m not sure how I’d deal with the fact that the owner of the Apple TV is likely to signed into the same game centre id on both the Apple TV and their own devices to which would mean they wouldnt be able to play because the host can’t invite “themselves” on another device (or can it?)

You probably could get it to work with some experimentation but, no, I don't think it would be worth the effort. You don't need remote play (which is GKMatch's biggest advantage), I suspect you're not interested in using the system's UI, and it sounds like you want a more dynamic and seamless drop in/out experience with Apple TV as the central server. GKMatch (and MPC) would only complicate that.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

So, let me actually start here:

Using the Network for the real time messaging seems doable but dealing with discovery / invites seems like a massive pain that I’d prefer to use built-in libraries if possible.

I'm not sure what you're referring to here, as the Network.framework actually handles all of this pretty well. The sample "Building a custom peer-to-peer protocol" actually demonstrates exactly how to build a full p2p game and supports macOS, iOS, watchOS, and tvOS. The tvOS app does use DeviceDiscoveryUI, but I believe that was ONLY done to show how DeviceDiscoveryUI could be integrated with the Network.framework. I've pinged Quinn to double check, but I think the iOS discovery code would work fine on tvOS.

One quick tip here- when starting with a project like this, I would actually leave p2p support turned "off", except for when I was trying to test or validate specific details. In my experience, until your network code is working correctly, the p2p layer just adds an additional layer of unnecessary complexity that gets in the way of forward progress. Indeed, when possible I actually prefer to connect devices over ethernet so that I can focus entirely on the software/connection layer without worrying about the hardware/wifi layer. What I've found here is that most p2p issues that come up in development are either:

  • Software layer problems which the p2p layer has magnified or complicated.

  • "Glitches" in the p2p layer caused by unreasonable scenarios your end users are unlikely to ever run into.

As an example, years ago, I had an issue where extended debugging cycles of connect-> crash, connect-> disconnect-> connect-> crash, connect->..., would eventually cause p2p WiFi to stop connecting, requiring a device reboot. While that was as system bug, the reality is that if any user is having your app crash multiple times a minutes, p2p WiFI not working isn't the main issue.

Covering a few details:

MPC is discontinued

Strictly speaking, this is not correct. The API is not deprecated and should work fine. Having said that, tn3151 has good guidance on it and I wouldn't recommend it for what you're describing.

Reading/watching videos suggests that using GKMatchMaker and friends seems like it might suffer from latency problems (because everything has to go via Game Centre - or does it?)

A few things here:

  • The GKMatch API can basically be thought of as MultipeerConnectivity + remote play. The APIs have a similar design, inherited from a common ancestor.

  • GKMatchMaker will actually do p2p networking using "startBrowsingForNearbyPlayers(handler:)". Using that API, it basically works "the same" as MPC.

On this point here:

(because everything has to go via Game Centre - or does it?)

For remote play, the sequence works something like this:

  1. All clients connect to the server and the server creates "a match" between those clients.

  2. The server sends all clients the connection data for all other clients.

  3. The clients start connecting to each other by both communicating through the server and by directly connecting to each other.

  4. Very shortly after the GKMatch "starts", clients drop their server connections, relying entirely on direct connection.

The VAST majority of connection issues actually come from #4, as it's VERY difficult (basically, impossible*) to establish reliable connections between "everyone" on the internet. Critically, these failures are generally not random, as they're almost always caused by problems with the underlyng network (for example, "double NAT"). They're also not something that an app can easily diagnose or explain to a user.

*Notably, this is the reason the vast majority of "modern" network games rely on a client/server architecture, as that architecture generally works fine even on networks that are pretty badly "broken".

In any case, my summary of all this is that GKMatch can be a great option in an app that "fits" it's gameplay model, as it gives you "reasonable" remote play support for "free".

However, looking at your case:

plus I’m not sure how I’d deal with the fact that the owner of the Apple TV is likely to signed into the same game centre id on both the Apple TV and their own devices to which would mean they wouldnt be able to play because the host can’t invite “themselves” on another device (or can it?)

You probably could get it to work with some experimentation but, no, I don't think it would be worth the effort. You don't need remote play (which is GKMatch's biggest advantage), I suspect you're not interested in using the system's UI, and it sounds like you want a more dynamic and seamless drop in/out experience with Apple TV as the central server. GKMatch (and MPC) would only complicate that.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thank you for your amazingly detailed reply.

TBH, I've never really kept up with the advances in the Network framework (all my day-to-day dev work so far has been invoking standard REST APIs using URLSession), so I kinda assumed it was just a newer version of CFNetwork which seemed pretty low level for my needs.

After watching the videos you linked me too and had a look through the sample project, it very much seems like I can get a loooong way with the Network framework - stuff like the protocol framing looks really neat and relevant.

I'll definition be starting there for some of my early prototyping. Thanks so much.

One quick sidebar:

... as it's VERY difficult (basically, impossible*) to establish reliable connections between "everyone" on the internet

The good news for me is that fully remote connections is actually an anti-goal for my game... my idea here is actually that this game is designed around the idea that players are physically co-located in the same room... which should remove (hopefully) a lot of the technical networking hurdles.

Thanks again

Thank you for your amazingly detailed reply.

You're welcome.

...so I kinda assumed it was just a newer version of CFNetwork which seemed pretty low level for my needs.

That's actually a somewhat accurate description, in that it is intended to provide a better networking API than raw sockets. However, as part of properly "replacing" CFNetwork we also:

  • Integrated bonjour support into connection API (instead of using "side" APIs like NSNetService).

  • Implemented NWPathMonitor, which both replaced and expanded SCNetworkReachability, as well as providing a level of connection route control which was previously quite difficult.

  • Expanded the area of API support to provide a common set of building blocks (like protocol framing) for higher level APIs to build on.

  • Shifted to the user space network stack to improve overall performance.

In other words, Network.framework goal isn't simply to replace CFNetwork (which it does) but is actually to provide the "base" API layer for the entire network layer (not just sockets).

Related to that point:

After watching the videos you linked me too and had a look through the sample project, it very much seems like I can get a loooong way with the Network framework - stuff like the protocol framing looks really neat and relevant.

In general, the Network.framework is intended to be "complete", meaning it provides access to the "full" capabilities the network system provides. SO, for example, anything an API like MPC or NSURLSession "does" should also be possible since, ideally*, those APIs WERE written using Network.framework.

*Many of our APIs still use BSD sockets but that's because of the difficulty and risk involved in rewriting existing frameworks, not because they couldn't be written using Network.framework.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Discovering peers from Apple TV app
 
 
Q