Multiplayer games are very popular with customers for nearly 40 years now since the first multiplayer games emerged. This is also perceivable in the App Store, there are hundreds of multiplayer games and some of them are really appreciated.
In iOS Apple gives us multiple possibilities to implement a multiplayer game. We will have a further look into two Frameworks we can use to achieve our goal. The first one is the Game Center and the second the MultipeerConnectivity Framework.
To follow the code examples in this tutorial you will need Xcode 5 and iOS 7.
https://www1.in.tum.de/lehrstuhl_1/teaching/tutorials/508-sgd-ws13-tutorial-multiplayer-games
1. Multiplayer Games Magnus Jahnensgd-ws13
Multiplayer Games
with iOS
Seminar Games Development (WS13/14)
04.10.2013
Session 14
“Tell me and I will forget.
Show me and I will remember.
Involve me and I will understand.
Step back and I will act.”
1
2. Multiplayer Games Magnus Jahnensgd-ws13
Multiplayer Games with iOS
• Introduction
• Game Center
• MultipeerConnectivity
• Motivation
• Overview
• Realtime multiplayer (SpaceInvaders)
• With Game Center
• With MultipeerConnectivity
• Summary and tips
• Helpful links
• References
2
3. Multiplayer Games Magnus Jahnensgd-ws13
Introduction - Game Center
• Social Gaming Network developed by Apple
• Makes third party frameworks like OpenFeint obsolete
• Available in iOS 4.1 (2010) and OS X 10.8 (2012)
• Features:
• Leaderboards
• Achievements
• Challenges
3
4. Multiplayer Games Magnus Jahnensgd-ws13
Introduction - Game Center
4
Real Time Multiplayer
Doodle Jump Real Racing 3
5. Multiplayer Games Magnus Jahnensgd-ws13
Introduction - Game Center
5
Turn Based Multiplayer
CarcassonneWord Rally
6. Multiplayer Games Magnus Jahnensgd-ws13
Introduction - MultipeerConnectivity
• Framework to communicate between nearby devices
• Introduced in iOS 7 (not available on OS X)
• Replaces facilities to communicate with nearby devices
in GameKit Framework
• Features:
• Discovering and exchanging data between nearby devices
• Message, stream based data and resources such as files
6
7. Multiplayer Games Magnus Jahnensgd-ws13
Motivation
• Multiplayer games obviously are fun
• Can fascinate players even if the storyline is over
• Real interaction with other players and social
interaction are more appreciated than just with a
computer
• Both Frameworks have a really easy to use API and
a high level user interface
7
8. Multiplayer Games Magnus Jahnensgd-ws13
Network layer
• Layer 4 or Transport layer (OSI model)
8
TCP
• Connection oriented
• Stream based data
• Reliable
• Higher overhead than UDP
• Slower transmission speed than
UDP
UDP
• Connection less
• Package based data
• Unreliable
• Very low overhead
• Very high transmission speed
9. Multiplayer Games Magnus Jahnensgd-ws13
Network Guidelines
• Handle network disruptions
• Send packages at lowest frequency
• Network updates are not needed 30 times per second!
• Use smallest package size possible
• Send data only to the players who need it
9
10. Multiplayer Games Magnus Jahnensgd-ws13
What we will do now
• Adapt the SpaceInvaders Tutorial
• To a real time multiplayer game
• Supporting two players
10
Player One
Player Two
11. Multiplayer Games Magnus Jahnensgd-ws13
Overview
11
1 1
MultiPeerCommunicationGameCenterCommunication
CommunicationStrategy
«protocol»
+findMatch()
+sendData(NSData *)
+disconnect()
MultiPlayerHelper
+sharedInstance()
+findMatch()
12. Multiplayer Games Magnus Jahnensgd-ws13
Before we start
• Debug builds use the Game Center Sandbox
environment
• Use eduroam network
• Use 3.5 inch iPhone Simulator (32bit)
• TODOs are marked with warnings
12
18. Multiplayer Games Magnus Jahnensgd-ws13
Exercise: TODO 1
• Init a GKMatchRequest and set
the properties minPlayers and
maxPlayers
• Init a
GKMatchmakerViewController
using initWithMatchRequest
• Set the matchmakerDelegate
property to self
• Present the ViewController via
[Helper presentViewController:]
• Time: 7 minutes
18
GKMatchRequest
GKMatchmaker
ViewController
19. Multiplayer Games Magnus Jahnensgd-ws13
Solution: TODO 1
19
- (void)findMatch {
NSLog(@"Searching a match ...");
#warning TODO 1a initialize a GKMatchRequest and set the maxPlayers and minPlayers
properties
GKMatchRequest *matchRequest = [[GKMatchRequest alloc] init];
matchRequest.maxPlayers = 2;
matchRequest.minPlayers = 2;
#warning TODO 1b present the ViewController
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]
initWithMatchRequest:matchRequest];
mmvc.matchmakerDelegate = self;
[Helper presentViewController:mmvc];
}
GameCenterCommunication.m
21. Multiplayer Games Magnus Jahnensgd-ws13
Running the game
• You should see the ViewController
• When you click cancel or play, you should see the
appropriate Messages in the console output
• You will not be able to play though!
21
2013-09-23 16:06:13.240 SpaceInvadersTutorial[1101:a0b] Searching a match ...
2013-09-23 16:06:15.768 SpaceInvadersTutorial[1101:a0b] matchmaking cancelled
2013-09-23 16:06:15.991 SpaceInvadersTutorial[1101:a0b] User clicked cancel!
2013-09-23 17:42:41.353 SpaceInvadersTutorial[4601:a0b] Searching a match ...
2013-09-23 17:43:29.832 SpaceInvadersTutorial[4601:a0b] found match!
2013-09-23 17:43:29.860 SpaceInvadersTutorial[4601:a0b] Looking up 1 players
23. Multiplayer Games Magnus Jahnensgd-ws13
Sending data
• Send data by calling sendData from class GKMatch
• Takes NSData which is just an array of bytes
• Data can be sent reliable or unreliable
• Remember the networking guidelines mentioned
before
• Small package size
• Lowest frequency
• Network topologies
• etc.
23
24. Multiplayer Games Magnus Jahnensgd-ws13
Sending Reliable (TCP)
• Guaranteed delivery
• No out of order packets
➡ Easy to use
• But may be slower!
➡ For infrequent messages which need to reach their
destination!
24
25. Multiplayer Games Magnus Jahnensgd-ws13
Sending Unreliable (UDP)
• Faster than reliable
• No guaranteed delivery
• Maybe out of order packets
➡ For real time updates (e.g. position updates)
25
26. Multiplayer Games Magnus Jahnensgd-ws13
Exercise: TODO 2
26
• Implement the method sendEnemySpawned in
MultiPlayerHelper.m
• Use [self getRelativePosition:] to get a relative position to
screen
• Init a EnemySpawnedMessage and send it via
[self sendMessage:]
• Time: 5 minutes
@interface EnemySpawnedMessage : Message
...
- (id)initWithEnemyIndex:(NSUInteger)index atPosition:(CGPoint)position;
...
@end
Hint:
27. Multiplayer Games Magnus Jahnensgd-ws13
Solution: TODO 2
27
MultiPlayerHelper.m
- (void)sendEnemySpawned:(int)enemyIndex atPosition:(CGPoint)position {
#warning TODO 2 send when an enemy/alien spawned
CGPoint relativePosition = [self getRelativePosition:position];
EnemySpawnedMessage *message = [[EnemySpawnedMessage alloc]
initWithEnemyIndex:enemyIndex atPosition:relativePosition];
[self sendMessage:message];
}
28. Multiplayer Games Magnus Jahnensgd-ws13
Exercise: TODO 3
28
• Implement the method parseEnemySpawned in MultiPlayerHelper.m
• Use [self getAbsolutePosition:] to get an absolute position to
screen
• Use the property self.networkDelegate to notify the Game Scene
• Time: 5 minutes
@interface EnemySpawnedMessage : Message
@property NSUInteger enemyIndex;
@property CGPoint position;
...
@end
@protocol NetworkDelegate
...
- (void)enemySpawned:(int)enemyIndex atPosition:
(CGPoint)position;
...
@end
Hints:
29. Multiplayer Games Magnus Jahnensgd-ws13
Solution: TODO 3
29
MultiPlayerHelper.m
- (void)parseEnemySpawnedMessage:(EnemySpawnedMessage *)message {
#warning TODO 3 parse the enemy message
CGPoint absolutePosition = [self getAbsolutePosition:message.position];
[self.networkDelegate enemySpawned:message.enemyIndex
atPosition:absolutePosition];
}
30. Multiplayer Games Magnus Jahnensgd-ws13
Whats missing?
• Player Position updates
➡ Good example where unreliable packages are useful
30
31. Multiplayer Games Magnus Jahnensgd-ws13
How to deal with the Problems
• Lost packages
➡ Just ignore them
• Out of order packages
➡ Just use the most recent received information
• These solutions apply for most scenarios!
31
32. Multiplayer Games Magnus Jahnensgd-ws13
Problem: Out of Order Packages
• Include a message counter in the position update
message
• Compare it with the message count we expect next
➡ Bigger or equal → Valid
➡ Otherwise we just drop the package
32
33. Multiplayer Games Magnus Jahnensgd-ws13
Exercise: TODO 4
33
MultiPlayerHelper.m
- (void)sendPlayerPosition:(CGPoint)position {
#warning TODO 4 send the player position unreliable
self.outgoingCounter++;
CGPoint relativePosition = [self getRelativePosition:position];
PlayerPositionUpdateMessage *message = [[PlayerPositionUpdateMessage alloc]
initWithPosition:relativePosition andMessageCount:self.outgoingCounter];
[self sendMessageUnreliable:message];
}
34. Multiplayer Games Magnus Jahnensgd-ws13
Exercise: TODO 5
34
MultiPlayerHelper.m
- (void)parsePlayerPositionUpdateMessage:(PlayerPositionUpdateMessage *)message {
#warning TODO 5 parse the position update message
// sorry, but out of order -> just ignore
if(self.incomingCounter >= message.messageCount) {
NSLog(@"received out of order position update!");
return;
}
CGPoint absolutePosition = [self getAbsolutePosition:message.playerPosition];
self.incomingCounter = message.messageCount;
[self.networkDelegate playerPositionChanged:absolutePosition];
}
40. Multiplayer Games Magnus Jahnensgd-ws13
Bonjour
• Apples implementation of Zeroconf networking
• Used to find available services in a network using
multicast
‣ Identified via the service type
• Used for example in iTunes or to easily find network
printers
40
41. Multiplayer Games Magnus Jahnensgd-ws13
Presenting the UI
41
Passive
via Advertiser
Active
via ViewController
42. Multiplayer Games Magnus Jahnensgd-ws13
Change the Strategy!
42
#warning TODO change the strategy
[MultiPlayerHelper sharedInstance].communicationStrategy = [[GameCenterCommunication
alloc] init];
ViewController.m
Change
To
[MultiPlayerHelper sharedInstance].communicationStrategy = [[MultiPeerCommunication alloc]
initWithPlayerName:@"Your Name"];
43. Multiplayer Games Magnus Jahnensgd-ws13
Exercise: TODO 6
• Init a MCPeerID with self.playerName
• Init a MCSession (property) with the peer ID
• Do not forget to set the delegate!
• Init a MCAdvertiserAssistant (property) with
service type „space“, „nil“ as discovery Info
and the session
• Then start the Advertiser
• Time: 7 minutes
43
MCPeerID
MCSession
MCAdvertiser
Assistant
44. Multiplayer Games Magnus Jahnensgd-ws13
Solution: TODO 6
44
- (void)setupSession {
#warning TODO 6 setup up the MultipeerConnectivity Session
MCPeerID *peer = [[MCPeerID alloc] initWithDisplayName:self.playerName];
self.session = [[MCSession alloc] initWithPeer:peer];
self.session.delegate = self;
self.advertiserAssistant = [[MCAdvertiserAssistant alloc]
initWithServiceType:@"space" discoveryInfo:nil session:self.session];
[self.advertiserAssistant start];
}
MultiPeerCommunication.m
45. Multiplayer Games Magnus Jahnensgd-ws13
Exercise: TODO 7
• First stop the Advertiser!
• Init a MCBrowserViewController with
Service Type „space“ and the
property session
• Do not forget to set the delegate and
maximum and minimum number of
peers
• Present the ViewController via
[Helper presentViewController:]
• Time: 7 minutes
45
MCPeerID
MCSession
MCBrowserView
Controller
46. Multiplayer Games Magnus Jahnensgd-ws13
Solution: TODO 7
46
- (void)findMatch {
#warning TODO 7 find a match/other peers using MultipeerConnectivity
[self.advertiserAssistant stop];
MCBrowserViewController *viewController = [[MCBrowserViewController alloc]
initWithServiceType:@"space" session:self.session];
viewController.delegate = self;
viewController.maximumNumberOfPeers = 2;
viewController.minimumNumberOfPeers = 2;
[Helper presentViewController:viewController];
}
MultiPeerCommunication.m
48. Multiplayer Games Magnus Jahnensgd-ws13
Summary
• You are now able to build a multiplayer game!
Congratulations!
• You know why Game Center and
MultipeerConnectivity are useful
• You know how you can find matches (other players)
with the standard View Controllers
• You know how to send and receive data over a
GKMatch or MCSession
• You know where you should pay attention at when
designing a multiplayer real time game
48
49. Multiplayer Games Magnus Jahnensgd-ws13
‣ Let the user decide
49
Game Center
• Server infrastructure supplied
by Apple
• Wide community
• Available on iOS and OS X
• More features available like
leaderboards or voice chat
• Dependent on Apple Servers
• No nearby players
MultipeerConnectivity
• No server needed
• Different communication Methods
(Bluetooth and Wifi)
• Seems to work better and faster
• Only nearby devices
• Available only on iOS
• Not optimized for gaming
50. Multiplayer Games Magnus Jahnensgd-ws13
Some tips
• Use my strategy pattern
• Enable Game Center/MultipeerConnectivity in the
Xcode project
• Register your app Bundle ID in iTunes Connect
• Check if the sandbox is online
• https://sandbox.itunes.apple.com/verifyReceipt
50
51. Multiplayer Games Magnus Jahnensgd-ws13
Helpful links
• Official Apple Game Center Guide
• https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/
GameKit_Guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008304-CH1-
SW1
• How to Make a simple multiplayer game by Ray Wenderlich
• http://www.raywenderlich.com/3276/how-to-make-a-simple-multiplayer-game-with-
game-center-tutorial-part-12
• Nearby Networking with MultipeerConnectivity (Video)
• https://developer.apple.com/wwdc/videos/index.php?id=708
• About Multipeer Connectivity by Apple
• https://developer.apple.com/library/ios/documentation/MultipeerConnectivity/
Reference/MultipeerConnectivityFramework/Introduction/Introduction.html
• Snap (card game by Ray Wenderlich)
• GameKit API deprecated, but good example how to exchange packages!
• http://www.raywenderlich.com/12735
51