There have been various other threads which touch on this topic, and many solutions offered - none of which ever actually work, so I figured I'd start again.
The problem, which started occurring on iOS 6, and has become chronic with iOS 8 is that Game Center will spontaneously disconnect players for no apparent reason. In my game I can have 2 to 4 players going and sending data to each other at a pretty good rate of 10-20 packets per second. The game will be running smoothly, and there's no sign of lost or delayed data. Yet all of a sudden one player will suddenly stop receiving or sending data, and then 20 seconds later it will timeout and disconnect from the game. This usually triggers a cascade which causes the remaining players to suddenly disconnect without warning.
In another thread someone thought the problem was caused by Reliable data packets - when one got lost Game Center would disconnect that player. This is not the case. I tried making all my data unreliable and it made no difference. Others have suggested it was caused by having Double NAT enabled on the router - not the case either.
Normally, this problem is sporadic, but in a new game we're working on it happens 100% of the time in a 3 or 4 player match, and occasionally in a 2-player match. It won't happen if all of the devices are in my office on WiFi. However, if I put one device on cellular it will fail every time. Or, if two devices are in the office on WiFi, and the other 2 are across the country on WiFi it'll fail.
Game Center clearly has issues, but this one is absolutely killing me. Has anyone made any progress in figuring out why Game Center will spontaneously lose connections with players even when things appear to be working just fine?
Related
I have a game, working with GameKit and using the Apple Game Center to manage the connection and messages.
When I am testing the software there is no issue with the connection, but once I am playing with another user over the internet the player is very often disconnected suddenly.
I would like to implement a simple method to reconnect the player or avoid to get the disconnected state from Game Center.
I was trying the solutions suggested at several forums and by the iOS documentation too, but all these are operating with sending a re-invite message to the user which is not really a nice solution.
I would like to have something like automatically waiting for the other user at least for 30 seconds or a minute before the game would tell that the player is disconnected finally.
Sometimes the disconnected message is coming very quickly after a normal data message, sent by the game itself, so it is not really clear why this happens.
Could someone has a good solution for this issue?
I am developing a platform game trying to make it as well for multiplayer using the IOS Multipeer connectivity. I am stuck/confused/do not know what is the best way to send messages between peers (mostly like 4 peers in the game). The game style is like fun run and I have 4 hero running and firing each other and stuff like that. The thing is that keeping the positions of the other players is pushing me crazy!!
Sometimes other players are positioned in the wrong position (keeping in mind all devices are with the same screen size). Is that because of the lag of connectivity. How much information I can send per seconds and what is the best way to manage data transferring?
Any idea/thoughts are appreciated.
The throughput of MPC depends mostly upon the connection. What I've seen as the biggest performance problem is when one of the peers has WiFi disabled. This forces MPC to communicate over bluetooth which is incredibly slow. I've seen it run 20x slower than MPC over Wifi.
You don't need to be connected to a WiFi network. Just enable WiFi on all of the devices and iOS will leverage shared WiFi networks or create its own adhoc network.
The second thing you want to ensure is that your peers don't invite each other. You can only have one inviter in your network. When multiple peers invite and accept connections the MPC network become unstable.
Third thing is sendData:(NSData *)data toPeers:(NSArray *)peerIDs withMode:(MCSessionSendDataMode)mode error:(NSError **)error. If you are broadcasting your packets to all peers in the toPeers: array AND mode is MCSessionSendDataReliable then MPC waits until all of the connected peers ACK the message before moving on to the next packet.
UPDATE: I did some testing with my own app and over WiFi and two devices I can put about 100kbps. I'm using an iPhone 6 Plus and an iPhone 5S.
UPDATE 2: Thinking more about your question, there are a couple things to keep in mind with MPC communications:
Do all of your sendData and didReceiveData calls on a background thread and have that thread update your position data in your model. Tell your viewController that updates are available with a delegate method or notification.
Keep your data packets small, but design them so an update received represents the current state of your player. This allows you to miss an update and not be completely out of sync -- "send player 1 moved to (10, 10)" instead of "player 1 moved by (1, -1)"
Number your packets and use MCSessionSendDataUnreliable. If you get a packet with an earlier number than the last one you processed, throw it away. If you follow the second guideline above, you won't need this packet.
If you follow Dan Loughney's suggestions, I think your best bet in debugging is to log the received coordinates from the other players. That should help you identify whether the problem is due to timing issues, misinterpreted data or something else.
I've encountered a pretty large issue and have been trying to find a solution for 2 months now with no luck. I've submitted it as a bug, ( https://bugzilla.xamarin.com/show_bug.cgi?id=4910 ) but was hoping maybe someone here could shed some light on the cause of the problem, or suggest a work-around.
In a nutshell, to encounter the error:
Create a basic .Net socket connection between two devices
Create and initialize a GameKit.GKSession object on a least one device.
What occurs is the transfer of the data on the .NET socket becomes erratic and too slow to be usable. I've performed many tests across different devices (see link below) and it affects all of them (iPad 3 affected the least). I've tested it between an iPhone and a Windows PC and it still occurs. MonoTouch's GameKit code is somehow affecting the Socket code.
As you can see from the spreadsheet, speed drop from a few milliseconds to send 1 MB to several minutes to forever.
As soon as the GameKit.GKSession is set to null, any backedlogged data on the socket flows freely again and the sockets act normally once more.
Sample Windows and iOS/MonoTouch Apps demonstrating problem: https://dl.dropbox.com/u/8617393/SocketBug/SocketBug.zip
Test results across different devices (PDF Spreadsheet):
https://dl.dropbox.com/u/8617393/SocketBug/SocketBugTestResults.pdf
This issue seems so hard even Apple decided to circumvent it: http://developer.apple.com/library/ios/#qa/qa1753/_index.html#//apple_ref/doc/uid/DTS40011315
The revealing sentence is this: "This change was made to reduce interference with Wi-Fi."
To assist with anyone that comes across this problem, the issue only manifests itself when the GKSession.Available is set to true. This is required for the device to be discoverable, but not to maintain a connection. With this in mind, a temporary work-around can be used where the GKSession.Available is only set to true when required, and set to false as soon as the connection has been made.
In my scenario, I have a socket connection to the server on both devices. I use this connection to send a message from device A to device B, asking it to become discoverable via bluetooth for the next 10 seconds. As soon as the message is sent, device A begins looking for device B and connects as soon as it finds it. Once the connection is established (or 10 seconds elapses without a connection), device B turns off discoverability and the socket behaves as normal.
In my circumstances, this is an acceptable (pending no real fix) workaround to the problem.
I am finishing up an update to a 4 player Game Center enabled game and am suddenly having issues with spurious player disconnection messages that I did not have in the previous version. What is more odd is that not all devices connected to the match are receiving the message. One device will think the player is disconnected, but there is still messaging passing from the (supposedly) disconnected player to the other players.
These messages are coming straight from the match instance via match:player:didChangeState: messages so I don't think it would be anything in my code, but it doesn't make much sense. The game can progress for 10+ minutes with no problems and once one errant disconnect comes it, the rest fall out pretty quickly.
I have searched the web with every search term I can think of to see if others have seen this kind of behaviour and it appears that it is unique. It has to be something in my code, but I can't even think of how to get to the bottom of it.
Any help would be GREATLY appreciated,
Cameron
Make sure to call this:
//Finalize
[[GKMatchmaker sharedMatchmaker] finishMatchmakingForMatch:match];
After all players have connected. I was having this problem and it seems to have stopped the spurrious disconnects in my case.
I have the following problem with GKSessions:
Sometimes there is a huge delay when sending data (3-4 seconds sometimes up to 10 seconds) in a client/server application.
If the server sends let's say 10 packets during the delay, those 10 packets are received all at once on the client. The weird thing is that the server still receives packets from the clients during the delay.
This delay seems to be worse in WiFi networks but also happens in bluetooth networks.
Did anyone else encounter such delay spikes when using gamekit?
What could be the source of this issue?
I've been working a lot with gamekit and gksession. I always use the Peer2Peer mode even though some people discourage it. I never experience any kind of delay like the one you describe.
Do you send with GKSendDataReliable or GKSendDataUnreliable? Try switching to the other and see if it changes anything. If you're using GKSendDataReliable then the sending device will wait for a "Received" message from the receiver before sending the next message. This might be the problem.
On your testing devices: Is anything running which might flood the network?
I was testing a multiplayer gamekit based game, and if I had several active devices then suddenly some would stall completely, and I needed to hard reboot (shut down completely and restart) them to make them work again.
If you keep getting in trouble you might want to try a much more low level api: dns-sd https://developer.apple.com/library/mac/#documentation/Networking/Conceptual/dns_discovery_api/Introduction.html
I hope you make it work, good luck!