[SUPPORT] Advanced Turn Based Tile Toolkit

@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.

Hey , I’m working on implementing Line of Sight based visibility of enemy pawns. Most of it’s working fine, but I’d like your suggestion in one last area. By default, the enemy pawns are set to invisible if the player doesn’t have a line of sight to them. When a player unit moves through tiles which should technically grant a clear line of sight to an enemy unit, I’d like to make that particular enemy unit visible from the said tiles.

I figured that using ‘Find Tiles in Range’ for each tile in movement might be the most accurate approach, but may end up being a bit too costly. An alternative approach would be to have an invisible square/circle collision mesh that can detect enemy pawns during movement. If any enemy unit overlaps with the mesh during movement, we make them visible/hidden based on a line trace as well as whether they’re already visible from any other unit from player team. It will give clean results for square line of sight, but is a bit inaccurate if we go for Diamond line of sight. Maybe checking the distance to overlapped units and comparing with the range of the unit could take care of that situation as well.

It’s more of a hack approach as I really do not have any need for the storage of information regarding enemy pawns that the bot sees while it’s moving. Would you suggest any alternate approaches to handling this particular situation?

Sorry for the delayed response, I got side-tracked into setting up other gameplay systems/map building, and forgot to check back here to see if you replied yet…

Anyway, I tried adding the node as you show there, but it doesn’t seem to have any effect what so ever, movement over and around different height hexes remained unchanged (as in, the pawn couldn’t jump off cliffs, or walk directly to the highest point of a cliff-side, it still went around the long way to gradually move to the top). I even tried just setting it to 1 without the Int Select node, and it too had no effect. Note that I am still running in 4.7 (too lazy to update just yet…), so could it be something that you changed in the 4.8 version that I’m missing, or possibly a bug with 4.7 itself…?

@: Ok, I’ve run some tests. I think using Find Tiles In Range will actually work pretty well. If you check “Find only Pawns” it’s actually pretty **** quick, and testing with a unit with a range of 20 with 20 enemy units within range it found all pawns within range with tracing for RangeTrace in 65 milliseconds, much less than a frame. That being said, using a volume to check for overlapping actors is still orders of magnitude quicker, with 0.054 milliseconds without tracing and 0.60 milliseconds with tracing. Choosing one method or the other is highly unlikely to have any perceiavable impact on performance, but those are the numbers, in any case.

You can quite easily create volumes in UE4 that fit diamond shaped and hexagonal visibility. For diamond shaped, use a cone volume aligned to its side. For hexagonal visibility use a cylindrical volume with 6 sides. I’ll be adding something like this myself in the update after the next, as it will be useful for overwatch-style events. Unsure what method I’ll end up using. I’m pretty **** when it comes to choosing the most efficient solution possible, but I also prefer keeping things within the grid arrays if I’m able.

@ Thanks for the statistics man. I didn’t expect the solution to be this detailed. :smiley: I was thinking of a sphere collision mesh to get better coverage for detecting pawns in elevated/lower positions.

Yea it’s definitely better to use grid arrays for most cases. I’m using the grid arrays for the rest of the LoS functionality so that I can extend it to use for Overwatch. However in this particular scenario, I do not have any need for storing the data regarding the spotted enemy pawns while moving. So I’m going to try out the collision mesh for now.

Hey , I read on the last page some stuff about adding extra factions but wondered if you go more into detail on that?

Trying to add a third faction that would attack both player and enemy

@Shenku: Oh, I see what went wrong here. I only made it so that difficult terrain is ignored (edges with a cost of 2 or below), not impassable terrain (edges with a cost of 0). That’s handled by the second and third branches in Search and Add Tile. However, you cannot simply skip these checks for flying units, as they would be able to walk through walls or leave the bounds of the grid. Solving this one was a bit more tricky, but in doing so I found a bug in the toolkit that I was not aware of, so thanks :slight_smile: There are a few ways to do this. One is to create a separate Search And Add Tile function for flying units where you skip the branches that check if an edge costs 0 and instead check if the parent tile is on one of the grid edges, in which case you do not add the indexes to the pathfinding that are in the direction of the edge. Another version that’s quicker to implement is to use the solution I posted above, and make tiles that have a large height difference have an edge cost of 99 instead of 0. This is somewhat less efficient for pathfinding, but shouldn’t matter that much. You need to do two changes to fix this, where one of them is to fix the bug I was unaware of (which I will fix in the next update). Go to the Add Viewport Terrain To Arrays function, and replace all the nodes in the top, right comment box with this. This makes it so that height is also checked diagonally, while before it was only checked in four directions. This is something that works with edge costs of 0, but not with edge costs higher than 1. Then in the Edge Costs From Z Difference macro you will change it to this:

This will make edge costs 99 between tiles of sufficient height instead of 0, which makes it possible for flying units to ignore it, as per the previous solution. It will still look a bit weird, though, as the units are likely to clip through walls, but I’m sure you can find a solution. If not I can try to come up with some ideas.

