—

"CHAOTIC ERA"

A real-time strategy nightmare. 2020-2024.

What if we landed on another planet, and it actually really sucked?

For years I had been learning various aspects of game development, but I was never able to make meaningful progress. In 2022, I went full-time on Chaotic Era, a “realtime strategy nightmare” which fused genres and inspirations that have motivated me for years.

The end result had you crash land on an alien planet, struggle to find resources and power for life support, build defences and structures to support your population, and try to fend off wave after wave of horror.

CHAOTIC ERA CHAOTIC ERA CHAOTIC ERA CHAOTIC ERA

A core design challenge was the commitment to keeping everything monochrome. This meant not being able to rely on conventional affordances for building visual hierarchy, which turned into a forcing function to get really creative.

CHAOTIC ERA CHAOTIC ERA

The principles of the final visual language were built around highly-functional copy and consistent iconography that was shared between the 2D interface and 3D game world, making the two feel tightly coupled and highly responsive.

CHAOTIC ERA CHAOTIC ERA CHAOTIC ERA

The limited colour palette also meant having to be highly intentional about the contrast assigned to every element based off it’s functional importance.

Terrain and decorative elements needed to always sit behind important focal points, such as UI and units, which in turn were given ultra dark/light tones, motion cues, and distinct silhouettes.

CHAOTIC ERA CHAOTIC ERA CHAOTIC ERA CHAOTIC ERA CHAOTIC ERA

Chaotic Era on Steam

—

"BITFIELD"

Intergalactic warfare. 2024—Present.

In Fall 2024, I decided to promote a prototype into the next full-time project. At the time I had a 2D physics sandbox that integrated various kinematic equations found in Classical Physics that I read off Wikipedia.

I wanted to expand on the foundation with gameplay and themes explored in science fiction, such as the logistics of travelling over interstellar distances, and the warfare that would be necessary at the galactic scale.

BITFIELD Dashboard BITFIELD Techtree BITFIELD Dashboard2 BITFIELD Gameplay BITFIELD Editor

—

Modelling every piece from a 1/144 Gundam kit in 100 days

Summer 2024

GUNDAM 100 Cinematic

To soothe some of the stress that had built up during the chaos of the release of Chaotic Era, I decided to invest more time in 3D modelling, but wanted to commit to a specific project and timeframe to ensure there would be a valuable outcome.

I realized the Gundam hobby kit I had received the year prior was a perfect opportunity to learn Hard-Surface Modelling and if I did each piece day by day, there’d be a clear start and end date.

GUNDAM 100 Front pose GUNDAM 100 Front pose exploded GUNDAM 100 Back pose side by side GUNDAM 100 Cinematic 2x2 GUNDAM 100 Leg 2x2 GUNDAM 100 Chest 2x2 GUNDAM 100 Detail 4x4 GUNDAM 100 All

—

Emojivision

Emoji goggles for your phone. Summer 2022.

Emojivision

What started as a silly proof of concept in a Swift Playground turned into a realtime camera shader built in Metal with swappable character palettes, adjustable resolution, text export, and more. The project resulted in a short writeup on TechCrunch and a spike on my personal website, but didn’t go much further beyond the texts I’d receive of my friends’ cats in cat emojis.

Mona Lisa

—

Mr. Paint

Paint cubes in 3D. Summer 2018.

Mr. Paint

An ARKit experiment for placing different coloured box primitives in 3D spaces. I later added networking support using Firebase for allowing multiple people to contribute to the same 3D canvas from all around the world.

—

Redmin/Ranker

Score your comments before posting. Winter 2018.

Redmin/Ranker

In the pursuit of building the perfect mobile Reddit client, two smaller projects sprung out - Redmin, an OSS library for interacting with the Reddit API in a Swift-first way, and ranker.swift, a command line tool built on Redmin for pulling and labeling posts, feeding them into a local CoreML model, and predicting what score you may receive.

—

TV Plan

See different TV sizes directly in your home. Fall 2017.

TV Plan

I recently made the decision to get a new TV, but couldn’t settle on which size to get. One Saturday morning I came up with the idea to use Apple’s new ARKit tech to help solve this problem, and shortly after TV Plan was born.

