Dec 3, 2022 - 2D vs 3D

Comments

Once upon a time I made a few 3D games, but these days I make exclusively 2D games. This includes both games that take place in a 2D space, and the artwork is made using 2D techniques. I believe it is easier to make a good 2D game than a 3D one, both in terms of playability and looking great.

While 3D definitely has its advantages - there’s nothing quite like the immersion of a first-person perspective, and 3D models can be infinitely oriented - overall I prefer 2D much more. Here are my reasons:

Easy to Understand

Bomberman 3-D Bomberman

Hard to believe there was actually a 3-D Bomberman (right), released one year later

With the notable exception of VR, most games are played on a 2D screen, so it is natural to present games in a 2D plane. Humans have thousands of years of experience mapping things onto 2D surfaces; most maps are drawn on a flat surface (and it’s also why most maps of the world lie).

Even outside maps, humans often think of spaces in 2D terms, as we still live in mostly 2D spaces. Our towns, cities, roads, are all 2D. There are some 3D spaces - shopping centres for example - but they are a pain to navigate, since moving vertically is much more difficult than along a flat surface. In a sense we are a living organism that inhabits 2D spaces (and seldom layered on top of each other), unlike marine life for instance, which could be said to truly live in 3D.

Because of this deep cultural and evolutionary experience, 2D is easier to understand, easier to navigate, and easier to play in.

No Lighting / Shading

3D almost always requires a shading model and lighting sources. With some exceptions, such as wireframe rendering, you need a shading model to see the different surface normals. Therefore the most basic 3D scene requires lights and surface materials in addition to models.

Shading models

Not so for 2D scenes. Even some of the most complex 2D scenes can be boiled down to 2D sprites placed around the scene and drawn in a certain order. The sprites can be painterly, pixel art, or any kind of style, and they will look just as good as the artist can make them. This gives artists maximum control, with little in between the artists’ pen and the screen.

This doesn’t mean that one doesn’t need to think about lighting however. Making a 2D scene look great requires thinking about the principles of lighting, and the art team still needs to decide how the scene will be lit, but this is manifested in terms of how to draw the sprites.

Pixel art shading

https://www.pokecommunity.com/showpost.php?p=8884279&postcount=37

But this is where artists can use their training in visual art to make the scene really pop, and furthermore the flexibility of 2D art allows them to achieve styles that are non-realistic yet highly stylised.

Cheaper Art

3D art has a higher quality floor. Barring super abstract art (such as Unity capsules), a basic 3D character typically needs hundreds of triangles, rigged with a skeleton and animated, and skinned with some materials. It also needs to meet some minimum quality criteria such as the feet meeting and not sliding on the ground while walking/running, and looking good from multiple camera angles.

3D pipeline

http://ithare.com/graphics-for-games-101-asset-pipeline/

By contrast, the simplest 2D art is ridiculously cheap. A cheap run cycle could be 3-4 sprites. And although 2D art doesn’t scale nearly as well as 3D, remember that if the game is played in a 2D world, it doesn’t need so many orientations, so for most games, the art budget remains cheap.

Mario spritesheet

No Camera

There is so much work involved in getting a 3D camera right that it can fill a book. The position of the camera, field-of-view, what the camera is attached to, who the camera follows… get any of these wrong and you can make the player disoriented and even motion sick. Early 3D games ran into all sorts of pitfalls with cameras, such as having things block the camera’s view of the player, or randomly zoom in and out to avoid such things blocking the view. Sometimes the camera might end up in an unexpected location and see unintended things, like parts of the level not modelled, or that the player shouldn’t be able to see.

Bubsy 3D

Compared to 3D cameras, 2D cameras are much simpler, if it needs a camera at all. While there is a lot more to 2D cameras than most people realise, it is a lot simpler to set up, and a lot harder to get wrong. Even the simplest follow camera often does the trick.

Hybrid Approaches

It may seem like I’ve been dunking on 3D all this time, but I have great respect for it and acknowledge there are many places where it makes more sense than 2D. What’s more interesting though is how we can mix 2D and 3D techniques to achieve unique effects.

2.5D

