Technical implementation of a game engine

I don’t really regret building my own game engine given how much I learned from the experience. I do, however, feel that the quality of my game has suffered from not using a framework such as Phaser.js and if I ever [hopefully] make another game one day then I’ll be going with something like Unity instead. Why all the negativity, you ask? Let’s take a look at the implementation and see.

I chose Javascript to write the engine and game logic as that’s the language with which I was most familiar. I also used a few libraries/tools, which helped me greatly -

  • RequireJS
  • jQuery
  • Underscore
  • Class.js
  • Grunt

RequireJS and jQuery are pretty explanitory, and I just really like Underscore because standard Javascript has such rubbish methods for iterating collections. Class.js is just a slightly nicer looking wrapper (if you don’t know what you’re doing) to implement inheritance in JavaScript. It was already there from the existing game skeleton and if I wasn’t a bit of a n00b at the time I would have never used it and stuck with Prototype. Grunt was used later down the line to minify and zip up the source code for deployment. I also started the project with the best intentions of TDD’ing the whole thing, but with a lack of experience at the time and an eagerness to see results in my short time-frame this never quite happened.

So here’s a class diagram of the the main bones of the game. I’ve excluded some modules as not to over-complicate the diagram but I’ll explain the additions in a later post.

The early Javascript module dependencies of Cosmic Badger

It’s fairly self-explanitory, the Main module contained a MenuLoader responsible for drawing the menus (this wasn’t always the case but I’ll cover that in a later post). The MenuLoader was also was responsible for creating a Game. I’m not sure that was the best design decision, it’s implementation just had the least time impact a very late stage of development. Like I said, I’ll cover that later. My Game module consisted of an [initially, 1d] array of entities which made up the enemies (which were just obstacles that weren’t bound to 32px grid co-ordinates). The terrain data was just integers stored in a 2d array. The integers corresponded to an image’s position in a large tilesheet and the array slot corresponded to the tiles position in the game world, which was tracked by the Camera. This data was stored in the Map module, which is essentially a glorified var containing the JSON game config.

Both the terrain tiles and the entities had their own Sprites (in the case of terrain, a single Sprite), some of which had Animations and Boundries. The Boundry was just a simple box with a width, height and offset co-ordinates from the Sprite image. The Renderer was responsible for drawing the entities and tiles in the Game, the Updater was responsible for updating the Player co-ordinates (based on input from the Controller) and also for checking any boundry collisions via the CollisionDetector. If there was a collision then the Game state would be updated accordingly.

Right, so what’s that red box all about? This box is lined with the bleak tinge of remorse. These are my god modules that got way too big with too many responsibilities. They are very tightly coupled and more a reflection of my inexperience at the time. With more software design knowledge, proper tests and the ability to smell when the code needed refactoring then this problem could have been avoided. Changing parts of this code was time consuming, but I knew it well enough to handle it and I’m just glad I never had to show it to anyone in an interview. To quote BuildKite founder Keith Pitt, it’s not legacy code, it’s founder code. I wrote that when I founded the company!

Building a game engine from scratch is a really difficult problem. If you haven’t been in the industry for a long time then there’s going to a be a lot of things that you don’t account for; and unless you’re a AAA game development company, my advice right now is to avoid building your own game engine altogether and just focus on building a great game. There’s no shame in sparing yourself the hard work and using something that someone else has already built for you. Having said that, if you just want to learn the ins and outs of game development then doing this is a great exercise.

What about the LevelEditor, you say? Calm down, I’ll tell you about that next.