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

GameKit Documentation

Post

Replies

Boosts

Views

Activity

How to know when an invitee declines a turn based match invite via the push notification action button.
I am developing a turn based game using GameKit. The happy path (pretty much as always) is fine; invite, accept, play, have winners/losers and match ends. Yay! But I am working on making sure I handle situations where invited friends decline to participate. I've been through the docs, and don't see how the GKTurnBasedMatch is updated to reflect the tap of the decline button in the Game Center Invite notification. When I reload the match from Game Center on the host device the status for the invitee who declined is still .invited. I also tested by setting all players that are not the host in the nextParticipants of the endTurn(...) to start the invites and the next invitee was not given a push notification to accept or decline the invite. I feel like there should be a way to determine when an invitee has declined an invite (via participant in the match.participants via status OR a delegation method somewhere that is called when the Decline or Accept buttons on that notification are tapped.) I'm missing something, please help me find it! Thank you!
2
0
205
2w
Editor Ok, but running batch get: Cannot locate a Release or Debug Apple.GameKit native library for macOS
After running build.py -p Core GameKit and adding the tar balls to the Unity project in Assets/ExternalPackages no packages seem to be found when running the build using our continuous integration system. This was not the case when the project was opened in the Editor. It looks like in Apple.Core, the ApplePluginEnvironment hasn't run the OnEditorUpdate function and so the _appleUnityPackages Dictionary is empty. A change to ApplePlugInEnvironment.cs seemed to fix the issue: public static AppleNativeLibrary GetLibrary(string packageDisplayName, string appleBuildConfig, string applePlatform) { // ?FIX?: If we're not in the editor, we might not have updated the package list. if (_appleUnityPackages.Count == 0 && _updateState == UpdateState.Initializing) { OnEditorUpdate(); // UpdateState.Initializing OnEditorUpdate(); // UpdateState.Updating } I'm not sure if this is something we're doing incorrectly, the documentation for the plug-in mostly covered building the package.
2
0
185
2w
GKGameCenterViewController initWithLeaderboardID doesn't respect GKLeaderboardPlayerScopeGlobal
I'm making the following call: [[GKGameCenterViewController alloc] initWithLeaderboardID:leaderboardID playerScope:(GKLeaderboardPlayerScopeGlobal) timeScope:(GKLeaderboardTimeScopeAllTime)]; When I present that VC, I get the correct leaderboard (for my passed leaderboardID), but it appears in "Friends" view, not "Global". Global works fine when I tap on it, but I'd like to display that list by default. Seems like a pretty straightforward request supported by the API. Does initWithLeaderboardID not respect that? I'm curious if others have this problem. Thanks!
1
0
151
2w
What is the earliest supported MacOS version that the Unity plugins will work on?
Hi. The earliest version of MacOS that Unity supports is 10.13. However, it seems that running a game using Unity Plugins on 10.13 causes DLL loading exceptions whenever you try to access part of the GameKit API. The errors look like this: Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/GameKitWrapper Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.dylib Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.dylib Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.so Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.bundle DllNotFoundException: GameKitWrapper assembly:<unknown assembly> type:<unknown type> member:(null) at (wrapper managed-to-native) Apple.GameKit.DefaultNSErrorHandler+Interop.DefaultNSErrorHandler_Set(Apple.Core.Runtime.NSExceptionCallback) at Apple.GameKit.DefaultNSErrorHandler.Init () [0x00001] in ./Library/PackageCache/com.apple.unityplugin.gamekit@e3d4ad5a2c8e/Source/DefaultHandlers.cs:35 (Filename: ./Library/PackageCache/com.apple.unityplugin.gamekit@e3d4ad5a2c8e/Source/DefaultHandlers.cs Line: 35) Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/GameKitWrapper Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.dylib Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.dylib Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.so Fallback handler could not load library /Users/love/Desktop/REDACTED/Contents/Frameworks/MonoEmbedRuntime/osx/libGameKitWrapper.bundle DllNotFoundException: GameKitWrapper assembly:<unknown assembly> type:<unknown type> member:(null) at (wrapper managed-to-native) Apple.GameKit.DefaultNSExceptionHandler+Interop.DefaultNSExceptionHandler_Set(Apple.Core.Runtime.NSExceptionCallback) at Apple.GameKit.DefaultNSExceptionHandler.Init () [0x00001] in ./Library/PackageCache/com.apple.unityplugin.gamekit@e3d4ad5a2c8e/Source/DefaultHandlers.cs:14 These errors do not appear on 10.15 or later, which is why I am assuming it's a problem with this particular version of MacOS. Have not been able to test 10.14 so not sure how it handles there. So, here is my question - what is the earliest version of MacOS that the Apple Unity plugins support? It's not documented anywhere on the GitHub page. // Love
4
0
249
3w
Game Porting Toolkit formula install error
So recently I have been trying to install game-porting-toolkit, and when I try to run brew -v install apple/apple/game-porting-toolkit Im getting an error: Error: apple/apple/game-porting-toolkit 1.1 did not build Logs: /Users/mateusz/Library/Logs/Homebrew/game-porting-toolkit/00.options.out /Users/mateusz/Library/Logs/Homebrew/game-porting-toolkit/01.configure /Users/mateusz/Library/Logs/Homebrew/game-porting-toolkit/01.configure.cc /Users/mateusz/Library/Logs/Homebrew/game-porting-toolkit/wine64-build If reporting this issue please do so to (not Homebrew/brew or Homebrew/homebrew-core): apple/apple I searched on this forum some threads but I couldn't take any advice from them. I would really appreciate any help.
0
0
322
4w
How to get GKMatch instance after accepting GKInvite?
In my SceneKit game I'm able to connect two players with GKMatchmakerViewController. Now I want to support the scenario where one of them disconnects and wants to reconnect. I tried to do this with this code: nonisolated public func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) { Task { @MainActor in switch state { case .connected: break case .disconnected, .unknown: let matchRequest = GKMatchRequest() matchRequest.recipients = [player] do { try await GKMatchmaker.shared().addPlayers(to: match, matchRequest: matchRequest) } catch { } @unknown default: break } } } nonisolated public func player(_ player: GKPlayer, didAccept invite: GKInvite) { guard let viewController = GKMatchmakerViewController(invite: invite) else { return } viewController.matchmakerDelegate = self present(viewController) } But after presenting the view controller with GKMatchmakerViewController(invite:), nothing else happens. I would expect matchmakerViewController(_:didFind:) to be called, or how would I get an instance of GKMatch? Here is the code I use to reproduce the issue, and below the reproduction steps. Code Run the attached project on an iPad and a Mac simultaneously. On both devices, tap the ship to connect to GameCenter. Create an automatched match by tapping the rightmost icon on both devices. When the two devices are matched, on iPad close the dialog and tap on the ship to disconnect from GameCenter. Wait some time until the Mac detects the disconnect and automatically sends an invitation to join again. When the notification arrives on the iPad, tap it, then tap the ship to connect to GameCenter again. The iPad receives the call player(_:didAccept:), but nothing else, so there’s no way to get a GKMatch instance again.
2
0
243
Nov ’24
Unable to test Game Center achievements in ad hoc builds to registered device
Hi, I have a test app with a single "game centre achievement" and I am running it on my iPad and unable to list that achievement with GameCenterManager.shared.loadAchievements The app is still in version 1.0, prepare for submission status, (it is not ready for review submission). Game Center entitlement is added for the app and the achievement is added to the Game Center section of app. However it is marked as NotLive. I am using a sandbox account to login to game centre on the iPad and I can't fetch this achievement. Is it because it is "NotLive". ? How do I test my Game Center achivement on the device without releasing it yet.
1
0
248
Nov ’24
GKGameCenterViewController won't turn off.
GKGameCenterViewController won't turn off. With Core and GameKit from GitHub apple/unityplugins, I succeeded in logging in and displaying GKGameCenterViewController. Other leaderboards and everything work fine, but when I press X on GameCenter to return to the game, nothing happens. I tried debugging by printing logs here and there in the plugin to check, but I didn't get any results. When I press X, I couldn't get any logs or responses. It was like a button with no listener attached. No, it was more like an image. Based on the community posts that said it worked fine before, it seems that the recent GameCenter update was not applied to the plugin, was omitted, or changed, causing a mismatch.
1
0
211
Nov ’24
Crash after using Apply unity plugin (GameKit-3.0.0)
Hi, I tried to save the game progress using the official Apple plugin for Unity but the crash happened when I active the "iCloud Documents" inside capabilities and when deactivated it this error message appeared: Code=27 Domain=GKErrorDomain Description=The requested operation could not be completed because you are not signed in to iCloud or have not enabled iCloud Drive. (UbiquityContainerUnavailable) Authentication with Game Center works fine using the Core plugin, but nothing works correctly when I use the GameKit plugin. Note: I already active iCloud for app Identifier. Tichnecal informations: Unity version: 2022.3.47f1 LTS XCode 16 Swift 6 GameKit-3.0.0 (Apply unity plugin) Core-3.1.5 (Apply unity plugin)
2
0
377
Nov ’24
Can the simulator be used to test a GameKit app?
I'm sure this question was asked many times before but I cannot find a good answer. In my case it just doesn't work. Here's what I did Created a couple of test user accounts on appstore connect under the sandbox section. Launched two different simulators via xcode. On each simulator I logged in into test icloud account and game center accordingly. Deployed and launched my code via xcode. What happens is that GameKit code fails to find any peers no matter what I do. Sending Invite doesn't work either because the simulator displays an error message saying "you need to log-in into icloud account first" although it's already logged in. I tried the same code on two different physical devices with two real icloud accounts and it works as expected but it's not a viable path to develop and debug an app. I'm using the latest Xcode 16.1 running on 15.1. Anybody has any clue how to solve this ?
2
0
274
Nov ’24
Game Porting Toolkit Crashing Playing HighEnd Games
Updated to GPT 2 with the app format and whisky in October. I'm using steam in GPT to play the windows only games. The games consistently crash my computer to restart when I played games like Liar's Bar and Phasmophobia, the latter even with its performance optimization update released today. Both of them do that when I load into the game room, so the bar/ghost house or even while loading. It ran Outpath properly though, which was something with much lower quality than LB and Phas. I don't think it's a simple RAM config issue because Phasmophobia ran fine for me with older versions in GPT 1 although I did experience occasional crashes but I think those were only crashing the game not my mac. I'm not sure what I'm doing wrong that I can't run those games or if it's a GPT problem. I'm using a MPB Pro M1 with 16GB memory on Sequoia 15.0.1.
1
0
333
Oct ’24
GameplayKit usage with Swift 6: Call to main actor-isolated instance method 'run' in a synchronous nonisolated context
Hi there, With a couple of other developers we have been busy with migrating our SpriteKit games and frameworks to Swift 6. There is one issue we are unable to resolve, and this involves the interaction between SpriteKit and GameplayKit. There is a very small demo repo created that clearly demonstrates the issue. It can be found here: https://github.com/AchrafKassioui/GameplayKitExplorer/blob/main/GameplayKitExplorer/Basic.swift The relevant code also pasted here: import SwiftUI import SpriteKit struct BasicView: View { var body: some View { SpriteView(scene: BasicScene()) .ignoresSafeArea() } } #Preview { BasicView() } class BasicScene: SKScene { override func didMove(to view: SKView) { size = view.bounds.size anchorPoint = CGPoint(x: 0.5, y: 0.5) backgroundColor = .gray view.isMultipleTouchEnabled = true let entity = BasicEntity(color: .systemYellow, size: CGSize(width: 100, height: 100)) if let renderComponent = entity.component(ofType: BasicRenderComponent.self) { addChild(renderComponent.sprite) } } } @MainActor class BasicEntity: GKEntity { init(color: SKColor, size: CGSize) { super.init() let renderComponent = BasicRenderComponent(color: color, size: size) addComponent(renderComponent) let animationComponent = BasicAnimationComponent() addComponent(animationComponent) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } @MainActor class BasicRenderComponent: GKComponent { let sprite: SKSpriteNode init(color: SKColor, size: CGSize) { self.sprite = SKSpriteNode(texture: nil, color: color, size: size) super.init() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class BasicAnimationComponent: GKComponent { let action1 = SKAction.scale(to: 1.3, duration: 0.07) let action2 = SKAction.scale(to: 1, duration: 0.15) override init() { super.init() } override func didAddToEntity() { if let renderComponent = entity?.component(ofType: BasicRenderComponent.self) { renderComponent.sprite.run(SKAction.repeatForever(SKAction.sequence([action1, action2]))) } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } As SKNode is designed to run on the MainActor, the BasicRenderComponent is attributed with MainActor as well. This is needed as this GKComponent is dedicated to encapsulate the node that is rendered to the scene. There is also a BasicAnimationComponent, this GKComponent is responsible for animating the rendered node. Obviously, this is just an example, but when using GameplayKit in combination with SpriteKit it is very common that a GKComponent instance manipulates an SKNode referenced from another GKComponent instance, often done via open func update(deltaTime seconds: TimeInterval) or as in this example, inside didAddToEntity. Now, the problem is that in the above example (but the same goes foupdate(deltaTime seconds: TimeInterval) the methoddidAddToEntity is not isolated to the MainActor, as GKComponent is not either. This leads to the error Call to main actor-isolated instance method 'run' in a synchronous nonisolated context, as indeed the compiler can not infer that didAddToEntity is isolated to the MainActor. Marking BasicAnimationComponent as @MainActor does not help, as this isolation is not propogated back to the superclass inherited methods. In fact, we tried a plethora of other options, but none resolved this issue. How should we proceed with this? As of now, this is really holding us back migrating to Swift 6. Hope someone is able to help out here!
2
2
498
Oct ’24
Error "No Apple native plug-in libraries found." when importing freshly built plugins into Unity
I just built Core and GameKit without errors. The command line I used was the following: python3 build.py -p Core GameKit -m macOS -c "Apple Development ID (redacted)" When importing these packages into Unity, as soon as the editor refreshes I get these errors: DllNotFoundException: GameKitWrapper assembly:<unknown assembly> type:<unknown type> member:(null) And DllNotFoundException: AppleCoreNativeMac assembly:<unknown assembly> type:<unknown type> member:(null) And Apple Unity Plug-ins] No Apple native plug-in libraries found. Were the libraries built with the build script (build.py), xcodebuild, or Xcode? Was any output generated from the build script/tool? Were there any errors or issues? Please check to ensure that libraries (.a, .framework, or .bundle files) were created and saved to each plug-in's "NativeLibraries~" folder. I made sure that the libraries were saved to this NativeLibraries folder. I made sure to update xcode, python, npm and Unity to the latest version, got the most recent commity from Github (Sept. 17th) but the errors persist. The errors also occur right as the game starts in a built player. Also occurs in a blank Unity project, where I tested both 2022.3.17f and 2022.3.48f. The versions I was trying to import was Core 3.1.4 and GameKit 3.0.0. Same issue with Core 3.1.3 and Gamekit 2.2.2. Last version I tried that works was Core 1.05 and GameKit 1.04. I haven't seen anyone else encounter this on these forums so I'm guessing that I'm personally doing something wrong rather than there being an issue with the plugins themselves, but what am I doing wrong?
4
0
717
Sep ’24
Leaderboard not updating immediately after submitting score via GameKit API
Hello, I’m working with the GameKit API, and I am encountering an issue when submitting a player’s score to a leaderboard at the end of a game. Goal: After submitting the new score to a leaderboard, I want to immediately fetch and display the updated leaderboard that reflects the new score. Problem: After successfully submitting the player’s score, when I fetch the leaderboard, the entries are not updated right away. The fetched leaderboard still shows the outdated player score. Is this delay in updating the leaderboard expected behavior, or am I missing something in my implementation? Steps to Reproduce: Submit the local player’s score to Leaderboard X. On successful submission, fetch the leaderboard entries for Leaderboard X. Expected Result: The fetched leaderboard should reflect the updated player score immediately. Actual Result: The fetched leaderboard shows the outdated score, with no immediate update. As a workaround, I update the leaderboard myself locally, that does the job, but is error-prone and require more efforts.
2
0
419
Sep ’24
Setting a timeout in GKTurnBasedMatch doesn't work... GKTurnBasedParticipant.timeoutDate is always nil.
I have created a turn based game using GameKit. Everything is pretty much done, last thing left to do is the turn time out. I am passing GKTurnTimeoutDefault into the timeout argument in: func endTurn(withNextParticipants nextParticipants: [GKTurnBasedParticipant], turnTimeout timeout: TimeInterval, match matchData: Data) However when I check the .timeoutDate property of the GKTurnBasedParticipant participants, the value is always nil. What am I doing wrong? Am I checking the right property or is there another one instead that I don't know about? I have tried passing different values to the timeout parameter but the timeoutDate is always nil. Has anyone successfully implemented a timeout using GKTurnBasedMatch ?
1
0
379
Sep ’24
Leaderboard/achievements and testing
Hi, I created a leaderboard in my application, and a method to record a new score: GKLeaderboard.loadLeaderboards(IDs: [leaderboardID]) { (leaderboards, error) in if let error = error { print("Error loading leaderboards: \(error.localizedDescription)") } guard let leaderboard = leaderboards?.first else { print("Leaderboard not found") return } leaderboard.submitScore(score, context: 0, player: self.localPlayer) { error in if let error = error { print("Error reporting score: \(error.localizedDescription)") } else { print("Score reported successfully!") } } } } When debuging, this method is correctly called and I have a success, so I tried to test it with an internal TestFlight release. The leaderboard is never updated. Is there a way to perform a test of a leaderboard before publishing the app? I have the same question for achievements: let achievement = GKAchievement(identifier: identifier) achievement.percentComplete = percentComplete GKAchievement.report([achievement]) { error in if let error = error { print("Error reporting achievement: \(error.localizedDescription)") } } } Thanks!
2
0
514
Sep ’24