Over the years people have used the “2.5D” term to mean different things - some variation of not-quite-2D-or-3D - but I’m referring to a game that is played in 2D, but contains 3D art. For example, using 3D models in a 2D game, or by adding depth and parallax to something that is still essentially a 2D game.

3D Mario

This technique has been used many times before. The overhead GTA games had 3D buildings to give a sense of scale. Since the early 90’s, fighting games have experimented with adding depth to the stages, using techniques like parallax scrolling and sometimes true 3D, even as the game is still played on a 2D plane.

SF2

It is a powerful technique but care must be taken so that the 2D and 3D elements don’t clash. Sometimes weird tricks are required to get the 3D part working well too.

Zelda: A Link Between Worlds

Sprite Lighting

One big advantage with 3D is that with a lighting and shading model, you can show dynamic lighting effects, which really gives a sense of depth and solidity to the scene. Without lighting, 2D environments can feel static and flat.

But if you consider 2D sprites as flat textures, there’s no reason why you can’t use texture maps and shaders on them as well.

These techniques are getting incredibly popular, and the results look fantastic. You can use lighting to add atmosphere, do environmental storytelling, or add depth that is otherwise very hard to do in 2D.

Graveyard Keeper

Games like Graveyard Keeper use sophisticated lighting systems with pixel art

Unfortunately these neat effects don’t come cheap - they can multiply your art budget, and may require special tools. Dynamic lighting should also be used with caution, as they can ruin a carefully-crafted look that you may have aimed for with a well-designed palette.

2D Skeletal Animation

Animation is one of the most expensive parts of a 2D art pipeline. Things like increasing framerate or adding the number of directions can easily double your precious art budget. But this is only because traditional 2D animation is done frame by frame. Nowadays animation extensively uses tweening - getting the computer to draw the in-between frames given parameters like start and end point of motion.

Motion tween

This is easy for simple animation, such as motion, rotation and scaling, but characters are much harder because of all the different body parts and poses. To do this properly you would need to rig the characters: add bones, attach body parts to those bones and animate the skeleton. This is a technique common in 3D animation, but there’s nothing inherently 3D about it. You could use the same technique for 2D.

Spine animated gladiator

There are specialised software for 2D skeletal animation like Spine, but you could easily use a 3D modelling software like blender and either import the characters into your 2D game, or pre-render to a spritesheet, making it even easier to use. Dead Cells used this technique to great effect.

There are downsides though, as rigging represents a higher up-front cost, and unless you spend a lot of effort, there’s something lifeless about typical 2D skeletal animation - perhaps due to their overuse in cheap mobile games? Well-executed frame-by-frame animation gives you more artistic freedom. Still, there is a niche for 2D skeletal animation, and worth trying out.

Chun Li SFIII vs SFIV

Aug 21, 2022 - Game Framework Tier List

Comments

To expand on some of the thoughts from my previous rant on nim, here’s a tier list I made. Yep, it’s going to be my garbage opinions! But it also includes my (admittedly subjective) first-hand experience with using these frameworks. I’ve used some for years, others just a week. And it includes a few engines and not just frameworks. So there 🧐

Criteria

How can you judge anything without clear criteria? Mine are quite specific; I am interested in making 2D games, for both jams and long-term hobby projects, so the results will seem heavily skewed if you have different needs. I have made 3D games in the past, but it’s not my cup of tea. I may expand on why I’m not interested in a future post. I’m also really keen on frameworks that are great for game jams - I’ve written about that in the past. In no particular order here are things I look for:

  • Learning curve
  • Quality of documentation and examples, ease of troubleshooting in general
  • How easy it is to package, including web export
  • How fun it is to use, vs. fighting with instability and quirks
  • How powerful and flexible it is

Also, some of these frameworks are super-specialised. I try to be fair here, for example if a framework is specifically made for VN games, I’m only going to judge it by how it can make a VN game.

Last but not least, I only list frameworks which I’ve at least attempted to make a game with.

The List

Tier list

  • Phaser: this was my go-to jam engine and I’ve used this for many years. The examples website is excellent, and being a web framework, is great for jams. I stopped using it only because I found something even better for jams, and for other purposes, a web-only framework isn’t ideal. Still for what it is, it’s great.
  • TIC-80: my weapon of choice for game jams. The limitations are perfect for jams as it’s insanely easy and fast to get something playable, and with the cheap pro version, collaboration is also easy. It’s so nice for jams that I wrote a whole post about it.
  • Love2D: on the surface this seems like a bog-standard 2D game framework, but being Lua, a scripting language, the packaging is genius - you can put your code in a .love file, and it can run on any machine easily. It also has a pretty big and dedicated community, with extensions for doing a lot of things. I take marks off because of Lua, a weird (in a bad way) language, and a lack of native support for web export, crucial for jams. However on those fronts, I’ve been looking into using MoonScript + a web export pipeline, which could make this an awesome option.
  • Unity: credit must be given for how insanely popular Unity is, which gives it a huge community, lots of resources for learning, and people to work with. Unfortunately it’s also very buggy, plugins randomly break with new versions, webGL export is always a pain, and wants to force you to do things a certain way.
  • SDL2: so lightweight calling it a “game framework” is a bit too charitable, but there’s no denying the large number of games, especially retro games, that have been modernised thanks to this library. I’ve made a few simple 2D games from scratch using this, and that’s pretty much all it’s good for, when it comes to making a new game.
  • MonoGame: I used this for a major project more than a decade ago (when it was XNA). At the time it was fantastic, as there was nothing quite like it - a simple yet powerful framework, that could target both PC and console, and supported by a large company that makes games. These days it’s still decent, with some good games still using it, but it does not offer any large advantages for the newcomer.
  • OpenFL: I must admit I’ve never actually managed to make anything with OpenFL, but I really wanted to get into it. There are some really nice games made with this and Haxe, but the dev environment is not easy at all to set up. Back in the day, the promise of having a single language that transpiled to C++ for efficiency and JavaScript for web was really enticing, but now emscripten is so widespread that most good game frameworks support web export as a first class feature. I don’t really have a good reason to revisit this platform anymore.
  • SFML: I consider this SDL-for-C++, although it’s a bit better and a bit worse. Better because it provides a few more nice features than SDL, worse because it’s not as well designed and built, and in the end you will still need to write most of your game yourself. Even if you need to use C++, there are better options out there for making games.
  • Cocos2d: I’ve only used this briefly in a prototype, but nothing really stood out. Doesn’t seem that popular these days, so there are much better options out there.
  • Pygame: Python is a fantastic language but its games offerings are woeful, due in large part to pygame. It’s quite easy to get into thanks to Python, and there are nice resources out there to get started, but it’s after the initial experiments where things fall apart - the terrible deployment process, lack of serious extensions or 3rd party games libraries, and until recent years, pygame was still based on SDL 1.x which could not do high definition at all. Don’t be fooled by how easy this framework is to pick up - it’s not much more than a nice wrapper around SDL.
  • libGDX: this framework has been around for a while, and sure, it seems decent and is mature. I have no interest in coding in Java however.
  • nico: I wrote more extensively about this game framework before, the tl;dr version is that this seems nice, but is very niche, and given the niche nim language and lack of maintenance activity, it’s hard to recommend this to anyone.
  • Your own engine: almost a joke option, but it’s here because I’ve done this before. Just don’t do it.
  • Construct2: I briefly tried this framework out to make a prototype, and discovered this kind of drag-and-drop game making is totally not for me. I would much rather code games myself, since I know how and it’s way more flexible. In theory you could make great games with it but judging from the typical Construct game (i.e. made by non-programmers), they’re nothing special.

Honorable Mentions

I haven’t tried the following frameworks but they are interesting and I would definitely give them a go if I had the opportunity.

