Turn Based Games with GameKit

Making a turn based game on iOS that relies on GameKit and Game Center would have been a pretty straight forward affair if only the documentation was consistent, clear and without errors. Sadly the documentation is quite bad making things feel so much more complicated than they are.

In this article I’ll first provide you with some background, then a overview, before diving into the details of using the turn based exchanges available with GameKit. When you’re done reading you will be able to confidently and efficiently make your own turn based game.

To experiment with these APIs yourself, consider downloading the minimal project I created to explore exchanges myself.

Background

For several weeks I struggled to figure out how exactly to use the GameKit APIs. Eventually I got everything working except turn based exchanges. No matter what I tried there was no way to resolve completed exchanges elegantly. So I decided to create a minimal project to highlight my problem before submitting a support ticket to Apple. After having waited two weeks I got a reply that sadly didn’t help at all (like so many other developers even the Apple engineer incorrectly interpreted the documentation). With even Apple engineers not knowing APIs or understanding the documentation I was getting quite frustrated.

Coincidentally the WWDC 2020 was just about to start at this time, so I decided to seek help at a lab session. Assuming they would need more than a single session to solve my issue I decided to book two 1-on-1 labs.

I spent the first lab explaining the issue I had with turn based exchanges. The Apple engineer then did some investigation, and in my follow-up lab he could inform me that they discovered a bug in the backend that prevented the turn holder from getting the notification needed to resolve completed exchanges. Only the requester would be notified, which obviously is only helpful when the turn holder is also the requester. In other words, turn based exchanges have presumably never worked as designed — my understanding of the APIs were correct, I had been fighting bugs that were not my own.

So now that Apple is aware of the bug, I was told they will update my thread on the Apple Developer forum when exchanges have been fixed. Meanwhile we should develop our game as if exchanges works properly, and simply workaround the error we receive when trying to mutate the match data while there are completed exchanges. So this is what I’ll be doing in this article.

Overview

To get started I think it’s best to establish a shared taxonomy. Apple uses several different terms for the same entities, so lets get some clarity:

  • Participant; this is an authenticated Game Center player that has joined a match, or a player placeholder before a real human has taken the seat in the match. For you as a developer it doesn’t matter if the participant is a human or not; in either case you can initiate an exchange, update the game and end a turn.
  • Turn holder; this is the participant that is currently resolving a turn; also called “current participant”. Only the turn holder is permitted to update the match data.
  • Match Update; you use updates when the turn holder performs an action that mutates the match data without ending the turn. You push the mutated match data to the server, which triggers a turn event for all the other participants ensuring everyone has the current match state.
  • Exchange; also called an “exchange request”. It sounds like a trade, but can in fact be used for almost any kind of communication between two or more players. An exchange is an event that includes a localised string, data, a deadline and a state (more about the states below). When you create the exchange you specify who should receive it. The replies optionally returned from the receivers are retained by the exchange and used to figure out how the match data is affected.
  • Requester; also called “initiator” of the exchange. This is any participant in a match that creates an exchange.
  • Recipient; a participant that receives an exchange request. Despite what the documentation is saying, you are not required to include the turn holder as a recipient. You can let the requester freely select any number of participants to be the recipients of the request.
  • Exchange reply; recipients can ignore or chose to reply to a received exchange request. If no reply is sent, the requester will have to wait for the exchange to time-out. Keep in mind, you don’t necessarily need to involve the player when determining if the recipient should reply or ignore the request. A reply can contain a localisable string and/or some data. A reply can be used to acknowledge, accept or decline the received exchange; it can be a counter-bid in a negotiation; a bid in an auction; a chat message between arbitrary players, or anything else you find useful.

Turn Based Exchanges

You use an exchange to pass data between two or more players. An exchange can be cancelled by the requester up until it has been resolved.

An exchange is created, passed to the recipients and finally returned to the requester all the while its state transitions as follows:

