The washing machine problem

The world of Highrisers is purely made of 2D sprites. We use a cabinett projection in order to generate a 3 dimensional impression. That’s a kind of drawing technique that works without a vanishing point. It’s well suited to the dollhouse-like look of Highrisers and for pixel art in general, as the “straight” lines running inot the back are at a 45 degree angle. Which works well with pixels.

We further enhance that impression by clever usage of light and shadows, but at its core, it’s all just plain 2D.

This means we can create levels quickly and simply, and the performance will be great even on older machines – we’re just moving 2D-sprites after all. We won’t be able to do stuff like the change of the looking angle as you might have seen in “This War Of Mine”, but that’s fine.

However, we now also encountered limitations when it comes to arranging items and walls.
We have dubbed this issue the “washing machine problem”, due to the nature of our example object. Simply put, it’s about this:

It might not be obvious why this issue should arise. But always remember: Those walls have no depth. They’re just flat wallpapers creating the illusion of depth.

Until now, our building (all the walls, floors, ceilings, pillars, etc.) have been based on a tilemap, and it has always been completely in the background. That means that all other game objects like furniture, equipment, the dreamers and the players, everything was in front of all the walls.

If you played the demo, you might have noticed that in some cases, this is not always entirely true:

What about that red barrel on the right of the workbench? Isn’t that clearly covered by the protruding wall?

Well – unfortunately, no. Like all objects, the sprite of the barrel is actually placed in front of the wall and looks like this:

I have manually set a clipping rectangle for the sprite and cut off the part that should be visually behind the wall.

For the dreamers that are hidden in the walls behind closed doors: They are only spawned once the door is opened, so again – no occlusion of objects by walls.

This worked fine for our static tutorial level, but of course this would not work once we integrate the procedural generation.

And as we were overhauling our building tilemaps to make them fit for the proc gen, we also decided to address this occlusion issue.
Object placement in Highrisers generally works like this:

Every object has an anchor point, which is the bottom left far corner of the object.
Remember that the object is purely 2D, so we only need to store the x/y offset. There is no real z-depth!
Since our perspective is vanishing to the right, we place objects from left to right, so that leftmost objects are occluded by their right neighbors.

The idea now was to have different possible layers where a horizontal wall can be placed, and a corresponding layer of object slots, which would place objects in front of their walls, but behind the next wall.

Slots are positions where an object can be placed. They offer an anchor point for alignment and help to avoid overlaps, as they prevent two objects from occupying the same space.

3 different wall layers and their corresponding slot rows
When placing objects in the slots, the walls and objects of a hihger level cover walls and objects of a lower level

Sounds nice and easy, and would have worked with our current level architecture. But when you think about it further, problems arise:

While this case would still work with our layering concept, it falls short for other combinations:

As we can see, the long right washing machine is placed on the yellow level, but it is so long that it covers the red wall. But read walls are supposed to cover objects on the yellow level?!

This can also happen for horizontal walls placed in the front:

We have not yet decided how we are going to address this.

We could simply limit our architecture so that we don’t run into such situations. No walls in the front, no walls portruding into the scene. As the architecture of Highrisers is stylized anyway, this would well be possible.

We could also limit our object design so that we simply don’t have such looooong objects reaching into the front. Or have them only placed horizontally only.

We could also change the rendering algorithm for our objects, drawing them only from one layer to the next, from left to right. That way, the right occlusion will always be selected, no matter where the anchor point of that object is. I would require to transform our flat tilemap walls into wall objects that interact with the slots.

Concept of layer by layer rendering

Oh, who would have thought that washing machine placement would be this troublesome?