How (and why) I made a game in Swift

Today I'd like to share a story of how I made a game in Swift. It will have nothing to do with inDrive, and frankly, it'll have very little to do with iOS. There'll be a little bit of Swift and some game development stuff that I've learned. Also, there'll be very little technical stuff, so i shouldn't be too complicated or boring. Well, I hope it's not boring.

Anyway. I wanted to make a game. The idea was simple - to make a platformer game for mobile devices. Of all the programming languages I had the most experience with Swift, and since the idea behind making a game was also to have fun and learn something new - why not go wild, unorthodox, and make a game with Swift, which is mainly used for apps.

Glide engine

Back in 2019 I stumbled upon a GitHub repo that really caught my attention - it was a game engine, for a platformer game, written in pure Swift. Holy cow, that was perfect, exactly what I needed. So, naturally, I looked into it, it all seemed a little too complicated for me, so I left it untouched until last year. Glide supported platforms Although its GitHub page didn't show any recent activity - it was still a nice option for the type of game I wanted to make. Glide in action

Glide had multiple platform support (Apple though), controller support and a full-fledged demo. More importantly - it had some kind of a documentation. For example, it explained an update loop - basically how different things are updated. That might come in handy. What the engine does well is handling cross-platform stuff. For example, making one image type to handle both NSImageView and UIImageView. Glide ImageView

Time to be creative

The first problem: Idea? I had no clue how to make games Except for that time I made a visual novel in Python that takes about 4 hours to complete, but I can't show it because it has too much cool and illegal stuff Fortunately, I have a friend, who, at the time, decided he was so interested in video games that he wanted to become a game designer. That was very helpful for me, so we decided to make the game together - I would do all the technical stuff and he would take the creative side.

Textures

After a while we realized that to have a game we need some design - textures, sprites, you name it. Luckily, the internet is a wonderful place with a lot of things, the best part - a lot of free stuff. Some designers are happy to share their work for free as long as you mention them, and since we weren't planning on making any money with the game - we didn't want to spend anything on it either. And a cool texture pack can improve a game visually. Just look at how different these two parts look. A tiny change of using a dimmed, kind of shadowy texture for the edges is a small detail, but details can make it so much better.

We found a great texture pack that fit our needs and from that point, with some help from ChatGPT, my friend came up with some game lore. You would play as a king who is saving his kingdom from evil pigs. The game would be called Oink Invasion. That's kinda cheezy, but I like it.

tvOS top shelf image

One downside from using free textures is that anybody can do the same - for example, I found a game on Steam that you can actually purchase that looks way better than what I made, but the reviews are mixed, soooooo. Download mine for free instead...

Anyway, my friend started to make some level mockups. I quickly realized that we needed a streamlined process where he could make game levels independently, send me some kind of a file, which I would use for the game build. It turns out that a lot of indie games are using similar technologies when it comes to textures.

Tiled map editor

For example: to make levels, I mean visually, we were using Tiled: it is a 2D level editor that helps you develop the content of your game. Its primary feature is to edit tile maps of various forms. My friend could use the textures we downloaded, draw a level, which would have all the details needed for a platformer game. You could export a JSON file that, conveniently, the game engine supported very well.

The level consisted of several layers, each for its specific purpose:

  • Ground layer is everything that has to do with collision - walkable elements, walls, sticky walls, etc.
  • Decoration layer is for the main stuff behind the player - walls, ground
  • The second decoration layer can be used for stuff that might be in front of the player - some platforms, columns and other decoration things
  • To make things even more strict - we had another layer for the tiny design elements like windows, banners, etc.

So, making a static level was pretty easy, really. Besides some work that had to be done to correctly convert the JSON that I had to the actual game level, it was easy. But adding some dynamic elements to the game was a bit more convoluted. Things like NPCs, collectables,, enemies, etc., all had to be done via code. So my friend would make these mockups and tell me exactly where everything had to be.

Alright, I hope this isn't too boring for y'all. Let's move to the cool part, shall we?

SpriteKit

Behind the curtain, the engine uses a special technology called SpriteKit. It might sound familiar because it's an Apple-made framework specifically for making 2D games. It's actually pretty cool in terms of what it can achieve, gotta give some point to Apple. SpriteKit Besides SpriteKit, which handles rendering and other 2D-specific things, the engine uses GameplayKit- another Apple framework, this one goes deeper into game development, like architecture, NPC behavior and much more. GameplayKit It all comes down to the user base though, at this point you'd rather make games in Unity, Unreal Engine or other frameworks that support multiple platforms, whereas SpriteKit and GameplayKit are Apple only.

