Download

[SUPPORT] Advanced Turn Based Tile Toolkit

Question, how would one go about extending this to allow units to move in 3d space; I.E. Straight up or down ala flying such as the Jetpack Units in X-Com

Hey Lexx, that seems like a likely candidate function. You should proabably be able to get the result you want by doing the same checks after the line traces in this function as I suggested for for the regular FindTilesInRange. Could you paste a screenshot of how you’ve modified it so far? Then I can see what you might have done wrong.

This depends a lot on what exactly you want to achieve. There are various flight mechanics implemented differently in the XCOM and X-Com games so I have to make sure we are talking about the same thing. Could you explain in more detail what you want so I don’t answer the wrong question? Do you want the unit to be able to occupy distinct increments up in the air over a tile? Can there be another unit standing beneath it when it is flying? Can there be multiple flying units all occupying separate height increments above and below one another? Can the unit move around to new tiles while keeping the same height, or does it have to land first? All of these things are factors that will make the implementation more complex so consider what you really need.

Basically the answer to all of those questions is yes. The unit should be able to go above other units including other units in the air, and can go in an arbitrary direction while in air. I imagine it as instead of a grid, it’s a cube that you can move to an arbitrary sub-cube inside it. If that makes sense.

Monokkel, what resources would you recommend me for learning more advanced-level Blueprints knowledge required to work with this toolkit? I’ve been looking during the past weeks, but what I found is nowhere near the complexity of your powerful powwwerful stuff. Oh and, I do have some basic-to-intermediate programming knowledge in C++ and other scripting languages, but when it comes to understanding complex graphs like these, I’m usually dumbfounded.

Hmm, ok. In that case it is going to be pretty tricky. The way heightmaps currently works, line traces check all tile locations and add new heightmap levels in cases where it finds two or more separate meshes blocking the PathTrace trace channel overlapping one another, and which are also separated by at least [HeightBetweenLevels] distance of unblocked space. This means that on a map a bridge high over the ground will be at level 2, while the ground beneath will be level 1, but on the same map, a tunnel going under the ground will have tiles at level 1 in the tunnel, while the tiles at ground level above it will be at level 2. This means that there is no direct relationship between how high up a tile is and what level it is considered to be at.

This is something I did initially as an optimization measure, to reduce the amount of height levels on a map to the minimum number needed. This was when I was still using arrays instead of TMaps for all grid size arrays, which meant that every time a new level was added all the different grid sized arrays had to be resized by GridSizeX*GridSizeY. Now that I have converted all such arrays to TMaps this is no longer necessary, as maps allow you to only add the indexes you actually use. In the live version GridEdges is still an array, but in my WIP version this too is a TMap. This has allowed me to change the heightmap system so that the level of a tile has a direct relationship to its height. This should make it easier (though still quite difficult) to add something like you are suggesting.

So if you want to add this to your game I will recommend you to work on other aspects of your game first and to add this in after my next update. Bear in mind that it is likely several months before this update is done.

If you cannot wait and you need this feature immediately I will do my best to think up the best way forward. Though be warned that even with my help you will need a really good grasp on both blueprints in general and the toolkit in particular to make this work with all aspects of the toolkit.

Hey Justo, thanks for the compliment :slight_smile: I hope I have made the toolkit intuitive enough that most users will be able to work with it and do moderate modifications with only intermediate knowledge of blueprints, but it is true that if you want to heavily modify the core systems in the toolkit you are going to have a pretty good understanding. I also hope my blueprints serve as good learning material for ways to utilize the power of blueprints and how to structure a blueprint-heavy project.

When it comes to tutorials and learning material besides my own, it is indeed true that much of what you will find is fairly basic. This is true for almost any software, as there will always be a lot more newbies than more experienced developers, so it often makes sense to gear tutorials towards them. I think your best bet is just to get a lot of practice with blueprints. Set yourself goals and try to make stuff work with it. Basically the same thing you would do for any other scripting or programming language. Then when you know how to do the same things in blueprints as you can in other languages you can look up tutorials and guides that use other languages or pseudo code. I personally got a lot of use out of the amazing tutorials on grid math and pathfinding by Amit Patel when I first started out. Even though the code examples are in pseudo code, almost all the same principles apply to blueprints.

