Hey, someone asked me to describe the process and challenges with building https://www.konkr.io/. It’s a pretty damn wide topic worth a number of blog posts, but let me at least share some quick notes on what I wish I knew before I started.
For context, this was my first real Phaser project, I mostly do web dev so not an experienced game developer at all. So take anything that resembles advice here with a huge grain of salt .
- dat.gui is amazing when you need a quick temp UI for testing or playing around with things
- Texture packer is awesome for automatically generating texture atlas from your png files
- BM font can be used for generating bitmap fonts from your system fonts; I kind of hate the tool, horrible UX, but didn’t find anything better
- I started the project from this template GitHub - yandeu/phaser-project-template: 🕹️ Phaser 3 - Starter Template with TypeScript and webpack. and never regreted it. Maybe there are cooler options now (swc/esbuild?) but to this day even with the project becoming quite big this setup gives me smooth and fast dev experience.
- Which reminds me yeah, typescript. I love TS and honestly can’t imagine completing a project of this scope in plain js. The complexity will grow and you will need to rewrite and refactor a lot, and typescript makes that actually possible without breaking everything. I’m sure I would spend like 20x the time debugging various stupid bugs without it (well not really, because I would just quit at some point).
- Don’t try to understand the Camera object API intiutively, you will suffer . Some methods deal with camera position on screen, others with world coordinates, some take into account zoom and some don’t… Spend the effort to go through the API and make sure you know exactly what you’re doing when you use it.
- If you want to use HTML for parts of the UI, you might want to go all in on this - mixing phaser objects with DOM elements in one UI gets messy in my experience. Just be aware of the limitations, mainly that you can’t render anything with phaser on top of DOM elements. For Konkr I mostly use Phaser even for UI elements and I’m happy with it now, but it took a lot of effort and I kind of built my own UI framework in the process lol. Going all in on building the UI in something like React might have been a better choice.
Scene.tweens.timeScaleis awesome for debugging tweens - go into bullet time and see exactly what’s going on with your messy transitions
- If you are returning a sprite/image into a pool, make extra sure there are no tweens still acting upon it, that can lead to really bizzare bugs after you reuse that object somewhere else.
- Second largest source of glitches was accidentally allowing multiple tweens to act on the same object. I am paranoid now and usually attach dedicated controller classes to UI and game world objects which ensure there can’t be any conflicting tweens playing on them simultaneously.
The process of building a game:
- Building a game that expands on an existing proven gameplay loop (in my case proven by Sean O’Connors Slay) was a huge boon and helped me stay focused and confident in the end result during the many months it took for the game to actually become fun to play. If you don’t have this, you should definitely throw together some quick and dirty prototype to prove to yourself that the core formula of the game is fun before you dig into it any deeper.
- Be ready to throw away days or weeks of work when you find out the feature just doesn’t work out the way you expected, isn’t as fun as you thought, or is fundamentally flawed. Pretty sure that’s an inevitable part of the process and falling for the sunk cost falacy is one sure way to doom your game.
- A lesson I learned with software development in general is don’t try to design sophisticated abstractions before you deeply, intimately understand the problem you’re solving. When you’re out of your comfort zone, just go for the most straighforward solution that kind of works and run with it until until it becomes too painful, then rewrite it. Almost every part of Konkr got completely rewritten at least once, and the only thing I regret about this is spending too much time upfront trying to come up with the perfect future proof solution form the start. The result was often an overengineered mess that of course had to be rewriten later anyway.
Design patterns that seem to be working out well for me:
- one scene for game world, number of dedicated scenes for various UI layers
- Scenes are not the main controller of the game. I use custom classes i call Screens to represent each “screen” in the game (like main menu, level select, play screen, map editor, etc.) - these orchestrate the individual scenes and contain most of the application logic - Scenes on the other hand are pretty dumb and only concerned with displaying and animating stuff, which makes them reusable across different Screens (so I can for example use the same world scene for the actual gameplay, map editor and level preview).
- a global event bus for UI events; buttons and other interactive elements are not wired to any particular method call, they just trigger an event and the currently active screen handles it
- UI scenes usually derive their look and behavior from a single state object that is updated by the controlling Screen. This coupled with the event-driven architecture leads to a redux-like way of managing state in the application and it made things much less buggy once I began to stick to it.
Thanks for reading, hopefuly you got something useful out of this .