[SUPPORT] Advanced Turn Based Tile Toolkit

Yup that’s it, it really is only for aesthetic purposes.
Here is my simple example. I have a “grass plains” tile, which has a small rock that randomly is shown as “visible” (again, just to break up the landscape a bit, visually). To further improve the aesthetics, you can see the tiles are rotated in multiples of 60 degrees. Because I’m too lazy to always do this manually, I added it to the constructor. I even went further actually, and made some utility scripts to auto-populate the grid with a base tile (as opposed to the static mesh). Just simple useful things, for lazy people like me :stuck_out_tongue:
I understand though that you want to keep it clean and tidy, and that is of course just fine :slight_smile:

I’m having alot of fun with your toolset though :smiley:

That is an awesome start, lodeman! Looks good! My default tiles would look identical no matter their yaw rotation so this is still not something I will be including by default. For spawning your tiles are you still using instanced static meshes? If you use actors or regular static meshes it can quickly have a large impact on performance for big grids.

I actually just went ahead and implemented a BP_HISM_Manager.
The constructor will go over all actors of type Tile_Parent, iterate through all child components, and assign the appropriate static meshes’ transforms to the relevant HISM component.

Ok, that sounds similar to my implementation for turning tile actors into ISMs and should work well. I toyed around with HISMs when they were added to UE4, but it didn’t seem to improve performance above regular ISMs. I’ll probably also switch over in a future update, though.

I love that you’ve added squads of units by the way! It is something I plan to do for a simple 4X game example. Did you encounter any problems when adding this or was it quite straightforward?

With how edge costs work would having some units have different costs for different terrain be an issue? From the videos it seems like edge costs are ‘global’.

Does this kit have the ability to pathfind for pawns that are multiple squares/hexes in size?

I went the HISM route because my tree meshes have LODs, and I don’t think normal ISMs supported those.
Implementing the multiple units was very easy actually. This was simply a matter of duplicating the skeletal mesh and moving them around in the viewport.
Additionally, the parts in the event graph that call the “move”, “attack” and “death” animations were put into seperate functions, which take in a skeletal mesh component reference.
Finally, I just do a loop over the Anchor scene component’s children, cast to any skeletal mesh component references, and call the new function.

Things I want to add to this though:

  • have the units use the anim graph with a time delay, currently they are all exactly in-synch, which is of course a bit sloppy looking
  • when the squad takes damage, have individual skeletal meshes already die off. Currently they all just die in sync when the health is fully depleted.

I’ve also done a bunch of other things too, I’d be happy to share more progress, but I don’t want to thread-jack :slight_smile:

@CampingCarl: Both of those features are currently not implemented in the toolkit, though I am working on adding both. You are right in that edge costs are global, which means I will need to create some workarounds to get variable movement cost for various units implemented.

I have given this quite a bit of thought and think I have found a good solution which I intend to implement in the future. This toolkit originally begun as an experiment to create the fastest possible grid based pathfinding using blueprints, and while working on this I’ve found that very small additions to the core of the pathfinding functions can have a large impact on performance.

Because of this I do not intend to add new branches into the pathfinding that checks if the unit is of a certain type before then choosing between various edge costs etc. Instead I plan to add the option of each unit using a separate variant pathfinding function that can be customized within each unit. This way each unit can have a tailored pathfinding that is as complex as what is needed for that particular unit.

Units that take up multiple tiles is something I have experimented a bit with already. My solution is to create a new array that holds the maximum size a unit standing in that tile can be. I generate this array at Begin Play, where I check the number of free, walkable tiles that surround each tile. My new way of storing edges might complicate this a bit, but I am confident I can get it working, though it is not my first priority. If you want to attempt to implement it yourself I can point you in the right direction and help you out as best I can.
**
@Lodeman:** You might be right when it comes to LODs. I have not worried about that yet since all my example meshes are very low poly. That is a good reason for me to switch to HISMs soon, though.