In Summer 2017, Apple made it offical that they were getting serious about Augmented Reality. After seeing what the tech was capable of, I realized immediately this was something I wanted to get involved in. Since June, I’ve been learning and tinkering with ARKit to see what it’s capable of, but only recently has an obvious real-world use case come to mind.

An important opportunity I’ve identified has been for simple utilities which solve problems that couldn’t otherwise be addressed without AR. My problem was “will a 55 inch TV look too big in my living room?”.

Changing sizes

A lesson learned from this project was the effectiveness of lighting and shadows. Adding a soft shadow behind the TV resulted in geometry looking way less like a superimposed 3D mesh slapped on top of my camera’s feed, and more like something which was actually “there”. Although subtle and not immediately obvious, I expect improvements in light estimation to be critical to the success of AR in the future.

Here’s an example of the TV with and without shadows:

With and without shadows

As for next steps, I’ve been collecting feedback online and offline, and will be cycling quick wins into the app in the near future. For example, a common suggestion has been to add support for different TV sizes. Turns out my assumption that TVs max out around 75” was pretty naive 🤓.

—

Making “Giovanni”, a Game Boy Emulator for the Apple Watch

A Game Boy Emulator for the Apple Watch.

Making “Giovanni”, a Game Boy Emulator for the Apple Watch

Since getting an Apple Watch last fall, I’ve been disappointed by the lack of content. To help address this, I made my own game a few months ago (a 3D RPG), but obviously it still didn’t address the bigger issue. An idea I had was to port an existing catalog, and emulation made perfect sense.

The result is a surprisingly usable emulator which I’m calling Giovanni after the super-villain from my favourite Game Boy game, Pokemon Yellow. Ironically, I’ve only ever played the game on an emulator, as growing up I didn’t have access to the real deal. In a way, I feel this is my way of giving back to the community.

That feeling from accomplishing something you thought was too crazy to actually work is phenomenal. Here’s what Pokemon Yellow looks like on a Series 2 Apple watch:

Pokemon Yellow on Giovanni

One of the big challenges was to find the right balance between framerate and performance. As you can see, it’s a bit sluggish and unresponsive, but as a prototype, I think it answers the question of “is this possible”.

Pokemon Yellow on Giovanni

A Few Lessons Learned

For the sake of prototyping, I committed to doing as little unnecessary work as possible, so extending an existing emulator was my first approach. However as platform limitations and ubiquities surfaced, I discovered it was way less effort to just start from scratch and only pull in what I needed from open source projects.

My go-to emulator was Provenance, an open-source front-end for iOS. Having made contributions (albeit minor ones) in the past, I was semi-familiar with the codebase. My first approach was to have the watchOS extension ask iOS for a list of games names, then when a game was selected, download it and run locally. The first issue was with WatchConnectivity and Realm. Because Realm requires queries to be made on the main thread, that meant I wouldn’t be able to communicate with iOS unless the app was running, which wouldn’t be an ideal user experience. After investigating having querying Realm without WatchConnectivity and not having much luck, I realized Provenance offered a level of sophistication that wasn’t really necessary at this point.

Taking a step back, I realized Provenance (and others) are just thin layers on top of Gambatte —— where all the actual emulation was being done. After cloning the repo and looking at example code, I realized Gambatte was already extremely high-level, already offering support for loading ROMs, saving/loading, even GameShark.

Graphics on watchOS

Oh yeah, up until this point I was working under the fatal assumption that watchOS supported OpenGL or Metal (because of SceneKit). As it turns out, it doesn’t. I imagine if I did this investigation beforehand, it probably would’ve deterred me from even beginning. Nonetheless, I was too far in.

Recalling a Hacker News post about how some guys from Facebook got Doom running on watchOS not too long before, I discovered they were rendering to a UIImage using Core Graphics. Looking at what Gambatte was filling it’s video buffer with revealed that it too was just outputting pixel data.

I realized I didn’t know enough about feeding pixel data into a Core Graphics Context, so I created a Swift Playground to play around with creating images from a pixel buffer. As someone who learns best through trial and error (“what does changing this thing do?”), the ability to get immediate visual feedback was amazing.

CGContext prototyping in Swift Playgrounds

Immediately after this exercise, I was finally able to get something on-screen, but the colors were all wrong. By adjusting the byte order and composition options (and with a little more trial and error), I was able to get what finally looked right:

Pokemon Yellow rendering