General Purpose Frameworks / Engines

  • Python Arcade: I came across this while looking for an alternative python framework than pygame, and was impressed by how it seemed to do everything right. The framework is well designed as a games framework first, with useful libraries like tilemap support, rather than a thin wrapper around SDL. Two reasons made it less enticing for me: it is still python which means it doesn’t package well, and pygame 2 adds SDL2 support which finally made it performant on HD resolutions. But if I had to make a game in python this would be my first choice. Possible Tier A
  • Godot: When this first came out there was a lot of fanfare about how this would be the open source Unity-killer. Years later Unity is still going strong, and Godot has a (relatively) small but healthy community, and is a regular choice among game jam entries. I’m not so interested in using its GDScript language, nor in learning a game engine, but otherwise this seems like a solid choice. Tier A-B, depending on how it compares to Unity
  • GameMaker: This popular and venerable 2D game engine seems like a totally legit choice for making games, with scripting ability so you’re not so limited to what the engine itself can support. Two reasons why I haven’t looked into it: it’s paid and not open-source, and its scripting language is proprietary. Still, recently it has started to offer a free version, so it could be worth looking into. Tier B probably
  • Unreal Engine: Never had an interest in this, as it seemed to heavy to get into. Plus it’s like 12GB, so no thanks. Tier D, not for me
  • Allegro: This is an old 2D games framework, originally designed for the Atari ST, but later being ported to modern platforms. It is pretty niche these days but there are a fair few quality games from the 90’s and early 00’s that use this library. It’s not bad as a 2D games framework, so I’m open to learning more about it if I ever decide to tinker on one of these older games. Tier B, only good for old games
  • PICO-8: The biggest fantasy console, with a community that dwarfs its rivals. It’s pretty good, although personally I prefer the open-source TIC-80, but if I had to work on a team that uses PICO-8, I wouldn’t mind learning about it. Tier S-A, I just prefer TIC-80

Genre-Specific Frameworks / Engines

  • Solarus: An engine specifically designed for Zelda-style action RPGs. For such a specific purpose, this engine is surprisingly polished and active, with several great-looking games made with it. I love seeing bespoke engines and frameworks like this, as it gives you a huge leg up over a general-purpose framework. If I had to make an action RPG, this would be one of my top choices.
  • Ren’Py: This VN framework is proof that you can get great results if you focus on doing one thing and one thing well. Many successful projects use this framework, and although I haven’t used it directly, I have worked on teams that used it, and it seems really easy to use. Unfortunately VNs are not for me, but I have no reservations about recommending this.
  • OpenRA: Red Alert has a huge following, but the makers of this open-source remake had the foresight to make the engine generic so that it can support many other RTS games. Now OpenRA drives many mods including KKND, Dune 2000, Tiberian Sun and Red Alert 2. Having tried my hand at making RTS games before, I know how much work there is in making a playable game in this genre, so OpenRA does most of the hard work for you.
  • RPGMaker: For making a retro RPG game there is no better way. Similar to making RTS games, there is a surprising amount of work in making the basic mechanics, so a tool like RPGMaker lets you focus on the fun parts - character design, story writing, map editing - than the mechanics and UI. I’ve seen alternatives but none approach the quality of RPGMaker. I’m not really interested in making RPGs myself but if I were, this would be a solid choice.

I have no experience with these frameworks but if they work as well as they seem, they could all be Tier S or A.

Final Thoughts

Game frameworks have come a long way and yet in many ways still have a long way to go. On the one hand there are lots of cool specialty frameworks making it easier to make certain types of games than ever before. On the other, industry-stalwarts like Unity are still a bug-ridden mess to use, which is very disappointing given how popular they are and how much better they could be.

New tech is always hype-y but the game dev world seems particularly bad; new frameworks and engines that over-promise but then can’t do really basic things is an evergreen meme. I am cautiously optimistic that, in the long run, the wheat will separate from the chaff and we’ll get some truly outstanding options in 10 years time. Here’s to hoping!

Jul 31, 2022 - Why I gave up on Nim

Comments

For a number of years, I’ve been looking for a great new programming language to make games with. When I came across nim, it felt like a breath of fresh air and my search seemed to be over. However, after trying it for a month or so, I have sadly concluded that it’s not the right language for me.

Disclaimer

Nim is a great language, in fact out of the languages that have come onto the scene in the last decade or so, nim is one of the more promising. This is not meant as a critique of the language overall, only that in its current state, and for my purposes, it is not the right choice.

Why look for a new language?