@: Don’t worry about it. It was something I was going to check out sooner or later anyway. Pawns in lower and higher positions should not be an issue for cylinders, and come to think of it you could just use a box rotated 45 degrees for diamond shaped visibility, which should also work for height, dependent on what you’re after. Boxes if you want the max height to be the same for all distances or cone volumes if you want it to vary as a function of the distance.

Let me know how your attempt pans out, as I’ll be implementing something similar in the not too distant future.

@tamaster92: Like you’ve said I’ve written about this before. It’s a bit hard to go into detail, as I haven’t tried it out myself yet, but I’ll give you the general solution and you can ask me specific questions if you have trouble implementing it. You will have to create a new faction in the faction struct for your new faction. Then you will have to change the parts of ATBTT_GameMode that change depending on the faction of the current pawn. Then you will have to change the parts in BP_GridManager, ATBTT_PlayerController and ATBTT_AIController that reference factions to take the new factions into account. In general you will have to change stuff that before said “if index X contains faction player, attack” to “if index X does not contain faction NewGuys or faction empty, attack”. Some of the main stuff you will need to modify is Pathfinding and Find Tiles in Range, since they both check for a specific faction. What you need to do is fairly straightforward, but a lot of stuff about factions is spread out through a lot of blueprints, so I wouldn’t attempt this until you feel you have a really good overview of the toolkit. I will be doing something similar in the future, but it’s a few updates away.

Okay, I added in the change for the Edge Costs From Z Difference macro, and it works like a charm. I tried to copy in the other part for fixing the bug you mentioned for square grids, but as soon as I pasted it into the Blueprint, Unreal crashed, so not sure what happened there(Probably because I’m using 4.7 maybe?)… No big loss though, since I’m using Hexes for my game anyways, and that works without the additional fix…

That’s easy enough to compensate for through animations or other means, so I’m not too concerned for the moment. After some quick testing, it’s only really noticeable for some of the more extreme height changes, but with a little tweaking I think it’s manageable.

@ Yes, rotated boxes maybe even better. Less polycount as well. Yea sure, I’ll post a video on the LoS part as soon as I get it completely working.

**@Shenku: **Good to hear that it worked! The bug doesn’t have any effect on hexagonal grids like you figured, so you’re in the clear. I’ll fix it in the next update in any case. Good luck on the animating bit. Looking forward to seeing how it turns out :slight_smile:

**@: **Great! I don’t think you’ll have to worry about polycount. You’ll only be using a single invisible shape, so even if you wanted to go beyond simple polygons it shouldn’t matter. Still, no reason do do something complex if simple works just as well.

So UE4 4.9 Preview is out and it seems like it will be a much smoother transition than 4.8 was. There are a few errors in the log, but nothing that seems to have any effect on the toolkit’s functionality. As such it does not seem necessary to make a conversion guide like I did with 4.8. There is one bizzare bug that has caused collision to be turned of for a strip of terrain in the second example map, but that seems to be a one-off error that cannot be replicated, so I see no need to touch it until I do a proper update for the full 4.9 release.

Hi ,

Do you ever thinked about the possibility of make building roofs transparent for the BP Camera in case there are pawns inside the building?
I am sure that if you played a lot of turn based games like XCOM and Jagged Alliance you know what I’m talking about.

How can I create a system like that? I’ve read about firing raycasts from pawns to the camera and if there is a roof from the pawn to the camera just set an Opaque = 0 translucent material.
It really can work like that?

Hi Wisdom-,

you’ve basically figured it out already. It’s very easy to set up, and I intend to include such a feature come the XCOM-style game example. Here is a forum post by Chance Ivey explaining how it can be done: Diablo Style Wall Hiding in Blueprints - Programming & Scripting - Epic Developer Community Forums

I’ve already implemented Cover System and Overwatch in my game, I’m pretty curious to check if we had the same idea :slight_smile:

On the other hand I’m really excited to get the multi-level grids and fog-of-war, but I did many changes on the toolkit’s core :frowning:

EDIT: if is impossible to have multi-level grid and fog-of-war functions (because of plugin protection) into a dedicated BlueprintUE web page, is it more reasonable to have the new functions very well marked and commented in the new code release?
In this way I could create a new project with the new version and just copy-paste what I need to my project :slight_smile:

That’s pretty much how I’ve been doing it so far. I try to mark every change I make in the toolkit blueprints with a boolean marker variable named after the version in which it was added, commented with a brief description of the change. If you right click on one of these version booleans you can find all instances of the funtion and be guided around the blueprints to where changes have been made. I think this is more practical than BlueprintUE for both users and myself.

I’m looking forward to adding XCOM-style features, and will get to work on that as soon as the 2D-update is out. That update is mostly done, but I won’t be able to finish it until early next month, since I’ll be on vacation travelling all of august. I will still be availible online to provide support as always, though :slight_smile:

Hi ,

I was wondering if it was possible to do a tutorial on having weapon pickups. Basically, changing the unit_player_melee character’s boolean “HasGun” would change the animation states (so that the idle is now an idle with gun; the attack is a hip shot instead of a punch) the range and the targeting of the attack (instead of just highlighting the tiles around the character) so that while the boolean is true the character can act just like a unit_player_ranged. Ideally I would want this to be dynamic instead of swapping between two pawn types!