A single exchange can be used to pass a message to an opponent, or a series of exchanges can be used to resolve an auction or negotiate a trade. The outcome of an exchange can be stored in the match data however you like; as a separate structure, or discarded after having updated the match data. How you resolve exchanges is completely up to you and the needs of your game — however keep in mind that it’s always the turn holder that resolves it, so combining the exchange and replies should result in exactly one outcome, with no need for additional input.

  1. When the exchange request API is called by the requester it is sent to Apple who creates the exchange and forwards it to all recipients. The state of the distributed exchange is active. Active exchanges will not prevent turn holder from performing an update or ending the turn. They can all be found in the activeExchanges array of the turn based match instance.
    • The participants that did not directly receive the request, but that is loading the game at this point, will also be able to present whatever is needed to the player by parsing and processing the exchanges in the activeExchanges array. You could eg. show that a trade is happening.
  2. The state is updated (by Apple) to completed after all recipients have either replied to the exchange request or the request has timed out. In other words, don’t expect to get a reply from all recipients. This state-shift triggers a notification event received by both the turn holder and the requester. If the turn holder is also the requester I assume the participant’s device will still only receive one event (this is unknown due to the mentioned bug on the server).
    • The job of the requester is at this point over, however you may want to use the received exchange and associated replies to present the outcome of the exchange.
    • The turn holder however, will use the exchange data and all the replies (actual replies or time-outs from the recipients) to work out how the exchange affects the current match data. After this is done the turn holder needs to update the server with the resulting match data to transition the state from ‘completed’ to ‘resolved’. Until the exchange is successfully resolved the turn holder will get an error if trying to update the match data or end the turn.
    • Other participants loading the game at this point will also be able to present whatever is needed by parsing and processing the exchanges in the completedExchanges array.
  3. Apple receives the updated match data, which means the completed exchange is now resolved. At this point the exchange is removed from the match, before the match with the updated match data is distributed as a turn event to all participants. This notification may be received possibly by all but the turn holder (as the turn holder already knows the outcome of the exchange and has the resolved match data).

Turns and Updates

The endTurn and updateMatch APIs works as needed, and are by nature very straight forward.

The turn holder can do actions that end their turn or optionally actions that only updates the match data (without ending the turn). Of course your game doesn’t have to offer updates, it may only need turn ending actions.

When a player ends their turn you determine who will be the next turn holder. However, in case the next turn holder doesn’t resolve their turn before it times out, you also queue up all the other participants – adding current participant last.

You always add the current participant last because the last participant in the queue will not time-out. This ensures there is at least one player that holds the game and ends it when everyone else have failed to take a turn.

Summary

Turn Based Exchanges are awesome – at least they will be when Apple fixes the bug. You can use exchanges for almost any in and out-of-turn communication. So go an be creative!

And that’s all folks! If this was helpful, I’m glad. You can reach me on Twitter if you have any comments or thoughts.

Writing Honest Code

The idea of honest code is not anything new. We are all to some extent trying to be honest when coding. However, conditions arise that causes us to cut corners, and that is often when dishonesty seeps into the code. And once it is there, it tends to stick around.

Writing honest code is to focus on writing truly appropriate code that in itself reflects the expectations and requirements of the underlaying business logic.

This means that you try to always ensure your code actually tests what should be tested, even when testing against the inverted case would result in less verbose code. Select the data structures that best reflect the expectations and requirements of the project.

Honest code results in higher quality self-documenting code that is easier to maintain, and will likely cause less regression bugs. Writing honest code is to avoid anti-patterns. Everyone will benefit, through the entire lifespan of the project, as the business logic is easier to piece together when reading the code.

For example, if your mobile app never plays any sound without user interaction, then postponing the loading of sounds until after the view is shown results in more honest code. Anyone reading the code can now induce this simple fact.

Conversely, preparing the audio while views are still being initialized is less honest as nobody can actually assert any expectations about the use of sounds in the app. A result is that it’s not immediately clear if postponing audio preparation will cause issues or not.

If you use an optional boolean that is nil while no timer is running, and either true or false depending on the timer having reached a certain value, let the name of the variable reflect this. A suitable name could be something like nilOrHasReachedValue.

In short, honest code means to:

  1. Do things as late as feasible.
  2. Check what actually matters, not what is convenient.
  3. Put thought into naming things.
  4. Guard against entry requirements.

What do you think? Did I manage to explain the idea of writing honest code?

Switch It Up

I’ve never liked seeing a console I love being replaced; it bothers me that the move may be little more than financially motivated. At least I feel that is true for the Xbox and the Playstation – each generation bringing little else than more horsepower.

Which is why I appreciate Nintendo. Sure, the lifespan of a Nintendo console is also determined by its commercial success – both the GameCube and the Wii U made that clear. But despite the realities of commerce, each new home console from Nintendo risked offering something delightfully different.