When it comes to making games, I’m a bit of an all-rounder these days, but I’m still a programmer by trade, and it’s what I’m best at. Writing code is what I do, and care most about, and the current state of game programming leaves a lot to be desired:

  • Good, established game frameworks often use old languages like C/C++, which lack modern features or aren’t as nice to work with
  • Python, arguably the most popular language and which is fun and productive, but cross platform deployment is still an afterthought, with no standard, battle-tested method
  • Modern JavaScript / TypeScript are also nice to work with, but is browser-first, and on desktop tends to be laggy and bloated
  • Unity, the 800-pound gorilla of game engines, uses C# which is a good language. But the experience of making games in Unity is very much about wrangling with an engine, rather than coding in C#.

This leaves a family of less-popular game frameworks for all sorts of languages, including libGDX for Java, XNA for C#, OpenFL for Haxe, Love2D for Lua and so on. Because their userbases are much smaller, they tend to be less polished and capable, but at least there’s usually one for your favourite language.

Thus the choice for me boils down to:

  • A good framework that uses an old language
  • A good engine that is highly opinionated and frustrating to work with
  • A good framework that is suboptimal
  • A suboptimal framework in a good language

As a programmer, I could deal with the last option the best, and this is where nim fits.

Nim for Games

nim

Nim is a great language, at least on paper. It is compiled making it fast, but also borrows great features from languages such as Python, making it a nice language to work with too. It can even compile to a JavaScript backend, which means it supports the web as a first-class platform.

In practice it is a bit quirky and has a learning curve. It uses var, let and const, but in ways that are quite different from what you might expect if you came from say, JavaScript. Its documentation is reminiscent of early-2000s-era language docs, and representation on stackoverflow is sorely lacking. Its choice to take features from Ada/Modula, two very uncommon languages, seems arbitrary and will trip up most learners, for example in its case/of statements instead of the more well known switch/case. And its pass-by-value/pass-by-reference system is something I still haven’t gotten the hang of. But overall I still found it good, and most of these issues are nitpicks and quite understandable for a new language, and would probably be easy to overcome once one becomes familiar. I certainly found it faster to learn than golang, which is much more opinionated and arbitrary.

One key shortcoming is the lack of IDE support for debugging. For simple projects, you can get away with no debugging or just occasional print-statement debugging. Fantasy consoles don’t have debugging but they are still excellent for making small games. But for anything more complex, a good debugger can often overcome an otherwise bad coding experience. For example, even though memory bugs are common in C, I’ve been able to work around them with conditional break statements in my C games. And the ability to modify values at runtime with dynamic languages is such a powerful debugging tool. Sadly this isn’t available in nim. If nim were otherwise a pleasure to work with, this could be overlooked to a degree.

The big disappointment however is with the lack of a good game framework in nim. As of writing, the list of game frameworks and engines for nim is a modest collection of barely-actively-maintained wrappers around SDL. This is ok for my purposes since I’m interested in 2D game development, and SDL is mostly fine. The standout in this list is nico, a PICO-8 inspired engine, and this piqued my interest.

As previously mentioned, I’m a big fan of fantasy consoles. Their limitations also make them easy to pick up and learn, and limitations drive creativity. Nico not only couples a nice language with a great API, it is cross platform, including for the web, out of the box. Its feature list contains all the nice things that make fantasy consoles great.

Unfortunately it is not actively maintained, despite plenty of community interest. As of writing I still have several pull requests that have stayed open for months. Being far from mature, a lack of maintenance is a critical flaw. I want to make games, not engines, which means fixing the issues myself is out of the question. Given that I was still learning the ropes with nim, this is an extra headache I did not need.

What’s Next

For now I’ll be taking a short break in my quest to find the perfect games programming language. Plenty of options exist no matter your favourite language, although you’ll be putting up with some limitations. I’ve been looking into MoonScript + love2D lately. Coupling a cool language made by a game dev’s game dev, with a venerable 2D games framework, this makes a promising combo. A lot of features are missing however, so I’m not diving in head first. If I do ever jump into a new language, I’ll be sure to keep my experiences with nim in mind, now that I have a better idea of what makes or breaks a language for games programming.