But for its purpose it's alright. Without going too deep into the framework, let me briefly show you the building blocks that the game is made with.

  • First of all, we have Entities - these are pretty much any objects relevant to the gameplay - a player, npc, enemy, collectibles, platform, weapon, etc.
  • To have these entities do something we can add Components - these are some abstract features, like jumping, health, damage, collectibles.
  • To organize all these there are Scenes - these are basically View Controllers but in SpriteKit. Scenes must load before anything can actually happen, they have entities loaded into them, they can fade to black to show the next scene, and so on. Glide has these things subclassed, adding useful features that are not only specific for platformer games, but, for example, make it easy to set up controller support. With SpriteKit you can even build your levels right there in Xcode! Bet you've never seen that editor. Although spending even more time in Xcode doesn't sound too good... Besides, using Tiled editor for maps was way too easy to do it any other way. SpriteKit Editor

Another thing to keep in mind when making a cross-platform app is the UI differences. For example, a macOS game should have s Quit button while the other platforms shouldn't.

Debugging

In terms of debugging, SpriteKit is surprisingly similar to your everyday UIKit debugging. It even supports view debugging, which will surely come useful. App icons To make things easier I had two targets - release and debug, keep that in mind, it will come later. When I was making the levels work I noticed a bug in the engine - the collision frame for the checkpoint entity was always way too up. That means that when the player was above the checkpoint, while not being actually in the spot, the checkpoint would register a collision, and the checkpoint was saved. Thus, a level with a door in the bottom could be completed while standing above the finish checkpoint. That kind of broke the game there, we would either need to fix the bug or to make it so that the levels would always end in the top of the map. Fixing a bug That's where development stopped for a month or so. I tried fixing the bug, but couldn't do so. After a while I came back to the bug and, to my surprise, fixed it within an hour. Classic. I made a Pull Request and messaged the repo maintainer on Twitter since it was the only way I could. After a month I got a reply, and a while later - my fix was approved and I officially became an Open Source contributor. Open source contribution There was another issue I had that stopped the development for a while: when I was making the game I was mostly running it on macOS. But when I tried running it on a real device I was shocked to see around 30 FPS, and it dropped even lower when I had a lot of items on the level. It bugged me for quite some time, I tried everything with no luck. The fix was so simple I was embarrassed. Remember when I said I made two targets - release and debug? Well, I was running a debug version, and it naturally has a lot of stuff needed for debug, for example, all the collision frames that aren't usually seen can be seen. For every entity on the level the performance drops significantly, and when I ran a release build I had a beautiful 60 FPS game on a device. View debugger

Task management

Making a simple game turned out to be a very difficult task. And since I was pretty much by myself, I had to manage all the things I needed to do - there was a lot to add, some things had to be done from scratch, and there were a lot of bug. That's when I decided to try using a task manager. We all know what this is, but for some reason we rarely use this tool outside the workplace. I can have a separate talk on how I made a Kanban board for my personal tasks, but I'll save that for later. Trello task To be honest, I didn't know that even GitHub has this feature, so I used Trello as a simple task manager. Making tasks for myself, organizing the workflow and saving stuff for later helped a lot, I didn't have to keep everything in mind and could track my progress.

Figma

Apart from task manager, I used another tool that we all know - Figma. As a developer, I only use it to look at design mockups, I imagine you do the same. But learning how to do basic graphic design with it can really help, and it goes beyond programming, really. Anyway, I made an icon, a logo, a cover image for Apple TV, all with this one tool. Figma

Apple TV

By the way, Apple TV. Now that was really interesting. I've made apps for iOS, macOS, even played around with watchOS, but never tried tvOS. As I said, SpriteKit can run on tvOS, and Glide helps you with it. For the purpose of game development I bought an Apple TV (please don't tell my wife) because you can't even make a test build and send it to TestFlight unless you have the device with your Apple ID on it. Classic Apple. tvOS main menu But if you have one - you can even build for it wirelessly! Or you can use a tvOS simulator. It looks pretty cool! Besides, that app icon that you see in tvOS - it consists of 3 layers, making the parallax effect possible. You can test it out in Xcode too. By the way, the controls aren't so good if you want to play with the remote (I don't recommend the remote honestly, the controller works way better).

Publishing

When you make apps or games you tend to think that coding is the most difficult part. You expect to solve complex problems, find solutions to technical issues and so on. In reality coding was pretty easy. Long and tedious, sure, but it's alright. The most boring part of the whole process is, of course, publishing. Uploading separate build to App Store Connect, filling out all the necessary forms (for all the languages you support, in my case it was 3), and, of course, privacy policy. App Privacy Thankfully, there're a lot of tools that can to just that, and after a while you get your freshly baked Privacy Policy. You'll have to find a way to host that page too, keep that in mind. And just like that you're ready for your TestFlight group to test the app.

One more thing - nowadays you can add a new platform for your app - visionOS. I haven't tried it yet, but my guess is it can be opened up in a window and it's probably playable.

After that - you release it for the world to see 🤩 Best games of 2023

Check out the game: Download on the AppStore

October 16, 2023