The weapon pickup class would contain the information about the weapon (such as damage and range).

This would eventually lead to being able to swap between multiple weapons during the player’s turn by changing the value of a current_weapon_index variable (such as unarmed melee, ranged hip shooter and grenade launcher).

Hello Monokkell,
I am trying to put in an end turn button that will end the player turn for all pawns and begin the AI turn. I currently have it cycle through all of the pawns and use a switch on enum until it gets to the AI pawn. Where would be a good place to put and event or something that would jump right to the AI turn. I know I will still have to set the current pawn to what ever AI pawn is used. Any help with this would be appreciated, Thank you in advance.

I think a cover system is better without an accuracy mechanic, because the randomization makes a game less tactical. Cover could reduce the damage by 50 %. A flanking mechanic makes a game much more tactical and it should be as important as the cover system. Flanking could increase the damage by 50 %.

A range mechanic would be great, too. Every weapon could have an optimal range and if the target is not in that range the attack inflicts less damage. For example a shotgun could have an optimal range of 5 tiles and if the target is 12 tiles away the damage could be reduced by 70 %.

Hi Wizard,

I was able to implement a flanking logic (and rear attack also) almost easily by modifying 's toolkit logic a bit.
Anyway I also think he can include this funcionality in the XCOM tutorial because for example real XCOM game has flanking option too :slight_smile:

First I apologize for taking so long to reply. I’ve been travelling for the last couple of days, but now I’ve got access to hotel WiFi and should be able to respond more quickly.

Hi cooleyo, that might be something several people might be interested in, so I’ll consider making a tutorial about it. I won’t be able to until I’m back home again, though. Here is my first idea on how to achieve this, though.

I’d first create a new actor type called weapon, which has a weapon mesh and variables for whatever attributes are tied to the weapon (a bool for damage, an integer for range etc.). Then I’d add this actor as a component to Unit_Parent and create various child actors for separate weapons. When the unit pick up a weapon I would change the unit’s weapon component to whatever weapon it is picking up. I’d then change the inputs in the various blueprints that get their input from stats such as range and damage to instead get the input from the variables stored within the unit’s current weapon.

That should cover everything except for animation. Animation is not my strong suit, so there might be many ways to do this. If there is some way to simply swap out the various animations in the animation graphs based on the value of the weapon variable , then this would probably be the best idea. If not, one could make a more complex animation graphs that checks this value at the first branch entered in the graph, and branch off into different sub-graphs dependent on the weapon. I can’t look into this without my home computer, so let me know if you test this out and find a better solution.

By default the current pawn is set in ATBTT_GameMode to whatever unit is currently on index 0 in the Initiative Order Array. When a unit ends its turn a custom event (the name escapes me) is called in ATBTT_GameMode that among other things runs the function “make the first pawn in initiative become the last” (I was a bit biblical in naming this one :stuck_out_tongue: ). This sets the previous pawn at the last index of Initiative Order Array and shuffles the array so that every unit is one index higher (the one that was 1 becomes 0, since 0 is now empty etc.).

For jumping to the AI’s turn, provided you still want the AI and player to have separate distinct turns, I would run this function on a while loop multiple times until the unit at index 0 has a faction variable of AI. I would put this at roughly the same place as the regular function is in the game mode now. I’d create a new variable called “Skip until AI unit found” or something that can be set from whatever place the player has the option to select this input. I’d create a branch on this variable in the game mode, and if true it should go to the while loop and if not use the regular, single “make the first pawn…” function.

Thanks for the input! I agree that turn based games without random probabilities can be really good. The Banner Saga is an excellent example of this. I think games with random probabilities can be just as good, however, but it is something that has to be carefully though about and must mesh with the rest of the gameplay. For instance, I think the randomness in XCOM makes the game better, as many of the game’s most engaging moments happen when you suddenly make that lucky shot that gets you out of a seemingly impossible situation, or a sneaky alien suddenly manages to taker out your only sniper, forcing you to rethink your tactics. I think randomness can too easily be used as a crutch for gameplay that is not properly balanced, though, and think more TBS games should consider not using random number generators for things like accuracy.

However, for my game example I intend to include randomness as the current toolkit does not use randomness at all, and as such I can show users how to set this up. It should be easier for users to remove the random systems from the example than it would be to add their own.

Incidentally setting up flanking and range to impact damage is pretty easy. For range, when inputting damage you could check the value of the range array for the index the target is standing on and reduce the damage depending on this. For flanking you could find units in a certain range of the target and if they are at certain positions (for instance if there are at least two enemy units within this range, where one has a Y or X coordinate higher than the target, while the other has one lower) you could increase damage.

I’ll probably add it in. It should, like I said, be fairly easy to add. The reason I haven’t added anything like this to the default toolkit is that I don’t want it cluttered with lots of if-statements for things that won’t be in many games. For game examples I have no such scruples, though :slight_smile: