The Right Tool for the Job

Posted 2018-01-21

If you hang around game development communities around the internet - for example, /r/gamedev - you would notice that certain questions are asked almost on a daily basis:

Making the decision to use one engine over the other, or a framework over an engine, can be paralyzing for some. Maybe some are afraid of starting off with one option and then feeling like they made the wrong choice. There are others who think they need to use a low-level framework over an engine because they need every bit of control for what they are creating, even though they may have never made a game before and have no idea what they actually "need". I've personally struggled with these issues in the past. Choosing the right tool for the job can be important and being able to vet your options properly to come to a decision is an important skill for any developer to have. That's why it's now time for some rubberducking-via-blog as I try to figure the technical stack for this prototype.

Goals

Deep down, I'm a curious person. I like to figure out how things work. For this reason, when making games I've always decided to use a framework and assorted libraries over an engine. Frameworks were a good level of abstraction for me.

When writing your own engine for a game project, you can end up spending quite a bit of time on tasks that aren't directly related to making the game. For example, the act of getting some text to render on the screen is much more difficult at low levels than one would think. When I was working on one early prototype of Tetris in Rust, I had difficulty figuring out how to accomplish this. While I was curious as to how font rendering worked, I didn't want to fall down a hole of digging deeper into this sort of stuff; I just wanted to render some text on the screen and continue on with my game1.

When I think to myself "What do I want to accomplish right now?", I think I want to make a game. And learn graphics programming. NO, BAD! See? This is hard. I really want to learn about graphics programming. The art people create with it is incredible. Sub-communities such as the demoscene are cool too; the marriage of art and technology is something I find interesting and would love to participate in. But with a full-time software engineering day job, it's hard to find the time and sometimes mental energy to get all of these wants done. So I have to focus and choose one thing to work on for the near future.

My goal is to make a game. It won't be some large, sprawling game - I have some ambitious ideas that are way outside my experience level that will need to wait for now - but it will be a serious attempt at making a game I'd want to play. No more toy projects! If the prototype doesn't feel right, I'll have to try again. If that doesn't work out, I'll take a break, try again, and repeat until it does!

With that hurdle cleared, it's time to reflect on what this game will be and what sort of technical requirements it will have. With those down, it should be easier to filter through engines and frameworks in order to find the right one.

My requirements

Like I said in the previous post, this will be a gameplay mechanic prototype (at first) of a 2D action RPG in the style of Quintet's Super Nintendo Games such as Illusion of Gaia and Terranigma. It will have a top down perspective. This is a gameplay prototype so I'll want the player character, a couple of enemies and some other unique hooks that I'll have to experiment with to find.

I've compiled a list of 10 tasks for this prototype, sorted in the order in which I should probably tackle them:

Depending on the engine or framework I choose to develop this prototype, the task list could either be quite difficult or moderately difficult to implement. Either way, I don't think it will be easy for me. Thinking about it is pretty exciting though!

From this list of tasks comes a list of requirements for our tools:

Some of the tasks are related to implementing gameplay mechanics and would probably be similar (in pseudocode) regardless of the tool used. The last three requirements of good documentation, a stable and well-maintained code base and being fun to use are pretty important and can easily disqualify some of my options.

With the requirements & tasks for this prototype defined, let's take a look at our options!

The Options

These are the options we will be looking at:

Unity & UE4

Both Unity and Unreal Engine are professional-grade game engines used by indies and AAA developers alike. I've never had luck getting UE4 running on Linux, so that's automatically out. Honestly, even if I had it working on my PC, I don't think I'd choose it as I don't need all the power that it provides.

Unity doesn't seem to have official Linux editor support; it's listed as "experimental" but I've actually had success running it in the past. Unity is a good game engine. It has a huge asset store which would make prototyping go by quicker in exchange for money. C# is a nice scripting language and the API offered by Unity seems pleasant enough. I'm not a huge fan of using the editor GUI though. I like to stay in a text editor when possible. I think I'd rather just use Godot over Unity3D as I prefer to use free open source solutions when possible. Godot also seems to have better 2D support out of the box. Maybe these are silly reasons to write these two options off but there are just so many tools available that I need to start cutting options off the list somewhere.

Does it meet our requirements? Yes.

Are these options going to remain on the list? No.

Love2D

Love2D is a 2D game framework that uses Lua as its scripting language. I've played around with it before and it's quite easy to get something up and running very quickly. It's cross-platform and offers many modules to interact with controllers, provide audio and physics, math libraries and anything else a game developer could want. I'd say it probably fulfills most of my listed requirements above. I'm not the biggest fan of Lua - writing medium-to-large size software in Lua seems a little intimidating. I won't cut it yet but it isn't at the top of my list of contenders.

Does it meet our requirements? For the most part. Lua makes this option easy to prototype with but I'm not convinced about the long-term effects of writing a large project with Lua.

Will this option remain on the list? Yes.

PhaserJS

I write a lot of JavaScript during my day job. At this point in time, it is probably the language I'm the most familiar with. For me, TypeScript makes writing JavaScript much more pleasant. I've used PhaserJS before for a few simple games and it was a pretty good experience. I'm not sure it has any advantages in prototyping over any other framework out there. It does work with TypeScript which would give me the ability to use a relatively lightweight framework with strong typing - a powerful combination indeed. PhaserJS v3 is close to being released at the time this post is being written while PhaserJS v2 has been given to the community to maintain. While PhaserJS v2 is quite stable at this point, I'm wary of situations where two separate versions of software with API incompatibilities are out side-by-side2. For this reason, I'm going to disqualify it.

