Sort actors in array by their INT (turn based combat)

Hello!

I want to try make a turn based combat system in UE4, but I am stuck when it comes to choosing whose turn it is.
I’ve seriously Googled myself to (almost) death.

I’m not sure I have dont this the correct way, but here is how I have set up my characters:

  • Blueprint base of “Enemy”, and made child blueprints off this to make different types of enemies.
  • Blueprint base of “Player”, and made child blueprints off this to make different playable characters.

I’ve made a structure containing things like name, HP, speed, etc.

Picture a turn based combat like Final Fantasy X, where the one with the highest speed/agility will act first.

Is it possible to put 2 different kinds of blueprint classes in an array, sort by INT (speed), and then notify the character with the highest speed INT to act? Or how can I do this?

I’m really lost here, I’ve tried different things but no luck. Hope you guys can help me or point me in the right direction :slight_smile:

first let me say sorting is possible and relatively simple. there are however some questions to ask. will the order need to change (speed/ agility modifiers)? are you only going to calculate the list once at the start of combat or does it need to keep being modified?

anyways the basics of sorting an array would be to have two nested for loops and two arrays. to begin you would need a n array that contains all your characters. then you would need a for each loop that takes that array and gets the characters speed value, then that information would be fed into another foreach loop that compares the current characters speed to that of the characters in the second array. when the loop finds a character in the second array that has less speed then the current character is added to the array at the index just before the slower one. also note that if you are planning to do this for your player characters and the enemies then you may want them to inherit from a common class so that they will have a common speed variable and can actually be compared to one another.

there may be a better solution than this but this is the basics.

Hey!

Well, it would be nice if I could manage to make some kind of turn order list in the HUD, displaying current character turn + a few more, say displaying up to 6 characters. If there are only 4 characters in battle, the last 2 of the six would be the ones in place 1 and 2 (repeat).

Like Final Fantasy X, top right:

(I was thinking of maybe having abilities like “haste” which increases the character’s speed/frequency in battle, but trying to think how that would work just makes my head spin :D)

So for this task, the characters will have a set speed. Let’s just say…

Player 1: 12
Player 2: 14
Player 3: 10
Enemy 1: 11
Enemy 2: 9
Enemy 3: 13

I’m not trying to be difficult here, but do you think it’s possible if you could show me in blueprints? Looking from the text I’m not really sure I have done this thing right.

So to just make this a bit easier, if I concentrate on the ENEMIES in the first place, we have 3 enemies… I made an image instead. Please have a look at that!

If I understand you right, I should have EVERY character on the battle field share the same BP class? And make both enemy and player character children out of it?

Another question though, but I may need to ask this later, is IF two or more characters share the same speed, say there are 2 enemies that share the same speed? Will you be able to just pick the first in the array with the equal speed, and then the second one next? I’m sorry if it’s hard to understand my question.

Thank you!

below a example of what i was talking about. this is all to create a very basic sorted list, for your purposes i dont feel this will be the complete script though. for instance in final fantasy the attack order is in constant flux and is updated often. also in many fights certain characters will have multiple attacks before the boss does. so this may not be the ideal solution, but actually more of the first step.

now i suppose i should explain how the script works. to begin i get all teh characters and add them to an array (may not need this but i like to be able to access a standard list when needed). then for each character we need to decide their placement by comparing the speed stat to the others in the list which is the rest of the script. first though we need to add one character to the list so we have something to compare to, so index 0 gets filled with the first character(char1) from the character list. we then move to the second character(char2) on the list and we compare their speed to the speed of char1 which is in index 0, if the speed of char2 is greater than char1 then char2 is inserted into index0, if not then we compare char2 speed to the char in index1. in this case there is no char in index 1 so char2 would be slotted in there. once the character is placed in the proper index there is no need to continue going through the loop so we simply need to break out (i used a custom event for this).

to answer your questions at the bottom of your post: i would have every character that will have stats inherit from one class. so i would create a baseCharacter class which contains the variables for stats and maybe even some basic functionality like damage handling (if you wanted). then have the player characters and the enemies as children of the base character class. this way you can avoid some of the casts and checks that would be required otherwise.

as for your other question at the bottom, the case of two characters with the same speed is handled by using the >= operand (you could use others depending on how you want the situation handled). the operand is basically like the rules for placement. if using > its like asking is char2 speed greater than char1, no then move on. but in this case we added one more check to the rule if = then char2 two also wins. so if char2 speed is greater than or equal then it takes the index of the one being compared to.

so lets see an example given 3 players: p1 speed = 5, p2 speed = 7, and p3 speed = 5. if using the > then the attack order would be p2 p1 p3, but if using the >= then the attack order would be p2 p3 p1.

thats if i didnt mess up anywhere haha

a thought just occurred to me, what about using timers? coudnt that make for a much more manageable system. now i dont know the specifics but each character could have their own timer and each time the timer reached 0 you add them to the attack order list. then you base which character you have control of based on the list. and all of the multiple attacks part is then a non issue and for the haste and slow issues you just modify the timer length or tick speed based on the characters speed stat. thinking about it now i think thats the kind of system used in ff7 if i recall correctly or at least thats how it looked with their atb active time battle system.

i suggest looking at Battle system | Final Fantasy Wiki | Fandom it has a good explanation.

Hey! Thank you so much!! i will have a look at this when I get time. Really appreciate it!! :slight_smile:

Hey! Thank you so much for your time. I have been trying out this the whole day, and I am getting closer, I just have a few issues. I know you said I’d probably need some more scripting than this, but. I really really cannot figure out how to do it. The sorting stuff is killing me.

I think this image explains most of it.

I’d actually need (I think) an array of all the actors with the correct speed order. Then I’d give them all a turn order INT, so if they get killed I can just remove their index from the array. That’s what I’ve been doing at least.

In this image the turn order and turn order list is really random depending on which character joins the battle (it’s random from a list of 3 atm).

I also know about the ATB battle system, but that sounds way more difficult?? I’ll definitely look into it. Because this here really takes so much time and I don’t feel I get any further haha. I really can’t find any guides or tutorials on this either! x_x

i just gave it a quick look and i may have forgotten the else part. basically it looks like i forgot to add what to do if the speed isnt greater than any other character. should be an easy fix, you just need to add in a condition to the completed pin of the second for each loop that says if you reach the last index and havent placed the actor add it to the attack list, which will result in it being added as the last index. so it would be on completed get attack order → get last index → last index = array index → branch → if true add character to attack order. this can also be done off of the false pin of the branch just after the speed comparison (as shown Below). this may be a more reliable solution but you would need to ensure you call the break loop after so you dont add the character to the attack list many times.

one note on doing the script off the completed pin there is one condition i can think of where the character could be added twice and thats if the character being placed is faster than only the last array index. to resolve this you could do the speed check again or find another way to eliminate the issue.

hope that helps i havent fully tested but it should work.

Oh my god I think it actually works!! :smiley: I will test it out a bit more, but this looks really nice now. Thank you so much for your help!