FEZ: engine algorithms and ideas

· Reading time: 4 mins

Yesterday I played for the first time Polytron's FEZ. Graphics and design are amazing, but what truly struck me was the way the game switched between the 2D and 3D "looks". It was truly inspiring, so I decided to spend a little time understanding and recreating the world rotation engine.

Turns out the mind-blowing effect is simply based on orthographic view transforms. Orthographic views aren't really used in realistic optical systems, because the projection preserves proportions and line parallelism. In other words, there is no perspective and far objects look as big as near objects.

This means that transformations look less realistic, and also that projecting a cube directly facing the camera is exactly the same as drawing its front face, ignoring everything else, regardless of its position. Perspective projection doesn't allow that: if you draw a cube positioned in the bottom left half of the frustum and projected via a perspective matrix, you're going to see its right and top sides. What we do want here is not realism, but a way of conveniently displaying a 2D environment and occasionally rotate it about the Y axis, and orthographic projection does exactly that.

The idea behind it all is that the game environments are the four sides of a cube-ish structure, and switching between them causes a gradual rotation of the whole environment, so that the player always faces a 2D world. The collision detection algorithms then simply ignore the dimension currently facing away from the player (e.g. in the direction when no rotation is applied) thus making the player roam in a purely 2D environment.

The code

I quickly sketched these ideas and you can see the results here.

In the meantime I also did a little bit of experimenting with procedural texture generation. What I did was implement a awfully minimal voxel engine which basically took a 3D point and created and textured a cube mesh around it. After the voxels were in place, I moved on to creating an orthogonal projection matrix (whose only job was to adjust to the screen's aspect ratio) and initialized the view matrix as the identity. To simulate FEZ's rotational movement, I used a quintic easing function. To make things quick I created an easing lookup table, containing all the possible values used to animate the view matrix. The peculiarity is that I didn't map the quintic function to , but created a transition made of small increments. This way, instead of specifying all the possible rotation angles, I just specified how much the view matrix should rotate at every step so I don't have to reinitialize it to identity every time.

In the final code I restricted the rotations to the Y axis, but in the picture above you can see what the world looks like seen from an angle. A 2D view, instead, looks like this:

I also had a little fun procedurally recreating the Minecraft's dirt block texture, inspired by this fiddle. The idea is to have a random factor that dims the brightness a bit, and then expressing each block of the texture with its own color. The top and bottom of the texture are simply a green and brown color with noise applied. The side is green the first few pixels, brown the last few pixels, and there's a small area, around the 7th horizontal line from top, where it's left to chance whether to put a brown or a green pixel.

You can see the code in action here, and read it here.

Merry Christmas! :)