Does it meet our requirements? For the most part; v2/v3 schism is concerning though.

Will this option remain on the list? No.

Godot

Godot is an open source game engine with an editor that closely resembles Unity3D. The fact that Godot is open source under the MIT license makes it quite appealing over Unity. In comparison, it lacks a few features such as the Asset Store3 but completely owning what you make regardless of whether your project makes $0 or $100, 000 is a good thing. It also has nicer support for 2D games out of the box.

Due to a Patreon campaign, some core Godot developers have been able to work on the project full time and as of the middle of January 2018, the final version of the eagerly-awaited Godot 3 is close to release. Coming with support for C# as a first class scripting language is a huge win. The original scripting language, GDSCript, is similar to Python in syntax. Python is a fun language but types seem to be very helpful in developing something with strict systems and rules like a game. There are also some nasty warts such as:

    func _on_discovered():
      get_tree().call_group(0, "guards", "player_was_discovered")

This code snippet taken from the official docs show getting the scene tree and then call the function player_was_discovered on each member of the group guards. Personally, I'm not a fan of all these references to groups and functions via strings so the news of C# coming to Godot makes me happy.

Installing Godot 3 with Mono/C# support on Arch Linux has proven difficult at this moment in time. No one has built any packages that would make it easy to install from Arch Linux's user package repository (AUR). After some finalging, I managed to get Godot 3 with Mono/C# support to build but trying to attach a C# script to a node would cause the editor to crash (There appears to be an open issue about this problem on GitHub). After trying to find a solution, I gave up and moved back to the stable Godot 2. Maybe once Godot 3 has had some time to stabilize, I'll check it out again.

Godot 2 would fulfill all of our requirements. It doesn't have as large of a community as Unity so finding answers to certain questions online can be more difficult. There is an active Discord group that is full of helpful people though and the devs are active there, on the /r/godot subreddit & on GitHub so I'm not too worried about getting help. It remains on the list as a top contender!

Does it meet our requirements? Yes.

Will this option remain on the list? Yes.

ggez

The first of our Rust-based options, ggez is one of the game frameworks I have the most familiarity with as I used it in my last project: a Tetris clone. It is modeled after Love2D, giving it a pleasant API to work with. v0.4 came out recently which added a bunch of features such as custom shaders, MSAA, sprite batching, and more. The documentation is fine and the library's main maintainer is usually active in the #rust-gamedev IRC channel. It doesn't fulfill some of our requirements such as tile maps, camera and UI but those can all be delegated to other libraries. It stays on as a contender!

Does it meet our requirements? For the most part, yes (No tilemaps, cameras, UI support).

Will this option remain on the list? Yes.

Amethyst

Amethyst is a game engine written in Rust. It comes with a built-in state system, an entity-component system, support for a scripting API, and multiple graphics backends. The API seems to be in constant flux as the team behind the engine continues to iterate on finding the best shape of their engine. The recent v0.6 release contains enough breaking changes to warrant a bunch of rewrites for older Amethyst projects. I totally respect the engine contributors for doing what is right for the future of the project but it is a little scary to hop on the Amethyst train at this point. I look forward to the day when I can use Amethyst from start to finish for an entire project.

Does it meet our requirements? At this point no; it isn't stable enough and the docs could be more fleshed out.

Will this option remain on the list? No.

Rust DIY Stack

The option that seems the most fun is also probably the worst to choose if one of my goals here is to actually prototype a game. It would involve building everything from scratch using various Rust libraries such as:

This option is probably bad for prototyping and potentially bad for building an entire game. But it also seems very fun, and if I did succeed, I'd end up with a decent 2D game framework that could be used in future titles. Additionally, as the author of own framework I'd have more information about the inner workings of my code and more easily track down bugs.

Does it meet our requirements? It is NOT easy to iterate with until something resembling a game framework/engine is built.

Will this option remain on the list? No- wait, yes- .....aaaaaaAAAAAAAAAAARGH!

And the winner is...

Writing this long post has helped trim some options off the list. I am left with the following:

  1. Godot 2
  2. ggez
  3. Rust DIY Stack
  4. Love2D

Godot 2 seems like the best tool for this job. GDScript makes prototyping quick but refactoring & iteration may be a pain due to the dynamic nature of the scripting language.

ggez comes in second place, being a Rust framework I'm familiar with and having most of the features I'd need to get going.

Due to my stubborn-ness/insanity, the Rust DIY stack comes in third place. Why? I don't know. I'm still attracted to the idea of DIY.

Love2D finishes off the list due to being a very nice prototyping tool. I'm not convinced about the refactoring/iterating abilities of the language for the same reason I'm skeptical of Godot.

My list is considerably shorter than it was when I started this post but even as I continue to look at it, I'm still not sure of which option to choose. So I've come to a decision: in order to truly get a feel of these options, I should attempt to implement the first task, "Render a simple tilemap", with each option. That should give me a better idea of what working with each of these options would entail. Do you agree that this is a good solution? Am I ruling an option out for silly reasons? Feel free to let me know in the comments!


  1. There are so many things I would like to spend time learning that it physically hurts to think about. Sometimes you need to focus on what you need to learn to accomplish your objective. Is this the right or wrong way to think about it? I don't know. [return]
  2. I'm looking at you, Python. [return]
  3. Personally, I'm not too bothered by this - but I'm sure some people would be. [return]