[SUPPORT] Advanced Turn Based Tile Toolkit

There are lots of functions in the toolkit at this point, and I might even have forgotten to cover that one in my tutorials. After the next update I’m planning on making a few new tutorial videos focusing on key concepts of ATBTT, such as the edge array/pathfinding. Hopefully this will make these sorts of things easier to grasp quickly.

That sounds great! Thanks man for the continued support.

I had two other questions that occurred to me over the weekend…

-I know you are in the middle of trying to get networked multiplayer working, when you release that update do you expect it would be relatively easy to drop into an existing project? Or does it change so much in how blueprints are handled that it almost would be better to just start fresh and try to rebuild any custom functionality with the old project as reference?

-I’ve gotten the hang of the Spawn Tile functionality at runtime and it’s working great, I was wondering – what do you consider the cleanest way to delete spawned tiles and have the edgecosts/pathfinding update? Does simply destroying that actor keep the edge costs or does it update dynamically and reset the edge costs of that tile back to the default?
For example, if I’m at runtime and want to add a wall blocker at this tile, but I changed my mind and wanted to delete it and replace it with a 3 Cost tile.

I’m away from my workstation at the moment so I can’t fiddle with it myself today :slight_smile:

Thanks again!

@ienjoywhiskey: Hey, sorry for the late answer. I’ll try to answer your questions.

For your first question, I think it will not be that straightforward to drop an existing project into the new update. It will probably be easiest to copy over any changes you mande one by one and testing each step/modifying as necessary. The toolkit has not changed so much that porting added features should be that difficult, but even the fact that I’ve changed quite a few variable and function names to better comply with Epic’s scripting standards means that directly copying over will not work in most cases.

For your seestion, the MakeTilePassable function should work well for what you are trying to do. Run it for the appropriate tile after destroing the actor occupying it. After that you can modify its tile costs either by using Spawn Tile for a tile with the correct indexes, or edge by edge by using Get Adjacent Indexes and Set Edge Cost.

Hey great kit, the VR map in particular is excellent and I hope this functionality continually gets upgraded. One idea is the ability to spawn pickup drops /units.

Anyway I noticed you mentioned turn based pathfinding is mostly for performance. What about if all units could move around freely except with a cool down timer? This would naturally limit the pathfinding and the cooldown could be tuned per unit so that theres not to much pathfinding going at at any one time overall.

This would also be really cool strategy wise as you have to track all your units at once.

Thanks! VR features is something I really want to work on in the future. When I finally get around to making my own game I want it to have VR-support, so this is something I’ll steadily be improving.

You can already spawn units. Use the Spawn Unit function in BP_GridManager.

Though one of the reasons I don’t have real time pathfinding is performance, a just as big reason is that having to accound for the possibility of real time movement in every feature I add would slow me down tremendously and probably make the blueprints bloated and hard to work with. Keeping everything turn based means I can keep some assumtions constant. I’m not saying it would be impossible to alter the toolkit to allow for this, but for me to include it as a supported mode along with everything else is much more difficult.

Hey,

I’ve been going through the code and I found that “Show Crosshairs” shows the units we’ll be able to attack if you move to that tile, now I can’t seem to find a function or bool to set where I can stop the target tiles, so all tiles you will be able to attack from that tile. Is there a way we can visualize the tiles that’ll be target-able?

Hi there! The “Show Crosshairs” functionality is intentionally set up so that it does not find all tiles in range and then filter out the target units. Instead it just look at the tiles containing units, which requires a lot fewer calculations in almost all cases. This is the reason you have not been able to find any bool or function to switch off such a filter.

So to get the game to display all tiles in range you’ll need to make some additions. The blueprint nodes below have been connected in ATBTT_PlayerController to where the switches from ShowCrosshairs normally lead (far bottom right of the event graph). In the first part I use the Find Tiles In Range function to get and display all tiles in range of the hovered tile. The array manipulation on either side is to make it so the range arrays are set back to what they were before running the function, as these arrays inform what tiles can be attacked, and we want to use the function just for displaying tiles in our case.