For input, making a button on screen for every single input wasn’t desirable, so I took advantage of gestures and the Digital Crown. By allowing the user to pan on screen for directions, rotate the Digital Crown for up and down, and tap the screen for A, I was able to eliminate buttons until I was left with Select, Start, and B.

Pokemon Yellow on Giovanni

GIOVANNI controls

Touching the screen for movement isn’t a great interaction, but being able to use the Crown worked out a lot better than originally anticipated. Scrolling through a list of options is basically what the Crown was made for, and if the framerate was even slightly higher, the interaction could almost be better than a hardware D-pad.

I’m anticipating revisiting the project once watchOS4/next generation Apple Watches are out, just to see if there are any opportunities to get a higher framerate. Maybe Apple will even announce Metal for watchOS at WWDC this summer!

——

This project was a ton of fun to work on, and a great reminder that even though unknowns are scary, you really don’t know what’s possible without trying. The end result was way less effort and code than I originally anticipated.

I’m still deciding if it’s worth investing more time into improving performance, but for the sake of getting some feedback, I’ve open sourced everything on Github. If you’re interested in contributing feel free to submit a PR. For any thoughts or feedback, let me know on Twitter at @_gabrieloc or through email.

—

Building a Quadcopter Controller for iOS and Open-Sourcing the Internals

An app and open source library for flying white-labelled quadcopters. Winter 2017.

Building a Quadcopter Controller for iOS and Open-Sourcing the Internals

I’ve recently started getting into drones, and like so many others, it all started with cheap toy quadcopters.

For under $50, you can get ahold of a loud little flying piece of plastic, and they’re a lot of fun. Some of them even come with cameras and Wi-Fi for control via a mobile app. Unfortunately, these apps aren’t just low quality — they’re unreliable and frustrating to use, and look out of place in the modern era.

SCARAB

The goal was to create a haptic interface for 6DOF control in UIKit and CoreGraphics, which also yielded an open source core library (“QuadKit”) for allowing others to extend support for other models, and an open source UI library (“PadControl”) after garnering interest from the robotics department at Stanford.

A longer form writeup on this project was published 02/17 on HackerNoon.

—

SAQQARA

A 3D RPG for watchOS made with SpriteKit and SceneKit.

When I finally got around to picking up an Apple Watch in Fall 2016, one of the first things I noticed was a lack of real games.

After hearing about Doom running on watchOS earlier in the year, and Apple bringing game technologies to watchOS 3, I spotted an opportunity. Inspired by classic dungeon crawler games, I began working on what would become SAQQARA, an homage to weird DOS games from the late 90s.

While the tech was fun to play around with at first, computational limitations of the platform became apparent early on, bringing perfomance front and center during development.

With Instruments.app totally unsupported for watchOS, I had to more or less improvise with stopwatch-logging methods wrapping heavy operations to identify slow algorithms or inappropriate data types. All in all, an excellent reminder of easy it is to take for granted the (by comparison) ultra-powerful devices we keep in our pockets.

One of the bigger architectural decisions that had to be made early on was which maze-generation algorithm I would use. While prototyping gameplay early on, the first choice was depth-first search, which yielded unpredictable corridors which spanned the area of the map.

Depth First Search in SAQQARA

This technique was dropped not longer after, as corridors and no rooms soon became tedious in-game, and generating a map with an area greater than 5x5 units would bring the process above the system’s High Water mark, crashing it shortly after launch.

The second option was something closer to recursive division, which was not only far faster, but resulted in a good mix of big and small rooms, separated by short corridors.

Recursive Division in Saqqara

For version 1.0, I was adamant on shipping essentials, and adding content iteratively in updates. After being rejected by Apple the first 4 times, SAQQARA went live right before the holiday break. As always, a great reminder to RTFM.

What does “Saqqara” mean?

—

Archive

Space game prototype

Architecture, visuals, and interaction

Cleaning Game - Pathfinding

Small update on a prototype

Cleaning Game - Art

Small update on a prototype

Emoji Chess Keyboard

Play chess from any messaging app! Keyboard extension for iOS.

ALEC Korean-English Chat

A language exchange service. Universal iOS app, Rails backend.

MISSI0N

For helping friends coordinate. iPhone client, Parse backend.

Wobblr

A super simple Dubstep bass synthesizer.

—