Create apps that allow players to interact with each other using GameKit.

GameKit Documentation

Posts under GameKit tag

86 Posts
Sort by:
Post not yet marked as solved
9 Replies
1.3k Views
I need to exchange small amounts of data in my app near realtime between users who could be anywhere with only an internet connection. One user is a Leader and needs to send data (just a few bytes) to all Followers - up to 30 - about each second. Then each Follower needs to send data (again, just a few bytes) back to the Leader about each second. The requirement is similar to the example app from last year's WWDC networking part 2 video called TicTacToe, except the users may not be local.I've tried using Game Center but can't get it right. I've been able to achieve most of my objectives with this GameKit implementation:Follower starts:[[GKLocalPlayer localPlayer] registerListener:self]; request = [[GKMatchRequest alloc] init]; request.minPlayers = 2; request.maxPlayers = 2; request.playerAttributes = 0x0000000F; request.playerGroup = groupName; [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request...Leader starts:[[GKLocalPlayer localPlayer] registerListener:self]; request = [[GKMatchRequest alloc] init]; request.minPlayers = 2; request.maxPlayers = 2; request.playerAttributes = 0xFFFFFFF0; request.playerGroup = groupName; [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request...You can update UI with the completion handlers, but don't count on a real match until:- (void)match:(GKMatch *)match player:(GKPlayer *)player didChangeConnectionState:(GKPlayerConnectionState)state { use the match / player combo to note the connection for both leader and follower. Add to array of followers for leader. If Leader, call your Leader starts code again }Send data to either with:[match sendData:encoder.encodedData toPlayers:playerArray dataMode:GKMatchSendData(Un)reliableerror:&error];and receive in:- (void)match:(GKMatch *)match didReceiveData:(NSData *)data forRecipient:(GKPlayer *)recipient fromRemotePlayer:(GKPlayer *)player { // you've got mail from player! } So far, so good. Here's the bad news: depending on network strength, connections disconnect regularly. Even though I've built in dependable reconnect code, it can take up to 15 seconds to reconnect so it really isn't a good "real-time" experience.I'm currently testing with various combinations of data size (sometimes pad it so it's heft may keep the connection) or frequency (sometimes just send a "poke me" message) or tweaking the reliable vs unreliable flag in the send message calls.I can get about 10 followers per leader on a good day, but other times, more than 3 followers cycle between connect, disconnect, reconnect in an unusable fashion.I'm still trying to make usable, but wanted to document my success/failures so far in hopes that I can help many and perhaps get help from a few.Any ideas would be welcomed and any tweaks will be tested and reported.
Posted
by
Post not yet marked as solved
18 Replies
10k Views
Hi everyone, My app was rejected for containing Game Center entitlement, here is what review team respond: Your app contains the Game Center entitlement, but it does not link against the GameKit framework. And they suggest a solution: If you do not intend to use Game Center, please remove the Game Center entitlement. My app does not have Game Center entitlement enabled, but App Identifier do have it enabled by default. The App Identifier was created years ago, and by then the Game Center was enabled mandatory, I can't deselect it since the disable button was grayed out. I thought Apple may has changed this behavior when received rejection, so I tried to disable Game Center again, but after I deselect Game Center for macOS and try to save it on developer portal, it warns me: There is a problem with the request entity Please select at least one configuration for Game Center. Is there anything I missed? Thank you in advance for any possible help. Regards,
Posted
by
Post not yet marked as solved
6 Replies
3.1k Views
Hello! Bare with me here, as there is a lot to explain! I am working on implementing a Game Center high score leaderboard into my game. I have looked around for examples of how to properly implement this code, but have come up short on finding much material. Therefore, I have tried implementing it myself based off information I found on apples documentation. Long story short, I am getting success printed when I update my score, but no scores are actually being posted (or at-least no scores are showing up on the Game Center leaderboard when opened). Before I show the code, one thing I have questioned is the fact that this game is still in development. In AppStoreConnect, the status of the leaderboard is "Not Live". Does this affect scores being posted? Onto the code. I have created a GameCenter class which handles getting the leaderboards and posting scores to a specific leaderboard. I will post the code in whole, and will discuss below what is happening. PLEASE VIEW ATTACHED TEXT TO SEE THE GAMECENTER CLASS! GameCenter class - https://developer.apple.com/forums/content/attachment/0dd6dca8-8131-44c8-b928-77b3578bd970 In a different GameScene, once the game is over, I request to post a new high score to Game Center with this line of code: GameCenter.shared.submitScore(id: GameCenterLeaderboards.HighScore.rawValue) Now onto the logic of my code. For the longest time I struggled to figure out how to submit a score. I figured out that in Xcode 12, they deprecated a lot of functions that previously worked for me. Not is seems that we have to load all leaderboards (or the ones we want). That is the purpose behind the leaderboards private variable in the Game Center class. On the start up of the app, I call authenticate player. Once this callback is reached, I call loadLeaderboards which will load the leaderboards for each string id in an enum that I have elsewhere. Each of these leaderboards will be created as a Leaderboard object, and saved in the private leaderboard array. This is so I have access to these leaderboards later when I want to submit a score. Once the game is over, I am calling submitScore with the leaderboard id I want to post to. Right now, I only have a high score, but in the future I may add a parameter to this with the value so it works for other leaderboards as well. Therefore, no value is passed in since I am pulling from local storage which holds the high score. submitScore will get the leaderboard from the private leaderboard array that has the same id as the one passed in. Once I get the correct leaderboard, I submit a score to that leaderboard. Once the callback is hit, I receive the output "Successfully submitted score to leaderboard". This looks promising, except for the fact that no score is actually posted. At startup, I am calling updatePlayerHighScore, which is not complete - but for the purpose of my point, retrieves the high score of the player from the leaderboard and is printing it out to the console. It is printing out (0), meaning that no score was posted. The last thing I have questions about is the context when submitting a score. According to the documentation, this seems to just be metadata that GameCenter does not care about, but rather something the developer can use. Therefore, I think I can cross this off as causing the problem. I believe I implemented this correctly, but for some reason, nothing is posting to the leaderboard. This was ALOT, but I wanted to make sure I got all my thoughts down. Any help on why this is NOT posting would be awesome! Thanks so much! Mark
Posted
by
Post not yet marked as solved
5 Replies
3.0k Views
Prior to iOS 14.5, I adopted the following workflow for my Game Center enabled game - At the launch, if there is no authenticated GKLocalPlayer, then store the viewController passed in the completion handler and display it later to the user (i.e. not immediately after the app completes launching). I am using the following code for the authentication process -         GKLocalPlayer.local.authenticateHandler = {viewController, error in             if (viewController != nil){ //store the viewController and present it at a later time             } else if (GKLocalPlayer.local.isAuthenticated) { //successfully authenticated             } else { // player could not be authenticated             } Since iOS 14.5 the callback to the authenticationHandler seems to have changed. The login prompt is displayed automatically after app launch, if there is no authenticated player. I checked - the completionHandler is not even being called in this case before the login prompt is presented. If there is already an authenticated player on the device, then the handler is called as expected. How can I prevent the login prompt from being displayed automatically by the system? Is there a new workflow for authenticating a player from iOS 14.5 onwards? thanks,
Posted
by
Post not yet marked as solved
3 Replies
847 Views
Is it possible to set an achievement progress to numbers like 0.5% or 50.1%? The fact that achievement progress is reported via a double suggests that it should be possible, but when I try doing it only the integer part seems to be saved.
Posted
by
Post not yet marked as solved
4 Replies
2k Views
I built the Gamekit Sample in apple/unityplugins for iOS and ran "_localPlayer = await GKLocalPlayer.Authenticate();" It worked fine up to the point where the GameCenter popup was displayed. However, the "OnRealtimeMatchmake()" and "OnToggleAccessPoint()" will result in the following error "MissingMethodException: Default constructor not found for type Apple.GameKit.Multiplayer.GKMatchRequest at System.RuntimeType.CreateInstanceMono" and "MissingMethodException: Default constructor not found for type Apple.GameKit.GKAccessPoint at System.RuntimeType.CreateInstanceMono" errors and does not work properly. Please tell me what is the problem here. The environment is as follows iPhone SE (iOS15.5), Unity2020.3.33f1, XCode13.4.1
Posted
by
Post not yet marked as solved
6 Replies
1.8k Views
public async void FetchItems() { try { var fetchItemsResponse = await GKLocalPlayer.Local.FetchItems(); } catch(GameKitException exception) { Debug.LogError(exception); } } App hangs when calling GKLocalPlayer.Local.FetchItems(); No exception is caught. Apple.Core and Apple.GameKit plugins have been included in our project Reproducible with https://github.com/apple/unityplugins Both Unity 2020 and Unity 2021 iOS and tvOS Xcode Version 13.4.1
Posted
by
Post not yet marked as solved
2 Replies
1.6k Views
HELLO WORLD! I am currently developing an amazing Unity mini Game. The game development has come to the deploying stage. Using Unity allows me to deploy this game on MacOS, iOS, Android and Windows which is fantastic . However, I really need this game to have the iOS widget extension as a key feature on mobile. Just like the "Steve" dinosaur game which can be played in widget. I had seen a lot of tutorials and youtube videos but still cant find a solution which make Unity iOS app into a widget. If I really want to make widget Game on iOS, do I need to develop the whole game all over again in xcode or using GameKit? Really hoping there's a way to simply convert the Unity iOS app into a widget.
Posted
by
Post not yet marked as solved
3 Replies
1.2k Views
Hello, In our Unity game, we've started experiencing application hiccup as a result of calling [[GKAccessPoint shared] setActive:YES]. The call itself does not take much time, but it seems to trigger something that causes a significant app stall causing running animations and transitions to feel laggy. This is new behaviour for us in iOS 16.1, as it did not cause any hiccups on 16.0 or earlier as far as we've noticed. We've tested the same build on 16.0 and 16.1, and it's working smooth on 16.0. The hiccup is present both when logged in and not logged into GameCenter. Did something change in 16.1 that requires us to use this API in a different way, or is it a (known) bug in iOS? My searches have not resulted in any similar reports. Best, -Trond
Posted
by
Post not yet marked as solved
2 Replies
1.5k Views
I’m tracking down a bug report with a game that has a bunch of achievements that do work. I am trying to reveal the name of a hidden achievement once a player learns it is possible, but before they have any progress towards it. GKAchievement* a = [[GKAchievement alloc] initWithIdentifier: anAchievement]; a.percentComplete = 0; [GKAchievement reportAchievements: @[ a ] withCompletionHandler: ^(NSError * _Nullable error) { if (error != nil) { NSLog(@"revealAchievement: %@ failed %@", anAchievement, error); } }]; The documentation says “isHidden is set to NO anytime this method is invoked” but the achievement is not showing up in the UI. The achievement in question is returned by +loadAchievementsWithCompletionHandler:, but it is considered hidden there (lldb) po a <GKAchievement: 0x6000027993e0>id: MonsterKiller.DarkAge 0.000000 (lldb) p a.hidden (BOOL) $3 = YES I am pretty sure this code worked fine (it’s in a game that came out several years ago). Has Game Center changed (I know hidden is technically deprecated now, but I don’t see anything explaining how to reveal an achievement other than by using +reportAchievements:withCompletionHandler:. And yes, the achievement in question is configured on the server (it can be earned, just not revealed with zero progress).
Posted
by
Post not yet marked as solved
15 Replies
3k Views
We are using apple unity plugin (gamekit) to authorized player using game center account. To get player the info we run a task from the plugin, var fetchItemsResponse = await GKLocalPlayer.Local.FetchItems(); But when this code run, there is an error on the xcode application on mac. The error is the following, Thread 1: EXC_BAD_ACCESS (code=257, address=0x2)
Posted
by
Post not yet marked as solved
2 Replies
1.3k Views
The documentation suggests that it should be possible to use a single shader with multiple instances of an SKNode, such that each instance will use the unique SKAttributes that are passed to it. Let's try that with an SKShapeNode. This is the fragment shader testFill.fsh, simply coloring based on the value for a_test: void main() {     gl_FragColor = vec4(vec3(a_test), 1.0); } And here we make two nodes `testNode0`, and `testNode1`, each using the same shader, but with a different value for `a_test`: class GameScene: SKScene {     override func didMove(to view: SKView) {         let testShader = shaderWithFilename( "testFill", fileExtension: "fsh", uniforms: [])         testShader.attributes = [             SKAttribute(name: "a_test", type: .float)         ] let testNode0 = SKShapeNode(rect: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)) testNode0.fillShader = testShader testNode0.position = CGPoint(x: -100, y: 300) testNode0.setValue(SKAttributeValue(float: 0.2), forAttribute: "a_test") addChild(testNode0) let testNode1 = SKShapeNode(rect: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)) testNode1.fillShader = testShader testNode1.position = CGPoint(x: 100, y: 300) testNode1.setValue(SKAttributeValue(float: 0.8), forAttribute: "a_test") addChild(testNode1) } } Here is the result: The squares are the same color, in particular the result of passing the second value 0.8 for a_test. Now, let's try the same thing with SKSpriteNode: class GameScene: SKScene {     override func didMove(to view: SKView) {         let testShader = shaderWithFilename( "testFill", fileExtension: "fsh", uniforms: [])         testShader.attributes = [             SKAttribute(name: "a_test", type: .float)         ] let testNode0 = SKSpriteNode() testNode0.size = CGSize(width: 100.0, height: 100.0) testNode0.shader = testShader testNode0.position = CGPoint(x: -100, y: 300) testNode0.setValue(SKAttributeValue(float: 0.2), forAttribute: "a_test") addChild(testNode0) let testNode1 = SKSpriteNode() testNode1.size = CGSize(width: 100.0, height: 100.0) testNode1.shader = testShader testNode1.position = CGPoint(x: 100, y: 300) testNode1.setValue(SKAttributeValue(float: 0.8), forAttribute: "a_test") addChild(testNode1) } } And it works! Why does the documentation not say that this is not possible with an SKSpriteNode? Why does an SKSpriteNode have a .setValue method if it does not function as expected? Is this a bug? Or something that is expected to be obvious? I am not sure, but I am sharing this in case somebody else ends up stuck on this issue as I was when otherwise trying to do something relatively straightforward. The solution (if your shape is a simple rect, as it is in my case) is to initialize an empty SKSpriteNode and size it accordingly, after which SKAttributes should work as expected. Apple, please either fix this, or update the documentation.
Posted
by
Post not yet marked as solved
1 Replies
1.2k Views
We are using the Apple Unity plugin (Gamekit) to authorize players, using a Game Center account. To get player info we run a task from the plugin, var fetchItemsResponse = await GKLocalPlayer.Local.FetchItems(); But when this code run, there is an error in Xcode. The error is the following, Thread 1: EXC_BAD_ACCESS (code=257, address=0x2) MacOS 12.5 Monterey Unity 2021.3.4f1 XCode 14.2 AppleCore Unity Package - 1.0.2 AppleGameKit Unity Package - 1.0.3 Crashes when calling FetchItems in Unity Installed in iPhone XR (iOS 15.2.1)
Posted
by
Post not yet marked as solved
7 Replies
1.5k Views
An issue appeared on IOS 16.4 when presenting GKMatchmakerViewController with the matchmakingMode set to inviteOnly. The view controller appears with the invite option as expected. But trying to tap it, the GKMatchmakerViewController disappears immediately. No problem on the previous IOS versions. It works also when matchmakingMode is not used at all.
Posted
by
Post not yet marked as solved
0 Replies
661 Views
Hi, We are facing a strange crash on iOS 16.4 and 16.4.1. The issue is not happening on iPad 16.4. We are getting very limited information on the crash, Here is call stack. 0 GameCenterFoundation 0x00000001f0498054 GKGroupActivityManager.reset() + 228 (GKGroupActivityManager.swift:450) 1 GameCenterFoundation 0x00000001f0496e8d GKGroupActivityManager.leave() + 1 (GKGroupActivityManager.swift:411) 2 GameCenterFoundation 0x00000001f04a67dd @objc closure #1 in GKGroupActivityManager.leave() + 1 3 GameCenterFoundation 0x00000001f04a6835 partial apply for @objc closure #1 in GKGroupActivityManager.leave() + 1 4 GameCenterFoundation 0x00000001f04a67f5 thunk for @escaping @callee_guaranteed @Sendable @async () -> () + 1 5 GameCenterFoundation 0x00000001f04a6839 thunk for @escaping @callee_guaranteed @Sendable @async () -> ()partial apply + 1 6 GameCenterFoundation 0x00000001f04a67f9 specialized thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out A) + 1 7 GameCenterFoundation 0x00000001f04a6899 thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out A)specialized partial apply + 1 8 libswift_Concurrency.dylib 0x00000001c84d0dd9 completeTaskWithClosure(swift::AsyncContext*, swift::SwiftError*) + 1 (Task.cpp:496) Tried looking into GKGroupActivityManager but couldn't find any documentation regarding this. High number of our usser base is affected by this issue.
Posted
by
Post marked as solved
2 Replies
871 Views
Hi All! I'm being asked to migrate an app which utilizes iCloud KVS (Key Value Storage). This ability is a new-ish feature, and the documentation about this is sparse [1]. Honestly, the entire documentation about the new iCloud transfer functionality seems to be missing. Same with Game Center / GameKit. While the docs say that it should work, I'd like to understand the process in more detail. Has anyone migrated an iCloud KVS app? What happens after the transfer goes through, but before the first release? Do I need to do anything special? I see that the Entitlements file has the TeamID in the Key Value store - is that fine? <key>com.apple.developer.ubiquity-kvstore-identifier</key> <string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string> Can someone please share their experience? Thank you! [1] https://developer.apple.com/help/app-store-connect/transfer-an-app/overview-of-app-transfer
Posted
by
Post not yet marked as solved
2 Replies
721 Views
I have implemented a standard GKLeaderboard in my app. The leaderboard includes the player's avatar, display name, and the score. I only use functionality provided by GameKit without any custom server functionality. I don't even have an own server. Still, my app got rejected with the following notice: We noticed that your app does not obtain the user's consent prior to uploading users' scores to a global leaderboard. To collect personal data with your app, you must make it clear to the user that their personal data will be uploaded to your server. What should I do here? Do I really have to obtain user's consent before uploading his score to Game Center?
Posted
by