https://i.imgur.com/d7ct8vn.png

Lastly we need to make sure that the displayed tiles are removed when we move the cursor to a new tile. These nodes are connected in the absolute bottom right of the event graph of ATBTT_PlayerController. I’m assuming you’re using meshes for tiles in sight range in this case. If you’re using decals instead, take a look in the ClearAllInRangeMarkers function in BP_GridManager to see how to do this with decals instead.

https://i.imgur.com/49KCEvS.png

Even though these calculations are fairly quick, if you have units with very large movement ranges (especially if you’re using multi-layer grids) and have not nativized the blueprints you could potentially see a drop in frame rate if the player quickly runs his/her mouse over multiple tiles in rapid succession. If you experience this, then I would add a tiny delay when hovering over a tile before finding the tiles in range (cancelling running the function if the hovered tile after the delay is not the same as the one before the delay).

Here is how it looks in action. Hope this is what you were trying to achieve:

https://imgur.com/a/ga7a4

Thank you for the info! Do you have an idea when the networked multiplayer update might be ready? No worries if it’s awhile out, just want to see if I should hold out on more custom changes and just wait for the update to continue.

To answer in boring, vague marketing terms: “weeks, not months” :stuck_out_tongue: It is mostly cleanup at this point, but new bugs keep popping up while I’m testing, so it is hard to predict exactly when I get it bug free and with all features working perfectly. A deadline I’ve hanging over me for my PhD has also slowed me down a bit.

Thank you for the update! Looking forward to this! Good luck on your PhD man!

Hi @
I’m going to bug you about something else when it comes to multiplayer and replication.

How have you dealt with spawning instanced static mesh objects on the tiles (i.e. the blue and red squares) when a player is moving or targeting? Do you do this purely on client side, so the other player can’t see their opponent’s move/target squares, or do you do it globally so it’s visible for all? I’m trying to do it purely client side, but I’m also using the “ActivateGridManager” function (particularly the collapsed graph at the end of that function) to set the values of the ISMs, for example, TileInMoveRangeMC. However, on the client side on the playercontroller (through my GridManagerRef variable) the TileInMoveRangeMC is just a null pointer. GridManagerRef itself is not null, I am successfully accessing the grid manager from the client side in player controller. I set TileInMoveRangeMC to “Replicates”, and I set the variables “bAlwaysRelevant” and “bReplicates” in GridManagerRef to true, but no luck. I even tried wrapping the collapsed graph (the one that sets values to TileInMoveRangeMC) in a RPC event, and I tried setting it to “Net Multicast” and “Run on owning Client”, but neither worked.

I read somewhere (I don’t remember where) that ISMs are not supported for replication. But that was just a random comment by a non-staff member. Otherwise I can’t find anyone else having my issue with replicating ISMs. How do you handle this?

Thanks.

Thanks! Deadline is tomorrow, so I should have more time shortly.

I’m spawning the ISMs client side, so I can assure you it is possible. Displaying tiles in sight and move range is handled in replicated ability blueprints in my WIP build. I pass input from the player controller to these blueprints which handle finding and displaying targets etc., mostly by calling functions from the grid manager. I can understand that you’ve had some trouble with this, because it is a bit tricky replication wise. Unless you have set things up differently, grid sized arrays like the Vector Field Array are not replicated (it would be a lot of data to send through), which means that if you try to run any function for spawning tiles on a client you’ll run into trouble, since the locations of all tiles are stored on the server. Therefore you have to get the appropriate locations on the server first and pass them to the client for display.

To give an example where you want to display tiles in move range around a unit when the unit is clicked:

Click input event in the player controller -> run event on the server that runs the Pathfinding function -> convert the array elements of IndexedCanMoveToArray to an array of locations locations by using ConvertIndexToLocation -> pass location array to a custom event running on the client, spawning an ISM on each location.

That is how I’m doing it currently, and it works great. Hope that helps!

I have a couple of questions for when you have some time. First, the current unit marker mesh doesn’t show on the current unit anymore, it only shows on index 0. I’m fairly certain I didn’t modify anything surrounding it. So far I’ve only changed stuff in the Receive Damage part of the Unit blueprint. I’ve looked through all references to this mesh with no luck. Any idea how I can go about fixing/troubleshooting this?

