2D and 3D. What’s the difference.. Really?

I’m gonna start off with a very, very interesting subject. 2D games, 3D games and 2.5D games.. And what exactly does this mean..(if anything).

Take a look at these games:

Half Life 2

Angry Birds

Monkey Island 1

One could argue that Half-life is 3D, and the other two are 2D. Someone else would say that Monkey Island is actually 2.5D. And a third guy will say, you’re both idiots, they’re all 3D. So, who’s right?

The confusion stems from not specifying exactly what we mean when we say a game is “3D”. It could either mean, this game has the illusion of depth or it could mean that entities in the game have a geometry composed of polygons. So to avoid the confusion, we could now agree on the following:

Half Life 2: 3D world using 3D models

Angry Birds: 3D world using 2D sprites

Monkey Island 1: 3D world using 2D sprites

For Angry Birds, the illusion of depth comes from the parallax effect. When the camera scrolls horizontally, the mountains in the background will move slower than things in the foreground suggesting they’re far away. For Monkey Island, when Guybrush moves over that bridge he’ll get smaller and smaller, again suggesting depth.

When developing Spark the initial idea was to be able to create both 2D and 3D games. That means the engine would be able to render 3D geometry (polygons) as well as sprites but also that you can create games that have depth and games that do not. If we stop thinking about graphics for a second, we can create an entire game, create the rules, the gameplay, the interaction between objects, everything, and programming wise we’d be done, even if nothing is displayed on the screen. So now if you knew that your target platform can support hardware accelerated graphics, you can just attach those entities to 3D models. If not, use sprites but either way you’ll only need to write the game once.

To accomplish this, we created a virtual world. This virtual world is a data structure that holds all the information about the game. A “scene” inside that world can have a 3D coordinate system (games width depth), or a 2D one. An FPS game level would use a 3D scene. It’s main menu though would use a 2D scene. Now, logic will be applied to that virtual world to create the gameplay for our game. Later on we can attach a 2D and/or 3D mesh for every entity and let the renderer decide which one to use at realtime. By using a virtual world as a middle-man and not giving commands directly to meshes (playerModel.x+=50;) we’re decoupling the game logic from the rendering logic, and this can have a lot of advantages. We can provide fallbacks at runtime, we can mix and match renderers without touching the game-code, we could even create a DOM renderer in the future and suddently you could be using Spark to build websites.

So, this covers the 3D geometry and 2D sprites bit. What about the requirement to create a 3D scene for levels with depth but a 2D scene for levels without. Why not use a 3D scene to create sprites for a 2D game (think Super Mario that doesn’t even have parallax) or a main menu, and just keep the z property for everything the same?

This is a legitimate question, and many engines, like Unity, are doing 2D this way. The problems with this approach is the overhead and additional complexity that comes from trying to use a renderer that thinks 3D, to be used as a 2D renderer. Let’s talk about the latter first.

In a 3D world, you can’t explicitly define what part of your scene is going to be inside your viewing frustum. You define a size for your view, position your camera, set it’s field of view and then you get a render. But in a 2D world all you really want is to either render the whole thing (e.g. a main menu background) or a part of it (a scrolling game). For 2D renderers this is easy, you explicitly specify the area of your scene you want rendered and pass it to the view for further processing (if the area you wanted doesn’t match the view size you will need to decide on scale-to-fit vs widescreen vs cropping, etc). So, what was once a convenience when rendering 2D scenes (a 2D scene rendered on a 2D screen, a match made in heaven) now becomes a problem. On the main menu example, your 3D engine will need to calculate how to position the camera or scale your scene so you don’t have to do trial and error by yourself. On the Super Mario example the 3D camera can’t tell if it’s rendering past the bounds of your scene so you’ll need to hack a solution yourself (min(camera.x,2184);)

The complexity of how 3D renderers calculate the viewing frustum also doesn’t come without a cost. So you will be spending CPU cycles to produce a behavior that you don’t want in the first place. Also, sprites belonging in a 3D scene have 3D positions (regardless if they share their z value or not) so in order to render them on a view the renderer will be querying the 3D camera and do a lot of transformations (positioning and scaling), a step that can be completely avoided on a 2D scene.

So, to sum up, there is a distinct difference between saying that a game involves a 3D or 2D world, and saying a game uses 3D models or 2D sprites. What we have found while developing Spark is that a game engine can benefit if it makes an effort to be more agnostic when it comes to the entities’ meshes (3D models or 2D sprites), but also make a clear distinction when it comes to rendering a 3D or a 2D world.

If you made it all the way down this article, you now HAVE to leave a comment :P. Give me feedback if this was interesting or not, if I made any mistakes, if you want to propose another article or anything else.

Thanks for reading!

Hello World!

After about one and a half years in development of our game engine, Spark, I decided it was time to start documenting the experience. We’ll talk about game development (I say ‘we’ cause blogs are a two-way communication and I’m gonna be pushing you a lot to leave a comment, whether you loved or hated an article..), how changes in technology are impacting games lately, and the problems I face while trying to make a generic cross-platform game engine.

This blog is not meant to be very techy. A game revolves around a lot of areas, from graphics rendering and networking to artificial intelligence and even story telling. Yes, we’ll talk about techniques and how to solve specific problems that come up when developing games, but I’m not actually going to be posting code. These posts are about the interesting phase of development where you just sit around staring at a wall thinking about how to implement something and not the boring after-part where you just convert those thoughts in a programming language.

So, thanks for reading, and remember, I’d love to hear feedback from you. Let me know what you’re working on, if you’re using a third party game engine or going at it yourself, if there’s anything you’d like me to cover in specific, or just wanna say hi, or that this blogs sucks, it’s all good 🙂

Till next time

Aris