Introductory Apple Developer Resources

I wrote up a list of Apple (iOS, iPadOS, macOS) developer resources that are not directly from Apple. (Perhaps obviously, if you are wanting to get into developing for Apple’s platforms, developer.apple.com should probably be your first stop. This was written for someone who wanted links to other sites they should know about.)

I figured since I spent a bit of time compiling these, I’d re-post them here.

  • If you still feel like you’re getting a handle on Swift syntax, (or just want to brush up and/or clarify optionals), I highly recommend the Unwrap app. It was instrumental for me when I first started learning Swift.
  • Similarly (on the topic of Swift syntax) https://swiftly.dev/ is a nice “cheat sheet” style site with a lot of topics. (Made by a local dude!) He also made https://iosref.com/ which is another “cheat sheet” for various device-specific info.
  • All Apple developers should at least know there is a book on Swift Language syntax. Importantly, it’s updated for every new version, and you probably don’t want the version that’s currently in beta, so be aware of which one you’re reading. Also, that link is to the overall swift.org documentation, which has a bunch of other semi-interesting stuff listed too.
  • The Swift Package Index should probably be the first place you look for swift packages. Apple is a sponsor.
  • I read iOS Dev Weekly when it hits my inbox every Friday. Might not be as much beginner content there, but it’s definitely the main way I “keep up” on interesting blogs and viewpoints. The intro usually touches on any news I should be aware of as well. (The author is also the maintainer/founder of the Swift Package Index.)

Some blogs that I find myself on regularly (with really nice articles):

  • NSHipster is kind of in-between a blog and a reference site. It used to feel more important than it does to me now, but it’s still a really nice set of articles on some of the tricker topics you might encounter.
  • Hacking With Swift is a source of SO MANY good articles. I have this one on SF Symbols bookmarked, as it’s the definitive guide, IMO.
  • Swift By Sundel has a TON of excellent articles, and this link (the “Discover” tab) feels especially full of “required reading”. The author uses a very nice static site generator written in Swift, called Publish, on Github.

There are also a couple of relevant and local (to the Twin Cities, where I’m based, in Minnesota, USA) developer meetups:

  • Our local Cocoaheads chapter merged with a meetup.com TCiDev group several years back. They have a joint Slack that has a not-zero number of posts per month (but it’s close).
  • SwiftMN is sort of the new-kid on the block. It obviously didn’t exist until Swift came about, and I was a late Swift convert (didn’t start using it until version 4), so I’ve only been to a few meetings. They have a mostly-dead slack also.

Introducing the Hexagon Grid Generator

I created an app called Hexagon Grid Generator. It’s open source, runs on iOS, iPadOS, and macOS, and makes it easy to draw hexagonal grids.

Hexagon Grid Generator

In short, Hexagon Grid Generator is two things:

  1. An open source example project (on GitHub it’s called SKHexGrid) for how to use a Swift package called hex-grid to generate hexagonal grids in various configurations.
  2. An easy (and fun?!) way to draw hexagonal game boards.

Here’s some text from the newly re-worked About screen in the application:

There are a couple of other uses imagined for this application (outside of serving as a nice example for the HexGrid library):

  1. You can configure and then Save images of hexagonal grids for use elsewhere. (For example, you might configure a grid for a board game played on a hexagonal grid, save it, then find it in your photos library and print it from there.)
  2. You could also use a grid to play some basic games pass-and-play right here inside the app. There are many games on Board Game Geek playable on a hex grid without much necessary equipment. Here are links to a couple of lists:
        • games played on a hexagonal grid (of any size), with single color markers/pieces/tokens
        • hexagonal territorial games with placement/capture but no movement

why am I just writing about this now?

So yeah, I think this first released in the app store back in March of this year (2023), although it had been on GitHub for almost a year now. I’m only just getting around to writing about it.

I guess I took a break from working on it for a while after Blither came out, but I’m back to thinking about it again, and I have a long list of things I want to make it do. You can see that list in the project README, but it’s a big bullet list that’s not really in any sort of order. I’ve written more about this below.

How did this come about?

While working on the app for Blither, I obviously needed to draw some hexagons on the screen. I had done this at least a few times previously, so of course the first thing I did was go look at my old code. The most extensive project with hexagons was of course Catchup (RIP earlier this year :sad:), but when I opened that up, I found that the hexagonal drawing was quite specific to the app, and not really all that extendible to different sizes or shapes of hexagonal grid.

I was disappointed by this revelation, and really wanted to use a library that could draw a multitude of different sized grids without too much extra effort. First-thing-first was to look to see whether such a thing already existed.

When making Catchup (and possibly even before!), I had been aware of the quite extensive tutorial on drawing hexagonal grids written by Amit Patel (Red Blob Games). That website is, as far as I can tell, the definitive guide on the subject. There are even links to other libraries, and it was there, in the Swift section, that I first found reference to the Swift package called hex-grid, that I ended up using for Blither.

So, while evaluating hex-grid, I still hadn’t quite decided what iOS framework/library I would use for drawing. Catchup uses UIKit, and I’ve used that professionally for over a decade, so it’s definitely the one I’m most familiar with. The only demo (at the time) for hex-grid was written in SwiftUI, which is Apple’s hot new declarative UI library, so I spent a bit of time with that, and realized the demo was quite limited. It really didn’t show off most of the features of the hex-grid library. (I’m also not sold on SwiftUI, but I did use it for all the menus in Blither as well as the menus in SKHexGrid, so I guess I’m coming around.)

I was starting to become familiar with hex-grid, and I decided to experiment with using SpriteKit , which is a 2D game engine/framework/library created by Apple. I’ve always avoided it because a) it’s proprietary to Apple, and b) UIKit is plenty capable of drawing a bunch of stuff really performantly, but at the same time, it has some nice capabilities, and I’d never used it before, so… why not?

Before long, I realized my “test” project (which I’d made specifically to easily switch around which grid is drawn) was a much better example of what hex-grid could do, and as I’d been in contact with the developers of that library a bit (mostly creating issues and asking them to add features for me), I showed it to them, and they promptly added it to the README.

One thing I’m really proud of creating for the application is all the different ways you can configure the coloring of the hexagons inside the grid. This is functionality that is unique to SKHexGrid, and not something that comes from the hex-grid project. (This is a candidate for pulling out of this project and contributing to that one, but it just sounds like a lot of work to me.) There are the following options for shading grid cells in the application:

grid shading types built into Hexagon Grid Generator

There is also a random color shading, but I didn’t picture that here. Each of these (aside from single and random color shadings) required their own algorithm, and were pretty fun to write. I only just thought of another shading type that might be fun, so I added it to the README.

What’s next for this project?

I did just yesterday submit the latest version (v.0.4.2) for app store review, so that should come out shortly. In it, I added the ability to draw and configure dots in the center of each hexagon, as well as lines between each of those center points. Just to illustrate, here are some example hexagons showing off those new features:

grids showing the new “center dots”, and “lines between center dots” features

As I said earlier, I have a long list of things I want to make the project do. I’ll just list a few of them, roughly in the order I want to work on them.

I really want to allow you to save the grid that you’ve customized, so the next time you load up the application you can see it again. This will let you toggle between different grids you’ve created, or save a “game in progress” that you’re playing with the app. But the serialization of colors makes it all a bit annoying. (SwiftUI uses a different object for colors than UIKit or SpriteKit, and it’s not serializable for some dumb reason.) I also think Apple’s new SwiftData framework is going to make syncing your serialized hexagon “save files” via iCloud a no-brainer to implement, and I’m kind of eager to play with that, so I might hold off on this feature until that is released along with the new iOS in the fall.

I think the next thing I’ll actually work on is showing coordinates not on the hexagons themselves, but as a sort of “key” along the side of the grid. This is common if you are doing any sort of annotation of your games, and should be highly configurable. Currently the cell (individual hexagon) coordinates are configurable, both in how they are displayed, as well as which coordinate “style” to use. But I’d like to be able to show the “axial” coordinate style both as two numbers (as it’s used in the library), as well as with a single number and an alphabetical character. Additionally, it would be nice to be able to “rotate” which side shows the coordinates, but I’m not yet sure how I would do that, so we’ll see.

After showing coordinates along the edges of the board, I’d also like to be able to show arbitrary colored borders for the entire grid. This is because one of the kinds of game most commonly played on hexagonal grids are connection games (like Hex). In connection games, the goal is to be the first player to have an unbroken group of your own pieces from one side of the board to the other. Or, as in The Game of Y, between 3 sides of a hexagonal board. Incidentally, showing the lines between hexes, makes the kind of board that is typical for The Game of Y possible, because (as in Go) you typically play your pieces on the intersections of lines, as opposed to inside the grid cells.

Anyway, if you’ve read this far, you are probably in the target market for this kind of application, and you should go download it now!

Download on the App Store

On being a self-taught programmer

This post was written this morning in response to a post on dev.to asking about how self-taught programmers got their first jobs. I have told versions of my career path so many times that I think I wrote all of this in about 20 minutes. But I was thinking just now that I’m not sure I’ve written it all out like this before, so I’ll reproduce it here just for posterity.

I’ve been working in tech for well over 25 years. My career path has been long and winding, so I’ll try and give just the highlights here.

I did take a class in Basic in Jr. High school, and an Intro to C in college, but it was while I was in college, as an English major, that I began to teach myself html. This would have been 1996 or so, and I was president of our juggling club. I just wanted to update the webpage for the club, and that’s when I started to learn.

Key take-away for getting a job as a self-taught programmer: When you’re learning, be sure to pick a project or projects that you’re passionate about! It will be so much easier to complete them, and when you inevitably talk about them, that passion will only work in your favor.

Really, I just had small changes I wanted to make to that site. I needed to add myself to the list of “club officers”, and change the meeting times periodically.

Take-away 2: It’s much easier to make small changes to an existing project than to dive in to a large project “from scratch”.

Eventually, I started working on websites for various projects in the English department. One was a grant-funded research thing, and did not have html anywhere in the requirements, but I decided to post our findings / research as a webpage. That led to a very part-time job for another English professor, and that in-turn led to working at the student-run newspaper, writing html for a new “microsite” for the A&E section every week. That was almost certainly my first real job in tech, though it was a student position, and only 10-16 hours per week.

When my financial aid got screwed up at the end of 1999, I just dropped out and it only took me a month or two to land a full-time tech job (it was in the middle of the dot-com bubble). That job was “front-end” work, (html & javascript) and ~2 years later the company merged with another company, and 2004 or so I was the last person remaining from that original. By that time I knew I wanted to do back-end development, or what I considered “real programming”.

Take-away 3: Never stop learning. Try new things when given the opportunity, and you might find you enjoy some things more than others. You can totally shape your own career!

Once I started looking, I had a couple of job offers, but I ended up taking a job with some of my previous co-workers, and the idea was for me to do 50/50 front-end/back-end work. But I never really did much front-end work after that.

Take-away 4: Almost every job I’ve ever gotten has been because I knew someone, or was just in the right place at the right time.

Around 2007 I decided I could teach myself flash, just long enough to make my first video game. (I followed a tutorial on how to make Tetris, then modified it to have very different rules.) Around that time I started attending meetings of our local Twin Cities chapter of the IGDA, which I found very inspiring. I did my first public speaking, talking about my Flash game, and it seemed pretty well received!