Second question isn’t exclusive to your toolkit. I copied the health stuff in the Receive Damage event to make second health bar that functions as “armor”. I have it all working fine, but I don’t know how to make it look the way I want it to. Do you know how can I make the HealthBillboard and the ArmorBillboard appear as a single material or stay aligned with each other? For example, if I put the armor bar above the health bar on the Z axis and I look up at the character from the ground, the health bar overlaps the armor bar.

I have an alternative route for the second question, which involves a 3D Widget. That works fine in the sense that the bars are aligned, but I can’t figure out how to get them to face towards the grid camera. If you have insight to that, that would be greatly appreciated also.

Thanks a lot for everything you do.

problems.PNG

@Zandothar: Hey an welcome :slight_smile: You first question is something that has been reported before. It is a pretty weird bug that I have no idea how to properly fix in the current build. Thankfully it is not an issue in the coming update, and it is also easy to prevent it from having an actual in-game impact in the current build. Here is what I answered last time this was asked:

As for your health bar question, I don’t think what you are trying to do is solvable by using two separate billboards, as they will overlap in strange ways. One way to do what you intend is to either make a more complex material for the health bar, so that is able to display both or, as you suggested, to use a 3D widget.

I’d probably go for the second solution, as it is easier and more flexible. The reason I’ve done it this way is so I do not need to have all units constantly running tick events, for performance reasons. However, this is very unlikely to have an actual performance impact for most games.

To rotate your bars appropriately to face the camera you’ll need to enable tick events in the unit blueprint and rotate the health bar to face the camera every tick. I’ve actually done so in one of the units in the toolkit already. Have a look at Unit_VR in Maps/VR. Here is the relevant bit of code:

when are you release multiplayer version? I’m waiting already 6 months

Thanks for the response.

To your suggestion, that’s basically what I’m doing. (Not exactly, but the main idea is the same.) I make a small array of only the locations (as FTransform objects) which are calculated server side, and that small array gets passed to the client successfully. So telling the client where to spawn the ISMs is no problem for me. However I haven’t been able to assign values to the ISMs on the client side (i.e. tell the client that these objects are big blue squares), so when it comes time to actually place them where I need them on the client side, TileInMoveRangeMC is just an empty object. Is it correct for me to say that (at least in your currently released build) this process is done in the collapsed graph at the end of the “Activate Grid Manager” function? If so, should I have that graph run client side? Because I tried that but it doesn’t seem to work for me.

Yeah this worked, thanks! Also had to add LocalCurrentUnit->!bHasUnitActedThisTurn before removing crosshairs and tiles in sight range because it was removing all attack tiles after moving.

https://puu.sh/xUDJ6/890358d46e.png

Sorry about the amount of time it has taken. I’ve explained the delay in several posts before, but the short version is that I am, as I’ve acknowledged before, really bad at assessing how long it takes to add new features. In this case, I’ve done a major refactoring of most parts of the toolkit, and the interdependence of all features has made it a bit of a nightmare in terms of ensuring compatibility and preventing bugs. This, in combination with a long summer vacation and several deadlines at work has made it take more time than planned. Though when you see all the changes that have been made in this update compared to any previous one, I hope you’ll come to understand why it has been so time consuming. The good news is that I’m close to the target now. It should onlt be a matter of weeks until I’m done.

Oh, sorry. I should have understood this from your previous post. What I’ve done is to connect the Add Mesh Components collapsed node in BP_GridManager to an unreplicated event, and I call this event from the player controller, causing the meshes to be tied to the client owning the player controller.

Glad it worked!

Thanks a ton for your help. I should have figured the answers were already there, so I’m sorry I didn’t thoroughly search for them before asking.

Thanks, that’s so simple! I’m such an idiot, I forgot that this event runs only once, at the beginning. So calling it that way couldn’t possibly do it for all clients. It’s one really simple dumb thing I overlooked that caused such a hassle for me.