@a_najafi: Thanks for providing such a thorough example. What you are describing is pretty much exactly what I had in mind myself. I will still need to fake a 3D-array just like I’ve faked a 2D-array, since blueprints do not allow for multi-dimensional arrays, but that’s really not a problem. Making a multi-level grid is pretty much exactly like making a 2D-grid, and the only potential issue is performance.
I might not have understood your example correctly, but I do not see how it will be better performance-wise compared to other methods, something I think you acknowledge in the last part. A quirk of my toolkit compared to regular graph-based pathfinding algorithms is that I store every edge for every tile, even though those edges might be 0.
If I was using C++ I would simply remove those edges at startup, meaning they would never have to be searched, which would make multi-level grids almost as fast as 2D-ones. I have tried to implement such an approach in my toolkit before, using an array of arrays, each array containing all the edges of a tile. However, this method turned out to be significantly slower than my struct-based approach for almost all types of levels (2D ones), so I scrapped this solution. What is quick in C++ is not always the same as what is fast in blueprints, which is something I’ve had to learn through trial and error. So if I use my current approach I will always have to double or triple the amount of searched tiles if I use multi-level grids.
How much this will slow pathfinding down is an empirical question, and it might not be that bad, as most searches will quickly return false, but it’s hard to know for sure. Therefore I’ve pre-planned a few approaches. I could mark certain tiles with a boolean as having access to other levels (say tiles with ladders), and only search up or down if this is set to true. I could also use a hybrid approach of my struct-based pathfinding for the 2D-grid, with arrays of arrays for searching up or down, where the amount of edges returning 0 would be much higher, making arrays more efficient.
I will begin testing all of this as soon as I’m done with my next update. I hope I understood what you wrote. If you feel I have missed some essential parts we could discuss it on Skype, as you suggest.
@tamaster92: I’ve shared my ideas on how to implement cover-systems with a few users before, but it might have been in PMs. There are two ways in particular I’ve considered using.
The first is a dynamic system using tracing similar to what I currently do for regular visibility. In addition to the head-to-head tracing I currently do I would also do a trace from the attackers head to the defenders torso (and/or legs). If all traces return false (have not hit any cover), this would give the highest hit-chance. This is very simple and efficient, and could work on many different types of map, but it’s not my favorite approach, as I prefer something a bit more predictable for turn-based and grid-based games.
My current favorite solution is to have a cover-variable on all tile_parent actors, designating the amount of cover the tile gives in different directions. I would then feed this information into a grid-sized array that would store the cover values in their appropriate locations, granting a defense bonus if the unit in cover is attacked from a direction on the other side of the cover (by simply comparing X and Y locations of units). A benefit of this is that it’s both very quick (since most stuff can be pre-calculated), and it can be easily used to display XCOM-style “shields” or similar for all tiles in move range, by using the indexes in the CanMoveTo Array to check the Cover array.
Something akin to this is what I plan to implement for the update after the next.