Glad to hear implementing multiple units was easy. I suspected it wouldn’t be too hard, but I feared there might be some complications I had not thought of. Glad that’s not the case. Thanks for your thorough explanation of your implementation. The time delay and killing individual units seems pretty easy to do, and I’m sure you can figure it out yourself. I’ll give it a whirl if you’re stuck, though.

Feel free to post about any things you have added. I love to hear what people use the toolkit for, and it inspires me to add features of my own :slight_smile:

My idea for variable movement costs was to replace edge costs with enums of data about the tile and just switch depending on the moving pawn. I have no idea how that will impact performance but your method of separate functions might help with that too.

For multiple tile units does that array save much time even if you need to check the same tiles for something else? For example if a 3x3 tile wide unit moves forward even if your array says the next space is walkable for a pawn that size you still need to check the 3 tiles it is moving into for rough terrain, height, ect. or have an array for attribute that affects movement.

To what degree enums will slow down pathfinding that is an empirical question, and the decrease in efficiency will probably be small enough that you will not notice it in your game. However for my toolkit I’m trying to make my solutions both as efficient and flexible as possible to accomodate for as many types of games as possible. If your game does not use units with extremely levels of move/turn it is unlikely to be a problem for you to implement it this way.

Just so I’m sure you understand what I mean when I talk about multiple tile units I’ve thrown together a quick demonstration in Excel:

The green squares represent a large unit occupying a 4*4 space. When the unit moves it only checks the top left index it is occupying (the red square) against the pregenerated array for large units (represented by the numbers). So if the unit tries to move straight right it checks the index to the right of the red square. If the number in the array is equal to or smaller than the size of the unit it allows movement to this tile. Height should work similarly to this, but difficult terrain is more difficult :stuck_out_tongue: If I do not think of something more clever one could do a similar array for higher movement cost, though I think it would have to be either a separate array for each unit size category or a similar solution using a nested array.

Small update. I’ve added a first version of fog of war, difficult terrain (that can provide a cover bonus).
Also, a tile type can now indicate if a unit should go “crouched” when they enter it. This gives a sense of immersion, as the unit actively appears to be hiding among the shrubbery :slight_smile:
It also decreases the walk speed of the unit, so it makes for some very cool sneaking movement when traversing multiple tiles of forest!

http://oi63.tinypic.com/2my11rd.jpg

The fog of war implementation is working well enough. But I’m getting small frame drops when I’m setting the fog-of-war vision range to higher values (say, >3 tiles).
So I’ll need to think up something to make that more efficient.

Very cool! You’re making great progress. Both cover systems and variable movement speed while crossing different types of terrain are both things I have on my to-do list. As for fog of war I’ve added this to the example game that comes with the update I’ve sent to Epic. That is for a 2D sprite based example, but the solution for finding visible tiles around units is quite efficient and should probably be of help to you. What do you use for determining what tiles a unit can see? The Find Tiles In Range function? If so how often are you calling it? You should only be needing to call it whenever a unit first enters a new tile. Lastly I’m very curious as to how you are rendering your fog of war. Fist I assumed you were using gray decals, but when I take a closer look it seems like your rock and tree meshes are transparent. Are you using some sort of post processing or replacing every mesh?

Edit: With all this stuff being shared I got inspired to show some of my own progress. Heightmaps are working pretty well now and I’m trying to find the best way for the player to be able to see lower floors that are blocked by roofs and similar. My current favorite solution is to make meshes transparent if they are a certain height compared to the length of the camera spring arm. A special type of actor are used for these sorts of floors so that the user can specify what meshes are affected. These actors also automatically detect if they are at the lowest level of a particular tile index, in which case they are never made invisible. If anyone have any input I’ll be happy to hear it.

Impressive, . Is performance proving to be an issue at all?
Sounds like changing the visibility by spring arm length is the way to go. Would structures appear opaque from the exterior to other pawns? (through a check if the pawn was beneath the mesh i guess) Is there a way to make it localized eg on the roof (level 2) building A, does not make building B level 3+ transparent? Don’t know, just a query