Chris Koelsch illustrates this with his handsome history of the Nintendo controllers created for each home console (if you want music with that, he also animated them):

For the complete history of all game controllers, you could check out this rather saturated flow chart available as a poster from Pop Chart Lab. It covers everything up to, but not including the Nintendo Switch.

Now that we know the basics of what the Nintendo Switch is, I think it’s a good time to publish my expectations for the system.

Not a Clam

I was a bit surprised that the Switch didn’t get a clamshell design, which makes sense for a portable system. The screens are protected and the size halfed while the console is transported.

However, I’ll gladly trade in the second screen for two removable controllers – each with their own battery – allowing two players to compete while on the go. And if the Switch reveal trailer is any indication, it seems like the Switch is able to connect to another Switch without an internet connection, for a four player outdoor extravaganza!

I’m not expecting the Switch to support peer to peer connections with more than one console, but it would fantastic if eight consoles could connect anywhere for a full game of Splatoon!

For the dock I expect cover plates, and maybe back plates for the console itself. Nintendo introduced this for the New 3DS, and I’m assume it makes financial sense to offer the same for the Switch.

I’m guessing the Joy-Cons will only charge while connected to either the grip (hopefully with its own battery) or to the console itself. The battery charge of the Wii U GamePad lasts about 3 hours, which was sufficient for me, but 5-6 hours would please a lot of gamers. And considering the nature of the Switch, a better battery would make perfect sense. I’m also expecting the battery of the console to support quick charging.

The Switch seems to be supporting Micro SD cards up to 128 GB. I’m expecting this to work much like the New 3DS.

I’m nervous about the ergonomics of the Joy-Cons: the shoulder buttons seems a bit ackward. But with a good shape, they’ll work just fine. Other than that, I think they make a lot of sense. The (almost) mirrored design means there are no excuse when loosing in a Mario Kart duel.

I’m eagerly awaiting the live Nintendo Switch Presentation 2017 event in Tokyo, where the launch date, price and game lineup will be revealed. I think this new Home and About Game Console will deliver a really exciting package.

Playing Splatoon

In June Nintendo announced that Splatoon had sold more than a million copies. I’m not surprised. Splatoon is a surprisingly well made game, and many Wii U owners hunger for shooter-like games. Since release Splatoon has seen two new game modes added to the initial Turf War. Let’s discuss these online modes, how they affect the gameplay, and more general game tactics unique to Splatoon.

Ink is Awesome

Splatoon is not Call of Duty, Halo or any other shooter for that matter. Yes, you can splat your opponents, but in Splatoon – splatting the opposition is just a means to an end; your team doesn’t necessarily win by stacking up a high splat count.

Ink is the universal ammo of the game and the only way you interact with other players. Ink is what separates Splatoon from other shooters and makes it unique. Inklings (players) use ink to:

  • Increase swim speed
  • Increase ink reload speed
  • Hide
  • Swim up vertical surfaces
  • Reveal and detonate mines
  • Reveal Bad Guys
  • Slow down Bad Guys
  • Splat Bad Guys
  • Help your Teammates

I’m not entirely sure of this, but I believe shooting at a friendly player removes enemy ink – which otherwise would cause the inkling to show up on enemy GamePads. Which, if true, gives you a second good reason to ink your own team (or at least those that are pulsating on the GamePad).

Game Modes

The only way to play more than 2 players is to go online. Currently Splatoon offers three online game modes: Turf War, Splat Zones and Tower Control. All modes pits 4 players against 4 opponents, they all use variations of the same maps, and all modes add a time limit to the match. However, only Turf War cannot be won by knockout.

A Knockout occurs when a team reaches the winning condition before the match timer reaches zero. In the event of a Knockout, the loosing team doesn’t get any points – otherwise both teams earn points, and the team with the highest score wins.

The interesting part of these three modes is how they affect the tactics deployed to win.

Turf War

Stage 1 in red; expand coverage by spreading out. Stage 2; convene by the bottle neck, or edge of your controlled area and push toward opponent spawn.
Stage 1 in red; spread out to cover maximum turf. Stage 2 in blue; convene at the front to maintain perimeter.

The winner of a Turf War is the team with the most ink on the ground (walls do not count). Keep in mind that the winning team is often determined during the final 40 seconds of the match.

