Pac-Man: The Idea
I’ve many abandoned solo projects, and I’ve worked at many different companies, but I’ve never built a complete game (or any piece of software) by myself and released it before. Knowing that the odds of my first attempt out the gate being a winner are low, I decided to dip my toes into the water by first focusing on something that I could reasonably finish within one or two months. Something that was modest enough in scope that one person could tackle all aspects of it.
There’s a common refrain told to aspiring game devs by those on the internet: take a classic game and clone it. I find cloning old games to be tiresome and boring, but it does have a positive aspect: the game design has already been done for you.
Game development is hard. You have programming, art, music, writing, etc. And lurking within all of that is the specter of Design which is the axis on which everything else turns. You can have a remarkably beautiful game with incredible music but if the gameplay is insipid then it doesn’t matter. By cloning a game you have the design part already figured out for you.
To ease my burdens a bit I decided cloning a classic wasn’t such a bad idea after all, if I could put my own spin on it. Take the general design and then enhance it and change it to suit my own tastes and creativity.
I thought about it for a while and inspiration struck: First Person Pac-Man.
Pac-Man is a cute and charming game when viewed from the top, but imagine being Pac-Man himself and how he must feel running through the cramped corridors of a maze with ghosts around every corner. It sounds creepy and unsettling, so I took the general idea of Pac-Man and put a horror spin on it.
The general idea is simple enough to be approachable and not overwhelming, but interesting enough to be fresh. And since I don’t need Namco knocking at my door, it’ll be inspired by Pac-Man but very definitively not Pac-Man.
Dimensions: 3
A majority of indie games are 2D, especially those done by a small team, because it simplifies a lot of things: art, math, asset pipeline, etc. But I actually find asset creation harder in 2D than in 3D. Making good pixel art (or any 2D art) is deceptively difficult while with 3D the computer handles the perspective and the shading for me, and the technical aspects of it align with my way of thinking. Animation, however, is frightening and to be avoided for as long as possible.
Engine: Custom
I debated for a while on which engine to use or whether to use one at all. I’ve dabbled with Unity and Unreal and Godot, and it’s amazing what you can do with them, but they always left a certain itch unscratched.
Maybe it’s because I’m a programmer at heart, or maybe it’s because I’m a self-flagellating masochist, but I get more joy and satisfaction out of writing things from scratch than I do using pre-built functionality in an engine, and if I need one thing to keep me going throughout this adventure it’s joy.
There’s an additional downside to using a game engine: complexity. If you need a hammer, they hand you a toolbox with a dozen different hammers as well as a nail gun, and now you’re wondering which hammer you should use or maybe the nail gun is a better choice. And sometimes they remove the nail gun after you’ve gotten really comfortable with it and have forgotten how to use a hammer.
I’ll re-evaluate this decision after building one game from scratch. If I determine it’s too much work, I’ll switch to using Unity or Godot.
Language: C
The language of choice among most game developers is C++ and that’s fine but I’m not a fan. I find it gets in my way and too much of my mental energy goes into thinking about how best to use the language rather than how best to solve the particular problem that I’m working on.
C, on the other hand, is amazingly simple. I can fit the entire language in my head and carry on with writing code.
- Should I use a class or a struct?
- Struct, it’s the only choice.
- Pointer or reference?
- Pointer, it’s the only choice (or use a handle).
- Does this statement call some function I’m unaware of?
- No. Function calls are explicit.
- What happens when this object goes out of scope?
- Nothing. It’s dumb data.
Et cetera.
Many people like C++ and that’s great. I wish I did but I don’t. So far the only thing about it that I miss is operator overloading for math operations. And namespaces are pretty nice also.
Some say that C++ is opt-in so just write it like you write C and add in stuff you want (e.g., operator overloading) but I find that just knowing I’m in C++ distracts me. Maybe it’s my own lack of discipline but I end up thinking about using other features anyway and end up going down a C++ rabbit hole, so it’s best for me if I just stick to pure C.
Some might ask: what about STL? Won’t I miss it? So far: no. I haven’t had the need for dynamic arrays or hash maps yet, but if I do need them in the future I’m sure I can write them myself. But I find static fixed-sized arrays get the job done more often than not.
Libraries: SDL
Libraries can be very useful but I decided to avoid using them whenever possible. I like the control of writing my own and I also enjoy the learning experience.
Currently the only exception is multiplatform handling because there’s absolutely nothing fun about writing Linux, Windows, or Mac platform code. I’d rather let someone else handle that garbage and all of the different edge cases for me.
SDL is a fantastic library that is industry-tested and runs on damn near everything, so that’s what I’m using. All I really use it for is creating a window, taking input, and sending out audio.
Graphics API: OpenGL
Platform-specific APIs like DirectX and Metal were out of the question from the beginning (I like openness), so the question came down to OpenGL or Vulkan.
I’ve used OpenGL quite a bit and dabbled in Vulkan, and I like the expressiveness of Vulkan, but it’s simply too complicated and long-winded for my purposes. In the end I’d be choosing it for all the wrong reasons rather than because of performance needs, so I decided to go with OpenGL which would allow me to get up and running quickly because it’s less verbose and I have a lot of old code I can rip out of abandoned projects.
Version Control: Git
When I first started programming I used Git and I loved it. It did everything that I needed and I became proficient with it. Then I entered the games industry and I was presented with a foreign beast named Perforce which went against how I had been conditioned to operate. Even now I’m still not comfortable with it and I find that I’m fighting with it more often than not. But I had no choice because Perforce is what was being used at work so I had to use it.
Now I make all of the decisions and so I can go back to using Git which is wonderful.
It’s true that Perforce is better at handling binary data, and its ability to lock data for editing is great when you have multiple artists on a team trying to create and modify assets simultaneously, but I find it to be horrible for code. So it’s back to Git. And Git LFS makes working with binary data (e.g., textures) better, although it isn’t as robust as Perforce but it doesn’t matter. I’m just one person.
IDE: Vim
At my old jobs the IDE of choice was Visual Studio and I found it to be slow and cumbersome once the codebase got large enough. I’ve also used JetBrains CLion and Rider which are much faster than Visual Studio but they still come with a lot of features that I don’t need.
Instead I’m just using Vim with a few plugins that give it certain IDE features that I find useful: code completion and smart syntax highlighting. I installed the following plugins to get it working:
|
|
I find that I’m much more productive in Vim than I am in an IDE because it has a reduced feature set, but I recognize it might not be viable for people working in codebases with millions of lines that were written by other people.
Build Tools: CMake
I’m developing on Linux so the natural choice of build tools is Makefiles, but I intend to also release the game on Mac and Windows as well, so it makes sense to use a tool that can build for multiple platforms with minimum fuss.
I’ve been using CMake for years and, while it has its flaws, it mostly works and it handles all of the multi-platform things fairly well so that’s what I’m using.
Art Software: Blender & Gimp
I’ve been 3D modeling off and on since I was a kid (mostly off, which is why I’m still really bad at it), and I’ve dabbled in a variety of different software, but my absolute favorite is Blender. It’s fast, it’s free, and it’s open source. It’s my second-most favorite open source project after Linux itself, and that’s saying something.
I also need to occasionally modify images and for that I’m sorry to say that I’ll be using GIMP. I find it hard to use and have never really liked it, but it’s free and open source so that’s what I’ll be using.
Music Software: 1BITDRAGON & Audacity
I don’t have much experience with music production so I wanted to use something that was simple and didn’t overwhelm me with knobs and features. Luckily I discovered a program called 1BITDRAGON which makes music production easier than most but still allows for creative expression. It’s not free but it is really cheap (I paid $12), and I like it quite a bit so far.
I’m also using Audacity for audio processing and editing once I export from 1BITDRAGON.
Task Tracking: Text Files
For a project of most any scope it’s a good idea to track your tasks so that you can see what you’ve done and what still needs doing. Most of my jobs have used either proprietary tracking tools or Jira. I don’t like Jira. I find it messy and hard to use.
Many people are fond of Trello but I’ve never used it. It’s free, which is nice, but it seems like overkill for a project that spans a single person. It’s also web-based which I don’t like because I don’t control the data and I can’t use it without internet access.
What I do like is plain text files. They’re lightweight, they can be read on any device, they’re easily transferable, and they play nicely with VCS diff tools. They don’t have to be ugly; you can use Markdown so that you can edit in plain text but render it prettily later if desired.
At the moment my task file looks something like this:
|
|
When I start working on a task I move it from Art/Music/Programming into In Progress and set the start date. When I finish it I set the end date and move it into Done. If I decide the task isn’t needed anymore I move it to Nevermind.
Simple. Maybe too simple. But it’s been working for me so far, and again, I’m just one person.
Level Editor: Blender
Part of what makes using an engine like Unity so nice is that they provide you with a level editor. You import your assets into your project and you can place them around the world and view a representation of your game from the engine’s perspective: models, lights, audio emitters, etc.
I’d have to write all of those features myself if I wanted them with my custom engine, and that’s out of the question due to time. Thankfully I can leverage a piece of software that I’m already using: Blender.
For small projects like mine, Blender works great as a level editor. It has a very rich Python API that allows for doing all sorts of cool things with it. You can place instances of your objects through a scene and tag them with your own metadata and use a custom Python script to massage the data into whatever form you need for export.
My export script serializes all of the mesh data into the same format that is sent to the GPU (position, normal, texture coordinate, indices). It serializes out the raw texture bytes (so no PNG loader is needed at runtime). You lose the PNG compression which makes your data files larger, but this isn’t a AAA game with 4k PBR textures so it’s fine. It also serializes object position data and will eventually serialize out light positions and sound effect locations.
Conclusion
That was a lot of boring text but future posts should be more interesting with code and visuals and things. This one was more about pre-production.
Last Edited: Mar 11, 2025