Dom Williams

Devlog #8: 2D to 3D

I recently made a significant change of direction to my game by switching the rendering style from a flat 2D top-down view to a 3D orthographic view. The hope is that this will help make it more intuitive to understand what is going on, as the underlying game is 3D anyway.

This post will look at some of the pain points I encountered while porting to 3D.

Top down to orthographic

Here's the old top down view of a forest, with some browsing horizontally and vertically around the tree tops:

And now enhanced with an extra dimension:

It's still a very simple world with "shrubs", "tall grass" and "trees", but I think it looks pretty good in 3D, especially with the smooth rotation. Ideally this should make it more intuitive to understand what is going on in the world by having multiple perspectives, instead of just from above.

The vertical slice view is still the same, where the up and down arrow keys move the view vertically 1 block slice at a time.

Block selection

Selecting blocks in the world was simple when it was top down, because it was just a 2D rectangle to render. There was also this little nibble in the bottom right corner that encourages right clicking, which opens the context menu.

But it's not fully clear which blocks are selected and to which depth, unless you want to read the verbose debug menu output. This would greatly benefit from being 3D; here is how the initial version looked:

It's kind of clear but still vague which blocks are selected, and it sometimes requires a 360 spin to be sure, which isn't great.

I had the idea of highlighting the faces of selected blocks, which has a remarkable impact (please ignore the grid-like borders, there is still some work left to propagate block face occlusions across chunks):

This shows another problem that I didn't have in a 2D top-down world - jittery screen to world space projection. It used to be trivial to convert between screen and world space, but now it's an imperfect grid-based raycast from the camera to the world. This is just the first iteration, but there is a definite need to smooth this out in the future.


It was so simple back in the good old days when entities were just flat 2D shapes. They still had 3D bodies in the simulation but there was no need to worry about that for rendering.

But that programmer art is no longer so simple in 3D. I considered keeping them as 2D blobs that always face the camera (known as "billboarding"), but I'm not sure this really fits the perspective.

Don't mind Joela shooting up that tree, I swear it was intentional and definitely not a bug

On the other hand, if they become 3D programmer art they revert to big lumbering cuboids. Eventually I will need to make them more people-like and less like oddly coloured geometric shapes, but that can wait.

Inanimate f&!*ing objects

I might be able to make use of both styles, whereby some entity types can remain as flat 2D shapes. For example, background things like "tall grass" (green circles) and "shrubs" (differently sized green circles) could be flat whereas objects like "apples" could be 3D - have a look, and please excuse the corners on the apples:

Job indicators

This is an area that definitely needs some work. Currently a little floating square appears to show information about an outstanding build job. Build jobs are only for a single block, so building a wall will layer multiple instances on top of one another.

This didn't really work properly in 2D, and it certainly doesn't in 3D either:

Build job comparison

The billboard effect doesn't really work in 3D, as it's not clear which block each job represents. At some point I will have to redo these to bundle up multiple block builds into a single "job" that clearly shows which blocks it affects.


This change to 3D was a big effort, and involved a lot more maths and quaternions that I was prepared for. I think it is an improvement to the old style, but I will need to put some serious thought into the UI to end up with an intuitive game.

But first it needs to be a game and not just a demo :^)