I’m not sure there is much else I can say than that. I started making this toolkit when I had basically zero coding experience, and the last few years has been a constant learning experience, where I every now and then look back at what I have done, see all my stupid mistakes and refactor everything. Coding it is the kind of thing where there is always more to learn, which is both daunting and amazing. In the end I think nothing really beats learning by doing.

I think that’s very good advice Monokkel, thank you (: I’m playing right now with the toolkit actually. And make no mistake, it is all fairly intuitive just like you say, and the descriptions you’ve added to everything are a huge help. It’s a lot to take in of course, so it’ll take some time to get my head around this. But it’s just like you say - small goals and learning through trial and error.

hi knut

i saw your progress on v1.10 in trello, looks great!!!

i hope you are putting a Boolean of the version changes every place you did a change? i modified the toolkit so much so for me using a new project when the new version update will come is not an option.

cheers
leo

Hi Monokkel,

I think you skiped my message from some days ago :stuck_out_tongue: (it was waiting for moderation aproval on thursday and published on friday because I never posted before :slight_smile: )

Grégoire

Best of luck, and let me know if you need any input :slight_smile:

I’m marking the major changes, but I do not mark everything. Two major changes I have done are changing the GridEdges array to a map and to switch to a grid index system where the index of a location is affected by the size of the grid, to one which is independent of grid size. Both of these changes mean I need to change every function in the toolkit that uses the GridEdges array or uses GridSizeX and GridSizeY to determine a grid index. If I were to add a boolean marker every such place things would begin to look very messy very quickly. For more specific changes I try to always include a marker, though.

Whoops, indeed I did. Sorry about that. Weird that I did not see that comment. Maybe it is because of it being hidden while waiting for approval, as you suggest. I’ll get to your question now.

Should not be terribly difficult, I think. You basically just need to create a new variable similar to CurrentAP in BP_Unit that holds the MP. Then for abilities that use this resource you would change the checks and modifications of the CurrentAP variable to instead reference CurrentMP. The reason AP is set to 0 and the turn ends when you’re using the ability you describe is probably because it has bUseEndsTurn set to true in its variables.

hi knut

ok, I understand

thanks for your answer

leo

About the above sentence: I saw that the CurrentTurn Counter that exists in the TurnManager Blueprint is not updated correctly.
I am trying to create a “Faction Turn” that increments when every unit in a Faction are exhausted.
What can be the best approach to achieve that?

I saw the enum option to change the End Turn behaviour (End, First, etc.) but if I change the default value to “Last in Faction” the whole toolkit do not manage correctly the turn end anymore and I have exhausted units active to receive another input, blocking the game flow.

thanks! I’ll look into it!

I do unfortunately have limited options when it comes to keeping the toolkit easy to update while at the same time striving to make it the best it can be. I’ve got a bit of a refactoring addiction, I think, and it is difficult to stop myself from overhauling large parts of the toolkit whenever I see the potential for even a slight improvement. When it comes to things like the modified GridEdges array it is at least possible for you to search for this specific variable, and its use in all blueprints and functions should be displayed.

CurrentTurn seems to be updated correctly on my end. Are you using the latest version? For incrementing the turn when the last unit in a faction ends its turn I would modify the EndActiveActorTurn event in BP_TurnManager. At the start of the event compare the faction of the unit at index 0 of InitiativeOrderActors (which should be the current active unit, which we are ending the turn for) to index 1 (next unit in line). If these are different, increment your turn value.

As for the end turn stuff and the LastInFaction enum, yeah, that particular selection might not work correctly if it is used in ways that are different from the standard approach of the toolkit. It essentially looks at all units from index 0 and onwards until it finds an actor with a different faction than the current active unit and inserts the active unit in front of this one. That works in some scenarios, but might not in others. I’ll put it on my list of stuff to refactor. If you take a look at the nodes of the function it should be fairly easy to interpret. All of the functions for sorting are essentially just swapping elements of the initiative order array according to different rules.

Best of luck!

hi knut

Do not get me wrong, I prefer (and happy) to do the dirty work of updating my project to your new version (even if it means working on all the functions one by one) and most importantly you continue to improve and add new layers,your overhauling everything and refactoring- that’s what makes this project so Good and special in my opinion.

cheers
leo

Had some fun with pathfinding today and made a better teleporter than the one in my tutorial. This one will be usable by the AI as well. In my next update I will be including an “experimental” map where I throw in some fun stuff like this, which is not part of the main toolkit or fits particularly well with a custom map, or is just not ready for primetime, but which might be good learning material.

Yep, I think what I’m doing is the best for most people in the end, but I knowledge that this means updates can be a bit frustrating sometimes.

hey knut
i have a question about the turn based system, i just watched the tutorial u made 2 months ago but i didnt really find a solution for myself (im just a little experienced in blueprints, but not this much as u are).
heres the question:
i want make a game, where i can select my character, and when im done with this character, the enemy AI is on turn and can play 1 random of his characters. after this its again my turn and i can play 1 of the other character i have, then the AI with 1 character and so on…

what do i have to change to make this work?

thanks

Hi Artjom, you can achieve this effect with a couple of modifications.First replace all calls to the EndActiveActorTurn event in BP_TurnManager with calls to EndEntireFactionTurn (a function also in BP_TurnManager). You can find all instances of a function or event by right clicking it, selecting “Find References” and then clicking the “Find in All Blueprints” binoculars icon. This will cause the turn to end for the entire faction whenever the turn would normally just end for a single unit, which I think is what you’re after.

All that remains is to add some nodes so that the AI selects a random unit to use each turn. To do this you could add a check at BeginActorTurn (in BP_TurnManager) to see if the unit to be activated is AI controlled. If it is you would loop through the initiative order array until you find a unit with a different faction than the AI unit. Then you would pick a random item in the initiative array between 0 and this index -1, and continue the BeginActorTurn nodes using this unit.

Hope that helps!

hey knut
thanks for the reply!
but honestly i dont really understand this part:

how do i check something there?
also “loop through the initiative order array until you find a unit with a different faction than the AI unit.”, i dont really know how and where i loop something :o

do you have a screenshot of how it should look like? so i just can add the needed loops where they belong to.

im not even sure if i did the replacement from EndEntireFactionTurn to EndActiveActorTurn right…
i added 2 screenshots, on the second one i dont know how i replace this condition(?) to end entire faction.

im so sorry i dont understand so much, but maybe you can add 1-2 screenshots of how it should look like.

thanks knut!

Sorry, I was a bit unclear. I\ll try to be more specific. I did not mean to change the boolean in the event or anything like that. I’ll try to explain. There are several actors in the toolkit that call on the turn manager to end the current unit’s turn. For example this happens in BP_Unit when the unit has 0 AP left, and it happens in the player controller when the player presses the end turn button. You want the turn to end for the entire faction and not just a single unit in all these cases. That means that you need to go to all blueprints that call this event (EndActiveActorTurn) and replace this call to instead call the EndEntireFactionTurn function. You do not need to replace anything in the turn manager itself to achieve this effect.

After you have done this, you have basically the effect you were after. The only problem is that for the AI, the first unit in initiative order will always be the one selected. You said you wanted to select a random AI unit, so you need to make a change to make this happen. You can do this by adding a check at the beginning of the BeginActorTurn event. You do this by adding a branch right at the start of the event that checks the actor coming in, casts it to BP_Unit (continuing as normal if the cast fails). If the cast is successful it check the bAIControlled variable of the unit. If this is false, we continue as usual. If it is true we want to select a random unit from the AI units at the top of the array (for this example we are assuming that there are no factions that have both player and AI controlled units).

To select a random unit we need to check through the InitiativeOrderActors array. As long as you have set up the initiative variables of the units so that there is no overlap between the factions, the first few actors should now be all the units of the AI’s faction. We want to pick one at random from these, but first we need to find out how many we have to pick from. For this we get a reference to the InitiativeOrderActors event and run a for each loop with break through it. For each element we cast to BP_Unit and get its faction. We do this until either the cast returns false or the faction is different from the faction of the unit at index 0. When this happens we know that we have found the first unit in initiative that we do not want to pick from. When this happens we store the current index of the loop -1 and break the loop. Then we pick a random actor from the array using the Get node and a random integer in range (from 0 to our stored index) and run the rest of the BeginActorTurn code using this unit.

Hope that makes more sense.

hmm so i changed everywhere the EndActiveActorTurn with EndEntireFactionTurn, but its not working right, sometimes the player is possible to play 2 characters in a row, also i cant select some other unit in my turn, there is everytime some unit i have to play, but no player choice to pick a unit.