Highly anticipating these updates. , you do great work. Thanks for the update, keeps me focused.

That is exactly what I’m doing, just call it when entering a new tile.
I’ve found out that this isn’t the cause of my framedrop though, it’s related to my FoW solution for meshes.

So what I have is a transparent gray plains mesh that overlays the basic terrain. No problems with that.
But for all my meshes attached to a HISM parent, I have a HISM_FoW variant. The FoW variant uses the same mesh, but with a transparent material assigned to it.
Whenever I reveal new terrain, I remove transforms from the HISM_FoW and add one to the HISM(_revealed) parent.
This seems to be giving quite a few hickups, as I’m always looping each HISM to find the correct transforms to remove.
I wanted to use the getInstancesOverlappingSphere function to find overlapping indexes instead, theoretically quicker, but for some reason this function simply seems to not work at all.

So yeah, that’s my problem :slight_smile: I’ll tinker with it more this evening after work.
Nice progress with the invisible roofs btw!

If you’re thinking about pathfinding using multi-level grids, then there is virtually no impact on performance. The way the edge array works in the newest update all tiles hold the indexes of each tile it is connected to (and only those) instead of naïvely assuming it is connected to all surrounding tiles and then checking each step of the pathfinding if this is true. With this system for edges checking if a tile is connected to an edge on a higher level is just as quick as for adjacent tiles. If you’re thinking of the way I create transparent meshes I haven’t really tested the performance impact yet. I doubt it will be a problem for most games, but there might be an issue for huge maps with several layers of heightmaps. I’ll be looking into this later.

The way it currently works I do not check whether or not the current unit is outside or inside something. It is also global so that all Heightmap Platform actors of the appropriate height are made transparent at once. I will look into alternate ways of doing this, but I might not find a solution that is generic enough to be included in the default toolkit. If I find a good solution that only works for specific types of games I might include it in an exampe map.

Yeah, getInstancesOverlappingSphere has given me some headaches as well. It seems like you’re having similar problems to when I made my own fog of war system. I think the problem is that a bunch of ISMs or HISMs are basically an array of meshes. If you delete one in the middle of the array then the engine will essentially have to delete and recreate all meshes again, since there can be no “blank” instances in this array. This is speculation on my part, but it does at least seem to be something like this. Because of this you do not want to delete multiple ISMs in one tick, since the engine will essentially have to repopulate the array every time. The solution I found was to move the ISM to a location it cannot be seen instead of deleting it. This way the amount of instances remain the same, so they do not all need to be recreated.

I have to say this HISM_FoW variant for each mesh is just giving wayyy too much headaches. And frankly doen’t even look as good as decals placed over each tile.
Honestly I simply hadn’t considered using decals before, but it seems much easier to manage, and a quick test on the 20x20 map didn’t seem to give any performance problems if I filled it up completely with decals.
So yeah, bye bye HISM_FoW. Hello decals!

Great! That is what I assumed you did initially. I would be interested in seeing how it works with decals if you would want to post a screenshot :slight_smile:

Hi ,
I got around to switching over to decals, for the most part.
Looks alot better, and runs silky smooth now :slight_smile:

Funny how much time you can waste on a bad solution before seeing the light!

Looks neat! Glad it worked so well. I might be wrong, but it seems like the leaves on some trees are still a bit green? If this is the case, make sure they are set to receive decals in their rendering settings.

So true with the wasting time on a bad solution bit. I’ve spent so much time changing and reinventing features. It is a part of the learning process, though :slight_smile:

Hey Guys,
I dont think i have ever posted here before but here is a preview of my progress so far. My main focus has been multiplayer and i think i have nailed it.

@Westcut: Very cool. I too at some point want to do this, was it alot of work to incorporate? Any specific struggles?

@: Aye, the leaves appear a tad green. I think this may be due to the material using subsurface lighting, but it’s a bit of a guess atm. When I go up close to the leaves, from above, it does have the decal applied correctly.