Highlight
Xcode 26 adds the
.gamekitbundle, which moves Leaderboards, Challenges, Activities, and Achievements out of the App Store Connect web UI and back into the project source. The bundle goes into version control and code review, and Game Progress Manager lets you debug score submissions and deep links locally.
Core content
Anyone who has shipped a Game Center integration knows the pain. Every Leaderboard, Achievement, and Challenge config lives on App Store Connect web pages. Changing one ID means logging into the browser. Team work has no diff, rollback runs on memory, and even local testing pushes real data to the server. A simple “check that the new level reports its score correctly” usually means creating an entry in ASC, submitting a real score, refreshing the board, then cleaning up the dirty data by hand.
WWDC25’s first cut lands here. Xcode 26 adds the .gamekit bundle — a local file that declares all your Game Center resources. You can pull it down from App Store Connect, edit it, and push it back. Locally, Game Progress Manager keeps every debug score inside the current session, so it never pollutes production data. From now on, Game Center config is a code asset. It goes through PRs, code review, and follows your branches.
The other two main courses this year are Challenges and Activities. Challenges sit on top of your existing Leaderboards. If you already call submitScore(), in theory you can let players start time-limited matches against friends without writing a line of code. Activities are deep-link entry points that send a friend straight into the right level or multiplayer room, with Game Center generating a Party Code that pulls everyone into the same session.
Details
Game Center initialization takes two steps: add the entitlement, and call GameKit once. Here is the Swift snippet Apple recommends running as early as possible (04:17):
GKLocalPlayer.local.authenticateHandler = { _, error in
print("\(GKLocalPlayer.local.alias) is ready to play!")
}
Key points:
GKLocalPlayer.localis a singleton. It represents the Game Center player signed in on this device.authenticateHandleris a callback. GameKit only kicks off the auth flow once you assign it.GKLocalPlayer.local.aliasis only valid after the handler fires. Before that it reads as an empty string.- Apple suggests wiring this up when the title screen appears. The earlier you call it, the sooner the game enters the “Top Played Games” exposure pool.
Unity developers get the same semantics in C# (04:29):
var player = await GKLocalPlayer.Authenticate();
Debug.Log($"{player.alias} is ready to play!");
The Unity Plugin source lives on GitHub at apple/unityplugins. You build it yourself, and the build produces an Xcode project with the entitlement already set up.
Challenges are the most restrained design choice in this release — they require no new API. The line that submits a score does not change (13:07):
GKLeaderboard.submitScore(points,
context: 0,
player: GKLocalPlayer.local,
leaderboardIDs: ["thecoast.lb.capecod"])
Key points:
leaderboardIDsis an array, so a single submission can hit several boards at once.- The same API forwards the score to every active Challenge tied to that board. You do not need a separate
submitChallengeScorecall. - Apple stresses this repeatedly: submit one score per level, do not accumulate a lifetime score. Challenges measure skill, not grinding.
contextis a free-form integer. Stuff a level ID, a weapon loadout, or any extra dimension you need into it.
Activities push deep links down to the system layer. The snippet below sends a friend who tapped through into the right level (20:24):
extension AppDelegate: GKLocalPlayerListener {
func player(_ player: GKPlayer, wantsToPlay activity: GKGameActivity) async -> Bool {
let activityId = activity.activityDefinition.identifier
if activityId == "thecoast.activity" {
let level = activity.properties["level"]
if level == "capecod" {
startCapeCod(activity)
}
}
return true
}
}
Key points:
GKLocalPlayerListeneris a protocol. Once you register it, GameKit hands every external launch to this handler.activity.activityDefinition.identifieris the string you typed into the Xcode.gamekitbundle. It must match the resource side.activity.propertiesis a dictionary that merges the base properties from Xcode with the properties of any associated resource (such as a leaderboard).- The handler returns a
Boolto tell the system whether you handled the jump. Returnfalseand the system falls back to its default behavior.
For multiplayer games, Activity ships with a Party Code mechanism (22:35) that gathers players sharing the same code at the same table:
extension AppDelegate: GKLocalPlayerListener {
func player(_ player: GKPlayer, wantsToPlay activity: GKGameActivity) async -> Bool {
let activityId = activity.activityDefinition.identifier
if activityId == "thecoast.multiplayer" {
startMultiplayer(partyCode: activity.partyCode)
}
return true
}
}
Key points:
activity.partyCodeis generated by Game Center, so you do not need to roll your own room-code system.- When the Activity is shared through iMessage, the code is embedded in an OpenGraph page. The recipient sees the share card even without the Games app installed.
- The UI must show the current Party Code and offer manual entry, since players may receive a code from another device or platform.
If you would rather not build your own matchmaking, one line plugs into Game Center’s built-in matchmaking (22:48):
let match = try await activity.findMatch()
The debugging flow is another highlight this year. In the scheme’s Run Options, tick “GameKit Configuration Debug Mode”. Once the game launches, open Game Progress Manager from the Debug menu, and every resource in your .gamekit bundle shows up in the panel. You can submit any score as any player, and you can fire Activity deep links by clicking inside Xcode — the effect matches a real-device tap. Every debug data point lives only inside the current session and never reaches the server (24:03).
Takeaways
-
What to do: move your existing project’s Game Center config from App Store Connect back into a
.gamekitbundle.- Why it pays off: config goes into Git alongside the code. PRs show diffs, rollbacks no longer rely on memory, and team members stop overwriting each other.
- How to start: Xcode 26 → New File → “GameKit Bundle” → from the ellipsis menu, choose “Pull from App Store Connect”, pick your team and game, and the resources land in the local file as-is.
-
What to do: add a Challenge on top of an existing Leaderboard for a zero-code “challenge a friend” feature.
- Why it pays off: it reuses the existing
submitScorecall path with no intrusion. Challenge ships with its own timer and friend-invite UI, turning a single-player board into a social match instantly. - How to start: in the
.gamekitbundle, add a Challenge entry to the target Leaderboard. Set the image, the displayName, and the allowed duration (1 day / 3 days / 1 week). Make suresubmitScore()’sleaderboardIDsis correct, and you are done.
- Why it pays off: it reuses the existing
-
What to do: configure Activity deep links for popular levels and multiplayer rooms.
- Why it pays off: friends arriving from the Games app or iMessage land directly in the level. They skip the splash screen, menu, and chapter picker — friction layers whose conversion is much worse than “open the game and let the user find it”.
- How to start: in the
.gamekitbundle, create an Activity, link the right Leaderboard, and fill inproperties(such aslevel: "capecod"). ImplementGKLocalPlayerListener.player(_:wantsToPlay:)and route onidentifierandproperties.
-
What to do: bake Game Progress Manager into your dev flow, in place of debugging against real servers.
- Why it pays off: no dirty writes to production boards during development. Deep links fire from inside Xcode. You can submit as any player, which makes multiplayer interaction tests easier.
- How to start: edit the scheme’s Run Options and tick GameKit Configuration Debug Mode. Once running, open Game Progress Manager from the Debug menu and pick your current device and game.
Related sessions
- Engage players with the Apple Games app — exposure mechanics and submission notes for the new Games app
- Level up your games — the full technical map of Apple’s unified games platform
- Discover Metal 4 — new Metal 4 features that upgrade game rendering at the bottom layer
- WWDC25 Platforms State of the Union Recap — a full-platform recap of this year’s developer conference
Comments
GitHub Issues · utterances