2.5D Projection & Djikstra Pathfinding


ZIMBY is a 3D game based on a 2D prototype (which you can play in-browser here: https://antiochian.itch.io/evacuationv1 ).

Something I realised when considering what changes would be required for the shift to 3D, is that 90% of the actual core gameplay still takes place on a simple 2D plane. In order to save duplicating work, I decided to start with a 2.5D approach that allows me to re-use some of the code I wrote for the prototype.

2.5D world

I have been playing a lot of Islanders, which has a lovely low-poly 3D game world, but almost all the actual game logic takes place on these perfectly-flat plateaus:

This is kind of how I dream my game ending up - 3D terrain and buildings (and creatures), but with tile-based 2D game logic projected onto flat surfaces of the landscape. Here is a (VERY) rough prototype of this effect in action:



The setup here is a 2D world being rendered to a texture in-memory, and then there's a super simple fragment shader I wrote that can be applied to any 3D object (here its on the ground plane) to project that 2D world onto the 3D object like a TV screen or something. Then I do some maths to figure out how to passthrough mouse actions to the 2D world, and am free to sprinkle 3D decorative objects on top of the 2D world to try to hide the fundamentally 2-dimensional nature of the game.

In effect I have just taken a few steps forward and then several dozen steps backwards by scrapping most of my old implementation, but I am having a lot of fun and also feeling quite confident about the extensibility/potential of this approach

Djikstra Pathfinding

One of the nice things about making your own game is that you can shave as many yaks as you like and there are no customers or product managers to stop you.

In order to improve the performance of zombies in my game, I decided to switch from the built-in A* engine pathfinding to Dijkstra's Algorithm. (cool explain-y animations on this page). A* is faster for getting a path from point A to point B, but Dijkstra is better when you want to generate tons of paths from points A1, A2, A3... to the same point B, which is exactly my use-case.

Dijkstra's algorithm requires you to recalculate the algorithm whenever the map changes (which is slow), but after this recalculation it is blazing fast. Since zombies will typically be pathfinding en-masse to the same static location (whether it be a sound source or to the train station), this makes Dijkstra a good fit.

Only problem is, Godot doesn't support Dijkstra's algorithm. So I wasted spent the last week implementing it in the engine and contributing it back upstream as a new feature, which was immensely fun and satisfying, and now I have super-fast many-to-one pathfinding in my game

Tile-based mechanics

Since I had a fresh start, I figured I might as well waste even more time, so I also threw away the existing tile system and restarted from scratch using a multi-layered tilemap where a single building might consist of multiple arbitrarily-arranged tiles and roads can be placed completely seperately. (Unlike before, where roads and buildings were tightly-coupled and limited to one tile only).



As a part of this change, I detached the functionality of buildings entirely from their physical representation. Previously there was a Sprite object for each tile, which both represented multiple buildings visually and handled all the gameplay logic. Now the gameplay logic is entirely implemented by invisible tiles on a Godot TileMap, and the sprites are purely decorative. The idea is that later on I can easily swap them out with new 3D models etc, or re-skin buildings at runtime without messing with any gameplay logic.

To this end, I started implementing things like navigation costs + collision boxes as invisible tiles that can be placed on top of any cosmetic tile-type, which proved very useful. As I started looking into 2.5D implementation this weekend, being able to have 3D gameplay objects interacting with the 2D grid-based objects has been surprisingly straightforward.


Leave a comment

Log in with itch.io to leave a comment.