Take-away 5: If you can, working on side projects is almost always rewarding. It’s especially important to get them to the point you’re not afraid to show them off, and put them in your portfolio or resume. (I do think portfolios are more important for folks who are self-taught than for folks with comp/sci degrees.)

Toward the end of 2008 I decided my next game would be for the iPhone. I spent a lot of nights and weekends, and I think I really leveled-up my programming working in Xcode and Objective-C. (I fell in love with strongly typed languages.) About 3 months later I released my first iPhone app in the store.

Around 2011 I’d been attending lots of meetups related to App development, and I’d worked on several projects, both personal and for my employer. (But it was still mostly web-dev at my day job, even though my passion was clearly for mobile.) I gave several talks at a group called Mobile Twin Cities, and the founder of that group had a mobile consultancy, and he recruited me.

Take-away 6: Find user-groups in your area that are relevant to the work you want to do. Attend them and (ideally!) find a way to give a talk. (Or at least address the group for a few minutes. Most groups have time for announcements.) Putting yourself out there, especially in a way that shows off your skills/abilities, can be crucial to landing any job in tech.

I think I was only at that company for 6 months before another merger was announced, and a year later, I found myself no longer writing mobile apps, but doing macOS desktop application development instead. I lined up a contract gig, (fortunately a very flexible one), and gave my notice.

They convinced me to stay a whole month before leaving, but in 2012, I began working freelance/contract, and I’ve been my own small consultancy ever since. I’ve even managed to work on a bunch of games! (Though my passion is definitely still mobile, I’ve done some VR work, and I’m currently very excited to work on some projects in visionOS.)

I someone finds this helpful.

Apple Vision Pro – the wait is over; the wait begins

I’ve been waiting patiently for Apple to reveal their headset for at least 5 years now, and as of WWDC 2023, that wait is finally over. A couple of weeks later (last Tuesday), the developer tools dropped, and I finally got a chance to start working with the frameworks and applications that Apple has created for making content on their new headset.

I’ll be eagerly exploring these frameworks and playing with this tech at least until the headset is covering my eyeballs, and (hopefully) for years after. There’s literally so much here that they devoted over 40 (admittedly short) WWDC talks to the topics, (with some overlap, sure, but not as much as you’d think). I have done a fair bit of VR development in the past, and while it’s been a few years, (and I’m sure there’s been some improvement in that time), to me, Apple’s APIs seem like the most flushed-out and easy-to-use way to develop 3D applications that I have ever seen. The only downside I can imagine is the vast amount of new frameworks to learn. There are seemingly a lot of ways to approach the same problem, or similar problems anyway, and I could imagine that being daunting for a lot of people. Fortunately, the documentation is quite good.

I imagine I’ll be writing about this topic a bunch in the next few months, and for my first post on the topic I’m going to just document some of my findings about the coordinate system in visionOS. I’ll jump right in.

position coordinates in immersive space

So I’ve been doing some programmatic drawing experiments on visionOS, and as anyone who has ever drawn things on a screen knows, one of the first things you need to know is:

Where is the center of your drawing area, or x: 0, y: 0, z: 0?

In short, when you open an Immersive Space in visionOS, 0,0,0 is positioned directly beneath you.

While the immersive space remains open – even while you move around within the space – 0,0,0 doesn’t move. But if you close the immersive space, and re-open it, 0,0,0 will have moved to a new location and rotation, again directly beneath your feet, and rotated to face the same way you are facing.

So, because the coordinate space will always appear in the same orientation as you, the following are always true (when you first open the space):

  • -x is to your left, and +x is to your right
  • -y is down, while +y is up
  • -z is forward, and +z is backward (behind you)
    I’m not sure I love that last z-direction decision, but it’s how it works.

Note that animating a transform is as easy as this code snippet:

.gesture(TapGesture().targetedToAnyEntity().onEnded { value in
    var transform = value.entity.transform
    transform.translation += SIMD3(0.1, 0, -0.1)
    value.entity.move(
        to: transform,
        relativeTo: nil,
        duration: 3,
        timingFunction: .easeInOut
    )
})

That example is from the WWDC video Develop your first immersive app.

I have a long list of things to explore next, but at some point in the near future I’ll be exploring drawing and transforms and coordinate spaces in what apple is calling “volumes”. (Volumes are 3D windows, or bounded boxes, essentially.)

How Blither uses the coordinator pattern and SwiftUI together

I never have enough time to work on the games that I make. So when I am working on them, I want to stay focused on the game screen, and spend as little time as possible writing the other boring (but still necessary!) screens for the App. Apple’s SwiftUI framework is very easy to use, and if you don’t much care about making things pixel-perfect, it can sure save a lot of time.

I am not yet convinced that SwiftUI is all that great at navigation, however. I feel like I only just got used to coordinators in UIKit (admittedly many years ago now), and maybe I’m still in the honeymoon stage with them or something.

So for my latest game, Blither, and somewhat by extension this open source Hexagon Grid Generator that I released, I’m using SwiftUI for all the straightforward UI, SpriteKit for the “interesting” views (game and grid), and UIKit mostly just for its UIViewControllers.

In Blither, I have a single UINavigationViewController, and a class named AppCoordinator that manages the navigation stack. It looks like this:

public final class AppCoordinator {

    public enum Route: Int {
        case about
        case appIcon
        case back
        case game
        case mainMenu
        case newGameConfig
        case options
        case rules
        case stats
    }

    public let navigationController: UINavigationController = {
        let controller = UINavigationController()
        return controller
    }()

    public func navigate(to route: Route) {
        if let presented = navigationController.presentedViewController {
            presented.dismiss(animated: true)
        }
        switch route {
        case .about:
            let viewController = AboutViewController()
            navigationController.pushViewController(viewController, animated: true)
        case .appIcon:
            let viewController = AppIconSceneViewController()
            navigationController.pushViewController(viewController, animated: true)
        case .back:
            navigationController.popViewController(animated: true)
        case .game:
            if let topVC = navigationController.topViewController, topVC is GameViewController {
                // already showing the GameViewController, so pop first
                navigationController.popViewController(animated: true)
            }
            let gameViewController = GameViewController(coordinator: self)
            navigationController.pushViewController(gameViewController, animated: true)
        case .mainMenu:
            if let topVC = navigationController.topViewController, topVC is MenuViewController {
                return // already showing the MenuViewController
            }
            let menuViewController = MenuViewController(coordinator: self)
            navigationController.pushViewController(menuViewController, animated: true)
        case .newGameConfig:
            let configVC = PlayerConfigurationViewController(coordinator: self)
            navigationController.present(configVC, animated: true)
        case .options:
            let viewController = OptionsViewController(coordinator: self)
            navigationController.pushViewController(viewController, animated: true)
        case .rules:
            let rulesViewController = RulesViewController(coordinator: self)
            navigationController.pushViewController(rulesViewController, animated: true)
        case .stats:
            let viewController = StatsViewController(coordinator: self)
            navigationController.pushViewController(viewController, animated: true)
        }
    }
}

That may look like a lot, but if you look closely, almost every switch case is the same. The AppCoordinator instance is created in the app delegate’s standard didFinishLaunching function:

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    /// The root coordinator for the app.
    var appCoordinator: AppCoordinator?

    /// The main window
    var window: UIWindow?

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        let window = UIWindow(frame: UIScreen.main.bounds)

        let appCoordinator = AppCoordinator()
        self.appCoordinator = appCoordinator

        window.rootViewController = appCoordinator.navigationController
        window.makeKeyAndVisible()
        self.window = window

        Blither.setup()

        appCoordinator.navigate(to: .mainMenu)

        return true
    }
}

All of those View Controllers getting created in the AppCoordinator are UIHostingController subclasses, and look almost exactly like this one for the main menu:

public final class MenuViewController: UIHostingController<MenuView> {

    private weak var coordinator: AppCoordinator?

    init(coordinator: AppCoordinator? = nil) {
        self.coordinator = coordinator
        let menuView = MenuView(coordinator: coordinator)
        super.init(rootView: menuView)
    }

    @MainActor required dynamic init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

If you’ve worked with SwiftUI and UIKit together before, you’ll recognize the UIHostingController, but even if you haven’t, all you really need to know is that MenuView is a standard SwiftUI View, meaning it’s dramatically fewer lines of code to add something like a button. And because it also holds a reference to the AppCoordinator, the definition for a button can look like this one:

                Button("Read the Rules", action: {
                    coordinator?.navigate(to: .rules)
                })

When that’s tapped, the coordinator pushes the RulesViewController onto the stack.

If I wanted, I could get rid of the coordinator reference, and do something like this:

                Button("Read the Rules", action: {
                    (UIApplication.shared.delegate as? AppDelegate)?
                        .appCoordinator?.navigate(to: .rules)
                })

…but I don’t like how that looks quite as much, and it also closes the door on dependency injection.

Hopefully you can appreciate how simple this all is! I’ve been pretty happy with how easy I found it to create new screens using this framework. Let me know in the comments or over on mastadon if you have done something similar, as I’d love to hear about similar approaches.

Blither for iOS

Last week I launched an app for my board game Blither. I’ve written about Blither on this blog twice previously, the first time describing Blither’s rules and a bit about how and why it was created, and the second time talking more about some basic play strategy. I was particularly proud of Blither as a game when I first designed it, and I am still pretty happy with it.

After launching the app, I spent a bunch of last week improving it in a lot of ways, and I recorded a video introducing the app and showcasing some of those changes on Sunday:

As you can see if you watch the video, I was (and still am) especially excited about the “high score mode” (which I’d only finished coding-up that day).

For now, the app is just $0.99 (USD). I’ve got a long TODO list in the project’s README, but I’ve already said semi-publicly that I’d like to increase the price when I hit certain milestones:

  • I’ll add $1 to the price when I add an actual interactive tutorial (that’s probably next up)
  • another $1 if I can get the AI up to at least “giving me a challenge” level
  • and +$2 if or when I add asynchronous multiplayer (almost certainly via GameCenter again)

I’d also like to add some leaderboards for that “high score mode” I mentioned. We’ll see.

2022 in Games Played and Created

2022 was the 4th year in a row that I kept track of all the games I played. This is the 4th recap I’ve written on or around new year’s, and I’ve only just created a category for them if you care to go have a look back through the others. I hope to keep up this tradition as long as I’m alive. But no pressure.

My Games Played in 2022

I won’t write so much this year about my method of keeping track. Suffice to say, it’s a “manual” collection, so obviously it has its flaws.

First, the numbers.

  • unique game titles: 352
  • days I logged at least one game played: 365
  • game titles logged only once: 193
  • journal entries about specific games: 30

Top 10 games

(by number of days they show up in the log)

  1. Flow Free: Sudoku: 244 days
  2. Good Sudoku: 186 days
  3. Picross s7: 144 days
  4. Picross s8: 83 days
  5. Picross s genesis: 67 days
  6. 7 wonders architects: 55 days
  7. New Frontiers: 49 days
  8. Jump Drive: 49 days
  9. Innovation: 49 days
  10. Azul: 41 days

Top 10 games, including platform, without BGA games

(…and making a special check for days I played Picross.)

