How It's Made
Since I've gotten a lot of questions about what Debug is built with, I figured I may as well write an article about it! I'll be covering not just which tech I'm using to build Debug, but also why I chose the tools I did. If you've got further questions, make sure to join our Discord!
Choosing a Language
- Publishing to platforms like Steam and Epic, whose revenue potential overshadows any platform that publishes web games.
That leads me into the first piece of the tech stack...
While I ultimately settled on Electron, I did review a couple other options...
- NW.js has been around since before Electron was released, but Electron's development ecosystem is much more robust. Solving issues with Electron is generally easier just because it has a larger userbase with more content written about it.
- Tauri and Neutralino are really interesting as well. They're written in Rust and C (respectively), so the overhead of building with them is minimal and apps tend to be very zoom zoom. That said, they also use the native OS WebView. That's fine, but it means you have to deal with browser inconsistencies (Edge on Windows, Safari on macOS, etc). Electron bundles its own Chromium with each build, so you can focus on building for the same web environment regardless of OS.
UI Is UwU
The first thing any user encounters when playing a game is UI. Loading screens, menus, settings... it's all UI. The web is brilliantly suited for building UI, so that's where I really started the development journey. I'm using React.js for managing UI rendering and interaction. While there are lots of other frontend frameworks I could use, React is the most mature of them with the largest ecosystem.
I'm also using Framer Motion to animate all of the panels and buttons that slide in and out of view, adding a lot of life to the UI.
Game Engines, Shmame Shmengines
We can get away with ditching a lot of typical game engine needs since we only have 1 character. The whole game is 2D, so there's no need for any fancy 3D tooling. I don't even need a physics engine. Instead of using something off-the-shelf, I decided to build everything from scratch. This was
probably definitely a bad choice, but I've been enjoying myself anyway. 😅
For rendering, I started out by building a custom renderer based on the one we'd built for the original version of the game. It was simple, but it solved a lot of traditional rendering challenges in novel ways.
Unfortunately it used Canvas2D which is quite slow, and it had become impossible to work with due to being a convoluted mess. I recently decided that rather than continuing down this path, I should shift gears and replace the old renderer with Pixi.js. It's been a dream so far. Pixi uses WebGL by default, which provides significant performance benefits over Canvas2D. 🤩
ngraph handles pathfinding much more efficiently.
As an aside, I'm also using
ngraph for a really awesome UI navigation experience when using a gamepad. I may write an article on it at some point. 👀
I'm still handling this one manually. I'm currently using the JS Gamepad API to handle controllers, and I've implemented a similar system for tracking keyboard keys and mouse movement/clicks.
Since the UI and the game engine need to share a fair amount of data, the state management decision was vital. It had to be fast, and it had to be simple. In the past I've invested a lot into learning and using libraries like Redux and MobX, but they're incredibly heavy and they get in the way of development a lot. I switched to using Zustand for a lot of projects in 2022, but even Zustand's relatively simple APIs provide enough footguns that it was slowing down my development.
Earlier this year I discovered Statery, made by the inimitable Hendrik Mans. Statery provides exactly the right amount of control for usage across different control paradigms. It's simple, but its simplicity actually makes it difficult to shoot yourself in the foot.
Wrapping It Up
Every piece of the stack has been chosen with care, each one playing a critical role in building the game. It's been a journey of learning, experimenting, and often just trial and error. But that seems to be what game development often looks like, especially when basically none of us have any idea hwat we're doing. 😅
Keep in mind: this absolutely is not the right tech stack for every game. That said, it's been a dream to use for building Debug. The technology choices I've made have allowed me to meet a lot of goals while overcoming all of the challenges I've encountered so far. And remember, at the end of the day, the best tools are the ones that enable you to bring your vision to life.
If you have further questions or want to discuss any of these topics in more detail, make sure to join our Discord! Thanks for taking the time to read about how Debug is made. Stay tuned for more insights and updates as I continue to develop and enhance the game. ❤️