🚧 App in Alpha. Features subject to change/break without notice. New Game Release!

New Game Release!

New Game Release!

Eric Augustinowicz
May 24, 2026 ⋮ The Kireji Project ⋮ 4 min read

At long last, I've finally reintroducing WebGU features into the Kireji web framework. That means we need a real game project to stress test it. Enter Orbital! Its a new - and very tiny - first-person shooter!

Fair warning: this game is currently largely in "developer art" mode. That means it doesn't look super pretty. Also, there is no mouse controls or mobile interactivity yet (although it does render nicely on mobile). Instead, it requires arrow keys and WASD to move and look around, respectively. There's also no "shooting" yet, just a disembodied first-person view running around a small map. But collision is working - and that was always going to be the hairiest part.

Finally!

I've been waiting a long time to bring 3D rendering and first person game mechanics back into my demo project. In a previous iteration of the project (a couple of years ago now...) I put up a very rudimentary WebGPU game. It had no textures, just vertex colors. You could jet pack around and there was basic gravity and collisions. WebGPU wasn't an official feature yet, so I was building and publishing the game through Google's Origin Trial.

I hadn't quite cracked the case back then on meeting the bigger design objectives of my framework - namely, the ability to efficiently achieve the maximum possible compression for runtime variables in order to store them in the URL. This allows the URL to act as a save game file that can be bookmarked and shared. Alas, I had to remove the WebGPU features entirely while I continued rapidly prototyping different paradigms for the framework.

Finally, that struggle is over. I'm very happy with the broad strokes of the Kireji framework's design at this point. The latest iteration of the framework made it very enjoyable to model the game parameters and get everything up and running quickly. I've spent a lot of time ironing out the exact state management details I wanted for all my web projects in general and didn't have the chance to bring back the "fun" part - building a real 3D game - until this past weekend. Looking back at that old WebGPU game's code, I can see clearly that the groundwork has paid off.

I've spent the last three days refamiliarizing myself with everything I need to get this project up and running. That includes the glTF file format, WebGPU features, WGSL shaders, render pass management, along with world building, game design and my favorite part which is creating 3D environment art (modelling, UV mapping, texture painting, etc). I'm creating all of the art using free, open source software (Blender and GIMP).

glTF in particular is incredibly easy to work with in this context because it's designed to be easy to parse and to work directly with WebGPU.

It's the Real MVP (Minimum Viable Product)

The purpose of this game is firstly to demonstrate and advance the development of the Kireji web framework. If it turns out to be a fun and exciting game with cool lore, that will be awesome, but that's icing on the cake.

The art style for the game is "90s realism": unlit shading and very low-poly geometry with low-res textures that rely on hand-painted or baked lighting. This art style appeals to me because of the deep nostalgia that I feel when I work on it. It is actually more immersive to me than modern photorealistic games because it leaves more to the imagination. It also means that all of the game data is small enough to download and render quickly.

This game currently represents the target minimum viable product for the Kireji web framework's integrated game engine. I probably won't do much physics in this game. Just a basic walkable collision area with static and sometimes interactive props and maybe collectables or perhaps puzzles with doors and keys. Design is still under way.

The Importance of Collision

The philosophy underpinning the Kireji Web Framework is that every single valid application state is directly addressable by URL and that no invalid states can be reached. That means there can't be a URL that links to the player character interpenetrating the wall. As a result, the player's position cannot simply be give by an { x, y, z } tuple.

Instead, the world must be quantized. The volume in which the player can roam must be turned into discrete points. Then, a two-way minimal perfect hash function must exist which can efficiently address all of those points and no others. I used one inch as the smallest unit of precision for the player's location. This means every inch of the valid, walkable space is assigned a unique natural number with no gaps or duplicates. This results in the most efficient possible way to store the player's location.

Figuring out how to implement this in my framework was a challenge that I largely solved while creating another game, a 2D top-down pixel art game called Glowstick. Oddly enough, the most challenging aspect turned out not to be quantizing the walkable space. Instead, it turned out that enabling wall sliding (so the character doesn't just freeze or get stuck when they reach a wall) was the single hardest part of the process. The solution ended up being to use ray casting to simulate physical interactions between the character and the collision mesh.

It turned out to be a cinch to extend the existing 2D game collision component used by Glowstick into a 3D collision mesh component. And testing the collision in Orbital turned out to be far easier than it was in Glowstick. Now that I have glTF support, I don't have to manually plot collision mesh triangles and then rebuild the game in order to find out if they look the way I imagined them in my mind. Instead, I'm modelling whole game levels in Blender (both collision and render geometry) and can one-click export it all as a single glTF package that contains all of the data for that level.

Conclusion

Look forward to steady updates as I decide what the story and mechanics of the game will be! Will there be achievements? Will there be enemies? Will there be hidden collectables? You'll find out when I do.