  1. Picross (Switch): 297 days
  2. Flow Free: Sudoku (iOS): 244 days
  3. Good Sudoku (iOS): 186 days
  4. Elden Ring (PS5): 35 days
  5. Cell to Singularity (iOS): 31 days
  6. Really Grass Cutting Incremental (web): 29 days
  7. Vampire Survivors (Steamdeck): 23 days
  8. Jetpack Joyride 2 (iOS): 18 days
  9. Borderlands 3 (PS5): 18 days
  10. Horizon Zero Dawn (PS5): 14 days

Observations

I stopped playing both Good Sudoku, and Flow Free: Sudoku after getting the “played for 365 days in a row” achievements. I don’t expect either of them to show up on next year’s list. Obviously this list has a lot of Picross in it, because I still mostly just play that when I’m doing my 20-40 minutes of cardio in front of the TV. I do let myself skip the workout on occasion, and it’s definitely more likely if I’m feeling sick. I think that explains most of the days I didn’t play it.

[Update/Addition on Jan 2nd]

My friend August asked “Do you have a favorite game this year and why is it Picross?” I realized that kind of analysis is maybe something this post was missing, so here is my response.

I do love Picross, but I’m not sure I’d even put it in a top 10 list. It’s my go-to workout game because it fires all the brain cylinders (meaning my workout passes without the clock-watching that ensues otherwise), and does that without any need for spacial awareness that can cause me to fall off the trampoline.

My favorite of the games I played in 2022 is probably Elden Ring (35 days, PS5)  just because of how sucked-in I became even as I lambasted it. I wrote several journal entries about it, and ended up loving it in the end, even as I reached a saturation point where I decided I never need to play it again.

I also loved Stray (9 days, PS5) and Horizon Zero Dawn (14 days, PS5), both of which I played to completion in 2022.

Probably my favorite indie game of the year was Tinykin (2 days, Xbox). Super interesting that my log only shows that I played Tinykin on two days! I definitely beat the game, and even remember stretching out my playtime by intentionally veering toward completionism toward the end. (I may have just forgotten to log it some days? Or maybe it really is that short.)

I also really liked Nobody Saves the World (10 days, xbox).

I did have a phase this year post-steamdeck where I got back into action puzzle games, and played a lot of those for a few weeks. Notable favorites are Lumines (8 days), Petal Crash (7 days), and Mixolumia (6 days). I only logged Tetris Effect on 5 days (probably during that same period). Note that none of those games were “new to me” in 2022 except for Petal Crash. Just like books, I tend not to return to games unless I remember really loving them, so those are all favorites.

Platforms by number of games

  1. BGA – 80 games on 231 days
  2. Playdate – 56 games on 54 days
  3. iOS – 53 games on 310 days
  4. Steamdeck – 46 games on 90 days
  5. Web – 30 games on 43 days
  6. Tabletop – 23 games on 31 days
  7. Xbox – 20 games on 69 days
  8. PS5 – 13 games on 84 days
  9. Pico-8 – 12 games on 8 days
  10. Switch – 11 games on 298 days
  11. Quest – 7 games on 7 days

Platforms by number of days

  1. iOS – 53 games on 310 days
  2. Switch – 11 games on 298 days
  3. BGA – 80 games on 231 days
  4. Steamdeck – 46 games on 90 days
  5. PS5 – 13 games on 84 days
  6. Xbox – 20 games on 69 days
  7. Playdate – 56 games on 54 days
  8. Web – 30 games on 43 days
  9. Tabletop – 23 games on 31 days
  10. Pico-8 – 12 games on 8 days
  11. Quest – 7 games on 7 days

Platform Observations

Poor VR. I never pay attention to it anymore. (I didn’t even preorder the PSVR2… I’ll buy it if it looks like any of the games are going to be amazing, or if they suddenly give it backward compatibility with all the OG PSVR games.)

I was really excited about the Playdate for a while there. I’ll talk a little more about that later. I’ll probably get back into it again if they release a Season 2 of games.

The Steamdeck is now my favorite gaming platform. I don’t have any free HDMI ports on my TV, or I’d be playing more of it there, probably, but in the mean time I do very much enjoy it as a handheld. It obviously helps that I have a library of over a thousand games to choose from on it. (Built up over years and years of bundles and various sales, but also I feel no qualms about paying “full price” for any game that I feel moderate confidence I’ll find the time to play.)

BGA

Board Game Arena was where I did the majority of games playing this year. My game log says 80 games (unique titles) played on 231 days, which is obviously wrong on both counts. I was initially surprised it wasn’t more days, but then I realized that’s definitely a consequence of how I’m doing my logging. I currently only log BGA games on the day they have been completed. This means if I play a single game (of Azul, for example), but the turns stretch out over a week, it would only get one entry, even though I played my turns every day. Last year I logged every day that I took any turns in that game, but it was too much logging, and I felt like it gave too much weight to async games.

For 2023, I’m definitely going to change it up again, but I’m not sure exactly how. I might actually just log that I played some turns on BGA, and not worry about what games. Or maybe I’ll try and just log any game that I’ve not yet logged that year, so I have a complete list.

It’s definitely less important, because BGA does a great job keeping track for me. You can see all my BGA stats at this link: https://boardgamearena.com/gamestats?player=1486543&opponent_id=0&start_date=1641016800&end_date=1672466400&finished=1

  • BGA “tables” (total number of games played): 614
  • Games won (victories): 328

BGA Most played games

  • 7 Wonders Architects: 77 games
  • Jump Drive: 62 games
  • Innovation: 55 games
  • New Frontiers: 51 games
  • Azul: 47 games
  • Splendor: 38 games
  • Stone Age: 22 games
  • Space Base: 18 games
  • Race for the Galaxy: 16 games
  • King of Tokyo: 15 games
  • 6 nimmt!: 15 games
  • Gizmos: 15 games
  • Nova Luna: 10 games
  • Oust: 10 games
  • Caverna: 9 games
  • Thrive: 9 games

Caverna and Gizmos get special shout-outs, because both showed up relatively late in the year. Gizmos is definitely in my top 10 games right now, and when it first showed up on BGA, I was playing so many games of it that I kind of burned out on it, and had to stop for a few weeks. Now I’m back to a regular game or two of it going at all times. Same with Caverna, though it’s not as high on my want to play list, it seems like it is for everyone else I play BGA games with on the regular.

I think 7 Wonders Architects and Jump Drive are only at the top because they’re very short games, and my friends Mike and Jason both like 7 Wonders a lot, so we have a continuous game going with the three of us, and we finish a game once or twice a week, I’m guessing.

My Game Design Journal in 2022

My game design journal had 40 new entries in 2022. (Sadly there were 4 months with only one entry, including December. And 5 months with only 2 or 3 entries.)

Of those entries –

  • 2 were from dreams (providing some evidence my subconscious is still thinking about new game ideas, even when my conscious mind can’t be bothered)
  • 11 were continuations – additional thoughts or implementation notes related to previous ideas

And the most disappointing stat:

  • only 1 entry resulted in a new (digital) prototype

There were a few entries that could have been flushed out into new physical game prototypes, but my guess is that I played physical games much less this year than in the past. (Although 31 days doesn’t seem like that few, tbh.) Anyway, I think a significant percent of my interest in designing physical games has waned with the realization that I just don’t play games physically that often anymore. This is a bit weird, because I play digital versions of physical games literally every day, but it’s something I’m pretty sure my brain is doing.

Game Development

My current work schedule allows for somewhere between 3 and 12 hours spent working on games per week. When motivation is low (as it has been most of this year), it’s usually on the lower-end of that range.

Mostly, I spent this entire year working on a digital version of Blither, an abstract strategy board game I designed a couple of years back. I’m happy with Blither’s design, and a few times I’ve considered trying to hand it off to publishers. I think it could work particularly well with some kind of animal/nature theme, but so far at least, the digital version is just all geometric shapes.

Swift for Game Development

A significant amount of the effort that I’m counting toward Blither’s development has actually been spent less on the game itself, and more on the toolchain for writing games in Swift. I spent several weeks – maybe as much as a month of my development efforts – just exploring cross-platform strategies for Swift and game development. The primary take-away is that it is relatively “easy” to write a swift “wrapper” for projects written in C, so there are many. Of interest, both Raylib and SDL (both of which exist in the cross-platform game development “space”) each have at least a few of these projects on GitHub. Unfortunately, while it is easy to write these wrappers, getting them to a state where they are easy to use requires more effort, and in my estimation, that narrows the selection considerably. “Easy to use” might be assumed to include “well documented”, but sadly it does not, and none of the projects I found would qualify there. Furthermore, lack of documentation definitely means lack of instructions for how to actually publish a project using any of these libraries across various platforms and OS targets. For a while, this was definitely my objective. Pick a lib, write a simple game, and document the hell out of getting it running on at least: MacOS, Windows, iOS, and Android, using the same codebase.

Unfortunately, of the aforementioned Raylib and SDL library wrappers, Raylib itself doesn’t support iOS (at least without plugins/modifications), and SDL is slightly more difficult to use, and possibly as a consequence, in general the wrappers I found for it were not as far along, or anyway, not as easy to use.

Another related project is re-writing my generic game library in Swift. There was never all that much code to GGM, so the actual rewrite was never the hard part. The original GGM used UIKit for rendering, so there is a Swift version that does that, but also now there is a version that uses SpriteKit, and a (not-quite-flushed-out-yet) version written in “pure Swift” without any rendering included. Ideally, I’d use that version to write “plugins” for platform-specific rendering engines, and this could be another path to writing cross-platform games. That last version, while unfinished, is already significantly more code than the others, and I got a bit hung up on what its internal API should look like. The other versions don’t really concern themselves with non-game UI, but this one would have to, and that’s a big old can of worms that I’ve barely opened.

Hex-Grids

Speaking of GGM, the original library supported hexagonal grids – it was used for the Catchup app – but the way it implemented them was very specific to the Catchup codebase, and felt a bit tacked-on. So when I went to add that detail to GGMSwfit, I got sidetracked a bit on what hexagonal grid coordinate types to support, and how many hexagonal grid shapes to make it easy to create. I dug around a bit, and ended up playing a bunch with a “pure Swift” library called Hex-Grid (https://github.com/fananek/hex-grid/) that does pretty much all of the hexagon-specific stuff that I wanted GGM to do, and I contributed to that library a bit. Mostly, I wrote a demo app that uses SpriteKit and allows you to visualize grids of arbitrary size and shape and swap out their coordinate types on the fly. (This also helped expose a few bugs in the lib.)

The current app version of Blither doesn’t use any flavor of GGM, instead it uses this Hex-Grid library, and it is also using SpriteKit for drawing. This means it can only target platforms where SpriteKit exists. (iOS, iPadOS, and MacOS, I believe. But – so far at least – I would need to make some not insignificant changes to make Mac Desktop work.) I’m still toying with the idea of making an abstraction layer for the SpriteKit-specific code, so code could be shared with other platforms.

Playdate

Another project I worked on this year was a match-4 game for the Playdate called Matching Machine (https://devforum.play.date/t/matching-machine-devlog-and-demo/7682). I “released” a version on the Playdate developer forums and then promptly lost interest in finishing it up. This year’s MinneBar happened while I was working on it, and it was the first time I’d been to an in-person conference in a few years. I gave a talk there about Playdate development in general.

Non-Game Development

Conferences

MinneBar was great (as usual), and while my family is under no illusions that the COVID-19 pandemic is over, I still ended up going to two other in-person conferences this year: Eyeo and FOSS-XR. Eyeo has been one of my favorite conferences whenever I attend, and this year’s conference came with the sad announcement that it will probably not continue – at least in its previous form – going forward. I somewhat regret not making more contacts and acquaintances while attending over the years, but it’s an intimidating crowd full of amazing digital artists and creative coders. I brought Thrive to one of the evening events this year, and introduced it to lots of new players, so it’s not like I was entirely invisible.

Foss-XR was a surprise to me, having found out the week before that it was going to be held only blocks from my apartment in downtown Minneapolis. I didn’t know what to expect, and after a rocky start with poor AV, ended up really enjoying the experience. I also reported on it a couple of weeks later at the only in-person MNVR&HCI meeting I attended this year.

Webdev

I haven’t done any REAL web development since around 2011 or so, but I still host a half-dozen or so websites (including this blog). Many of those are using WordPress, and I’d love to move those to Jekyll, or (maybe ideally) something similar to Jekyll but written in Swift. (Publish is the only one of those I know about, but I haven’t done any due diligence yet.) I guess I’m officially stating this as a goal for 2023. I did already export some blog content, and then import it into Jekyll at some point in 2022, but I would probably have to do that again if I were going to migrate “for real”. (I helped out with a transition of this sort when the IGDATC website moved from WordPress to Jekyll, but I didn’t personally handle the export/import.)

I also got really into reading about ActivityPub after moving from Twitter to Mastodon in 2022, (my mastodon account is @grid@mastodon.gamedev.place) and I thought seriously about starting a project to support ActivityPub/Mastodon interop from Vapor. I have played with Vapor a few times since I found out about it, and did so again for an afternoon when I was thinking about this. It’s more likely that I’ll just create some static files to point a domain or two to various Mastodon accounts, but I haven’t even done that yet, so it’s obviously not a huge priority for me. I do think federated social networks are here to stay, and I hope the trend of user-owned content creation continues. I will help it along if I can.

AI

Like everyone else, I was gobsmacked this year by text-to-image AI. I spent a not-insignificant amount of time reading about the technology, and even went so far as to install Stable Diffusion on my M1 MacBook Pro. Initially I wanted to use it as a pipeline for making game art, but the many important discussions happening around the ethical implications have me cooling my jets a bit. I did also use Midjourney to generate character portraits for a D&D campaign, and that was an easy win. I will definitely continue to keep my eye on the developments related to this technology going forward.

Contracting

A few years back (even before the pandemic) I realized that working on games professionally left me without interest in working on my own games, so I re-focused my contract work back on native iOS. I am still waiting patiently for Apple to release a headset, and hope to find some crossover contract work when that happens, but until then, my bread-and-butter is mostly won with plain old iOS app development. I’m very happy with my current contract, and it should take me at least partly through 2023. There is other work on the horizon (they would like me sooner than later – and I appreciate their patience), but for now I’m trying to focus mostly on one contract at a time.

Something I haven’t talked about publicly in a while is how much time I’m devoting to contract work versus my own game development. But to talk about that, I need to first talk about how much time I spend working. Period. It’s a hard number to pin down, because there are several contributing factors. How many hours do I work each day? And how many days? How many of those are billable?

In general I aim to bill my clients for 20 hours per week. Ideally I would be working a 40 hour week, and that would leave 20 hours for gamedev, but it’s hard to say whether that’s actually the case. It’s only possible if you include hours outside of my normal workday, because for the last few years those tend to only be 6 or 7 hours long. Previous to this year, I’d have said it was very common for me to put in some extra hours in the evening after the rest of my family has gone to sleep. This year, I would say that’s definitely been the rare exception rather than the norm. So my guess is that I’m putting in a work week that’s more in the order of 30 hours than 40. However, there have been a lot of saturdays and sundays that were essentially a normal workday for me, (but always devoted entirely to gamedev), so maybe it averages out. Again, it’s really hard to say, because I don’t track the time that isn’t billable.

Generally on days when I get started working on a game project, it’s rare that I will want to stop working on it and go back to contract work, so that day is usually then relegated entirely to gamedev. For this reason, I usually try and always start my work day with contract work. Then if I’m itching to do some gamedev, I’ll switch to it later. But I don’t give myself that restriction if I’ve already billed 20 hours that week. That used to mean that most of the time Fridays were days for gamedev, but pretty regularly (this year anyway), I’ll be in the middle of some client task, and want to keep working on it more than I want to switch tasks and work on a game project. So usually my gamedev is on the weekends, with the occasional Friday afternoon thrown in for good measure.

Contracting gives me the freedom to turn off the clock whenever I want, and take an hour or an afternoon off just to run some errands or even unplug or play some video games. It’s relatively rare that I take a whole day away from “work”, but it’s very common for me to take an hour here and there, which has the consequence that it’s very often Friday morning and I haven’t yet hit my 20 hour mark. But I really do enjoy what I do. I can’t really count the number of times in the last 3 years I’ve remarked that my job is one of the things that’s keeping me sane. I find programming to be a much-needed catharsis when the rest of the world is an assault of illogical thinking and frustrating politics. I get to solve puzzles all day, and that’s not an exaggeration. And as anyone who knows me will attest: I do love puzzles.

Book notes

I’ve been keeping a log of books I read much longer than the log of games. The first iteration of this was just a text file that followed me from computer to computer from sometime in high school until several years after college, when unfortunately I fell out of the habit. Then I used LibraryThing for a couple of years, and then Goodreads for at least the last 10 years or so. (I’d really like to switch to Bookwyrm, and I have an account at bookwyrm.social, but I haven’t fully transitioned yet because their importer has been turned off due to overwhelming demand on resources. I did try to convince a friend to set up a new instance for us, but that hasn’t happened yet.)

Last year I marked 64 books read on GoodReads. Mostly I just read science fiction (and fantasy, and graphic novels, which I’ll admit are such easy reads that they make me look like a more voracious reader than I probably am), but a few days ago, I wrote a thread on Mastodon about some of the game-related books in my library that I recommend, and I thought I could link to that thread here.

Notably, the last book included in the thread is one I haven’t marked as “read” on goodreads yet. I’m still working my way slowly through Ben Orlin’s book Math Games with Bad Drawings, which I’ve been meaning to recommend here.

Conclusion

I wish everyone reading this a wonderful new year in 2023!

Foss XR 2022

Around the beginning of October, I found out that there was going to be an open source XR conference (called FOSS XR) in my neighborhood. I attended, and took some notes. I posted some of my notes in the MSPGameDev slack, and Zach, who runs our local VR & HCI meeting, asked if I would give a short recap of my impressions. I put some slides together, which I’ll embed below the video. There were some technical difficulties getting started, so the beginning of the video is actually as I’m getting into my second or third slide.

A play date for Playdate owners, or Getting Started with Playdate development

I signed up to host what I’d hoped would be a kind of Playdate user group at this year’s MinneBar, but I also prepared what I imagined to be a ten-minute talk on the various ways to get started making games for the cute little device. My ten minutes easily stretched to 42. (Apologies about how hard it is to hear the Q portions of the Q&A.)

You can watch it on Youtube:

What have I been up to lately?

Writing some Lua

I’m working on a playdate game. It’s sort of a mishmash of tile-matching mechanics, and attempts to get the crank working with various ideas I’ve had for square-grid manipulation. I’ve sort of thrown a bunch of ideas together and what I need to do now is decide how I’m going to focus it into an actual game. Currently there are both realtime “action puzzle” levels and also some more discreet puzzle levels that are not really designed so much as some tutorial and proof that puzzles could be designed pretty easily. I’m tempted to write a generator so I don’t have to do any level design, but I’ve gone down that road before, and once I’ve got the generator, I still have to pick levels that seem fun, and that’s usually where I crap out. I’ve mostly been focused on the action puzzle mode, which is what I really want to be the game, but if I’m being honest, I think the other mode seems maybe slightly more fun right now. I think I might try and think of ways to make the levels not be realtime, but still have recursive puzzles.

Playdate game screenshots

As I touched on in my last post, toward the end of last year and into the beginning of this one, I spent a bunch of time building some framework stuff for iOS grid-based games. I only mention this because now I’ve re-built a lot of that stuff in Lua for Playdate dev, which has me thinking lately about how I could re-use it in Pico-8, and maybe also in Love2D. The Love2D aspect is interesting because I could then target/publish back on iOS (in addition to desktops), bringing my development path pretty much full-circle. (I still definitely prefer Swift to Lua though, and have been daydreaming a bit about writing a Swift package that generates my Lua for me… that’s probably silly though.)

But no Unity

After publishing Thrive Digital last fall, I have yet to even install Unity on my new MacBook Pro. I think I may be “done” with Unity as a platform. (At least until I have another VR or AR project, but possibly not even then.) Unfortunately, this means a whole lot of my “in progress” projects are kind of abandoned at this point. That includes remakes of Action Chess and Go Tetris (which I’d been planning on calling Action Go when I do finally finish it), as well as a handful of prototypes and game jam games.

One of the jam games I thought was particularly promising and that I always meant to finish up was called Tetro-Buddies, and it had excellent art by August Brown.

Tetro-Buddies game jam art made with cardboard by August Brown

Also in my Unity “in-progress” folder is Puzzle Prison, a game made for and targeting Google cardboard (no relation to Tetro-Buddies). I more or less abandoned Puzzle Prison around the time the first Oculus Quest came out. It was very near completion for a while, and I should probably have just released it. I actually showed Puzzle Prison at a number of events, and for a while it was my go-to demo whenever I wanted to show off VR on my phone. (It was a 3DoF Chain-Shot clone where the “puzzle was all around you”.)

Puzzle Prison screenshots

I have been meaning to blog about Puzzle Prison for years. I even had an amazing OST made by musician Paths (who was calling himself DR00 at the time). The gameplay was… fine, but nothing special. I had all these ideas for making it more of a unique take, (mostly I just implemented a few additional block types, but I entertained plenty of other ideas) but none of the ideas really improved the gameplay much, and I think that had a lot to do with my never releasing it beyond TestFlight.

Now this article has become more about what I’m not doing than what I am, so let’s get back to that.

And some Action Puzzle game cataloging

The other thing I’ve been spending a lot of time on lately has been action puzzle game curation and Taxonomy. I have a relatively long blog post I’ve been working on, so I won’t go into it here, but of course action puzzle game taxonomy is a topic I’ve written about, and even felt compelled to present about, in the past. One piece of this is that I put together a relatively long list of action puzzle games on IGDB, mostly to make it easier to get feedback from fans of the genre about any that I may have missed or just don’t know about while putting the list together. I think there are a ton missing from the last 10-20 years, and I’d love for this to be as close to comprehensive as possible, but I’m not including any sequels or games that just don’t add anything to the design-space (although of course sometimes that judgement is subjective, so I’m erring on the side of inclusion).

One thing that’s decidedly missing from the IGDB list are smaller indie and hobbyist games. The list started not on IGDB, and the original is more comprehensive, and includes a bunch of iOS games not found on IGDB, a well as Pico-8 games. Of course it is possible to add games to IGDB, but I’m not sure that’s the best use of my time. The Pico-8 curation has been especially fun, because I recently bought an Anbernic RG351V, and have set it up to play all my favorite Pico-8 games, including some excellent Action Puzzle games like Pushamo, PullFrog, Bondstones, Drop Blop, TetraChess, and Sirtet. I definitely feel like I’ve barely scratched the surface on finding them.

Anyway, look for that blog post… sometime soon-ish.