During the initial stage of the match, shown in red, the players spread out to cover as much turf as possible. Usually it’s a good idea to have at least two players make their way to the front to secure the bottlenecks, leaving no more than two players coloring the back.

When the home half of the map is sufficiently covered, stage 2 of the match begins (shown in blue). All four players convene at the front of the controlled turf (shown in blue), where the entire team work together to keep the front intact, maintain control of the bottlenecks, and splatting any bad guys that breaks through the perimeter.

Splat Zones

Stage 1 in red; using different paths, convene at a zone. Stage 2 in blue; spread out to maintain control of the zone by adding ink to the area around the zone.
Stage 1 in red; using different paths, convene at a zone. Stage 2 in blue; spread out to maintain control of the zone by adding ink to the area around the zone.

This mode is about coloring one or two smaller sections of the map with ink for 1 minute. If there are more than one zone, all zones must be controlled by the same team for the countdown to begin.

The team should use different paths to convene at the splat zone (red arrows). If there are more than one zone, use the GamePad to pick the least risky zone. Get the zone under control by covering it with sufficient ink. If you find yourself outnumbered, swim to safety or target the other zone.

When the zone is under control spread out to maintain control from a safer distance (blue arrows). At this stage focus on closing down bottlenecks and hunting down bad guys preparing an attack from the flanks. With no opponents near you location, focus on expanding the inked area around the zone – as that will make it harder for the bad guys to launch a surprise attack.

At all times try to avoid getting covered by enemy ink as you’ll become visible on the GamePad. Don’t ink more turf if you want to avoid to revealing your position to the enemy.

Tower Control

The goal of Tower Control is to move a tower from the center of the map all the way to the tower zone on the enemy side of the map. The tower keeps moving towards the enemy for as long as it’s controlled by your team; when no player rides the tower however, it stops. If you wait too long while the tower stands still, it’ll begin moving back to start (the center of the map).

BadTowerTactics

This mode is currently by far the most chaotic. Though some of the chaos is caused by the tower itself (disorienting and frustrating camera clipping issues), the tactics practiced by most players is the bigger issue: everyone are mindlessly rushing to reach and ride the tower, hoping to brute force their way to victory.

This tactic adds very little to the game. Even worse, it reduces the ink to little more than ammo – which is a pity, as ink is so much more.

The cause of this tactical choice is the small point of interest – the tower – and the fact that it is always moving, preventing players from establishing themselves on the map. However, when players get more familiar with this match mode, we’ll hopefully see better teamwork emerging.

The goal of any tactics deployed should be to take better advantage of the awesome powers of ink.

Stage 1 in red; players spread out to defend the tower, no riders at this stage. Stage 2 in blue; advance to next positions when one team member moves in to ride the tower.
Stage 1 in red; players spread out to defend the tower, no riders at this stage. Stage 2 in blue; advance to next positions when one team member moves in to ride the tower.

Stage 1 (in red) should be to spread out to cover turf that leads the team to good tactical positions. From these positions the team splats the opponents.

When at least half of the opponent team has been wiped out stage 2 (in blue) begins: Move up to better tactical positions around the tower rail, while focusing on preventing the opponents from reaching the tower both directly (splatting foe) and indirectly (inking turf).

Never have more than one concurrent rider, and try to always be prepared to step onto the tower within seconds after your friendly rider is taken out.

Finally, when the tower is within the friendly half of the map, don’t try to ride it back to the center of the map! Instead simply get the enemy riders off the tower, and position yourself to simply keeping it clear. When the tower is back to start, one team member moves in while the rest of the team endeavors to keep the friendly rider safe.

So, what do you think?

WiiU Stamina

As you likely know by now, Nintendo is once again making money. Apparently, they haven’t done that since 2011. Surprisingly, the earnings are coming from lower than expected sales:

Wii U sales totaled 3.4 million, expected 3.6 million.
3DS sales totaled 8.7 million, expected 9 million (despite the New 3DS).
63 million 3DS games, expected 67 million.
24.4 million Wii U games, expected 25 million (up from initial prediction of 20 million).
The sales of the best Mario Kart in the franchise, and well received Super Smash Bros, clearly helped these numbers. Furthermore, Nintendo reported a 30% increase in digital sales, which obviously made them more money than physical disks.

However, I’m surprised digital sales didn’t increase more. Digital distribution makes environmental sense, in addition to the personal advantages that I think by far outweigh the benefits of physical disks: they don’t break, get lost or outdated; are instantly available, and finally encourages impulsive gaming. I guess Nintendo doesn’t push digital sales more aggressively by lowering their prices on the eShop as Nintendo as a brand benefit from being visible and available in stores both on- and offline.

Anyway, if Nintendo can keep this going, the WiiU should stick around for at least another two years:

We know that Nintendo will focus on WiiU and 3DS at E3 in June, which makes it obvious that both the WiiU and (New) 3DS will last well into 2016. Which is the year Nintendo will launch their first mobile games and likely some Quality of Life products, as well as reveal the Nintendo NX, and finally get Zelda in the hands of impatiently waiting WiiU players.

Meanwhile Nintendo will keep increase their lucrative Amiibo collection and extend in-game Amiibo support; and publish Splatoon, Yoshi’s Woolly World, Xenoblade Chronicles X, Mario Maker and Star Fox.

Nintendo NX

When high quality games are discussed, it doesn’t take long for a Nintendo game to become part of the conversation. To my knowledge, Nintendo have been creating high quality games since Jumpman was introduced in Donkey Kong (1981).

My first thought when I think about Nintendo is how delightfully playful their games feel. The entire screen is filled with playful polygons dressed in familiar saturated colours. The use of high contrasting colors was initially a consequence of hardware limitations, but eventually a deliberate and consistent choice to remain energetic, lively and family friendly.

The family friendly appeal however, doesn’t explain the enduring perception of high quality. This of course, relates more to game feel and mechanics. A classic Nintendo game feels tight, responsive and immediate, and the mechanics are brilliant – and is in my opinion, where the game truly shines. The player is given a limited repertoire of actions to manage, which the player quickly learns to master. But just as the player feels in control, the environment changes, forcing the player to relearn and adapt. This creates a rapid loop of skill mastery, which stimulates our brain and basically makes us feel good. Few games manage to do this as successfully and efficiently as Nintendo.

These good feelings associated with playing a Nintendo game is why we keep coming back, and also why their games are still appreciated more than 30 years later. Which brings me to Nintendos superior dedication to backwards compatibility, Virtual Consoles, and finally to the Nintendo NX.

I consider the Wii U to be the most complete game system available. It can play the entire catalogue of Wii games, several of which are truly classics! It supports all the controllers made for the Wii, and adds the GamePad which opened the door for assymmetric gameplay. Currently, the Wii U Virtual Console supports games for Nintendo Entertainment System, Super Nintendo Entertainment System, Nintendo Game Boy Advance, Nintendo 64 and recently the Nintendo DS.

If the Wii U wasn’t launched when and how it was, it might have sold better. But primarily I think consumers were a but weary of buying a second underpowered Nintendo console; especially as rumours about the new Playstation and Xbox were so completely focusing on processing power.

Nintendo’s next console, nicknamed NX, could fix this.

My hopes about the NX

This is what I’m thinking about the NX which we’ll likely see in 2017, or if they rush development, already for Christmas 2016, but I doubt it.

If the Nintendo NX is a dual screen GamePad that works as a 3DS when out of the house? Sign me up!

The NX will be given enough polygon pushing power to match the PS4. It might have an overlapping hardware architecture with an “NX Portable” widescreen gaming system to enable code sharing and speed up cross-platform development.

For the NX to retain backwards compatibility with the Wii U, which it has to in my opinion, it needs to support all the official game controllers. Personally I love the GamePad, and I hate the idea of seeing it dethroned and made optional, but if replaced by a dual-retina clamshelled NXP, then I’m all for it!

I’m also hoping that the NX will support multiple NXPs being used simultaneously. This should be possible as the NXP will be a client running the game itself, not a streaming device with game controls.

I’m hoping that the NX has native support for Wii U games, and that the Wii Virtual Console is available at launch – with several classic titles.

Finally, Nintendo should focus on getting third party involved from the get go, with at least a couple of high quality games in the launch lineup. The games don’t have to be exclusive to the platform; the important thing is that developers can target the NX without cutting corners, and show their dedication at launch.

I hate to see the Wii U go, but I love the idea of the NX having the power to support the fidelity seen on the Xbox On and PS4 at a time when both of them should have found their groove.