I am making a turn-based RPG game in UE5 with C++ (with 2D sprites). Think of something like Darkest Dungeon but with memes and no procedural generation. For the most part my combat system works, but sometimes the turn triggers for an allied character that isn’t even in the party (another ally performs their attack) and sometimes the turn triggers for two allies at once - when one attacks, the other does too, same with using an items.
For my allies I have two arrays - AlvailableAllies that stores all allies regardless of whether they’re in the party or not and AlliedParty - the actual party.
For fight encounters I have an actor class - AFightEncounter that spawns enemies and deals with what happens after the fight and a regular object UFight that is created when the fight is started and handles the fight itself.
I’ve tried debugging - looks like StartTurn() (and Use Item() as well when we choose to use an item) is called twice for different allies, I suspect it might be ralated to my timers - one that introduces a bit of delay between turns, the other that prevents the enemy from being stuck on their turn when they can’t use any skill. I honestly don’t have any idea what to do about it.
Here’s the code on pastebin, because I don’t know if there’s a character limit here:
If it’s not very readible lket me know if i should split each source file into separate link. Thank you in advance.
Unfortunately there is too little information to dig into the problem.
I’m guessing that maybe the building of AlliedParty inside of your CurrentGameMode may be the source of the problem. I don’t have access to the function that builds the allied party but maybe you are duplicating the pointer to a specific character (maybe a bad for loop?)
Maybe consider using AddUnique for your TArray to not add duplicates.
This is the variable that really dictates how the turns pan out as it takes in the allied party and then enemies to build the turn order in void UFight::BuildTurnOrder(){}.
I pasted my DefaultGameMode class here: DefaultGameMode - Pastebin.com
Although I don’t understand how it could cause starting a turn twice with different allies. If you explained it a bit I’d really appreciate it.
Edit: Oh, and i’m actually using AddUnique both for Available allies and AlliedParty, completely forgot that as it was couple of months ago
Well it’s just causing more missing files at this point. Try putting a break-point durning the turn build process (in visual studio F9) and then try stepping through the code (F10) to see where the errors are occurring
You can disable code optimizations with this:
It will help you evaluate the contents of TArrays while the code is running (usually optimizations will obstruct the code)
Other than this on the screenshot I don’t see anything weird (it just is like that at the end, when I’m enqueueing the tail is the first character from BothParties, then it disappears). BothParies array is fine, nothing unexpected here.
Maybe it’s garbage collected somehow, but when I try set it as a Uproperty it won’t compile. Maybe i can ditch the queue and make it a regular array that i remove the last element from at the beggining of the turn so i can make it a uproperty but I don’t know if it’ll make it any better
Maybe you should consider isolating the queue for the fight & it’s logic to a separate fight manager. Right now you seem to have the logic for building and managing the flow of battle spread out to many areas.
Sometimes the game mode, other times the in AFightEncounter.
The funny thing is it doesn’t happen when staring new game or loading from save, only after adding new ally to party/replacing one ally with another, I change how I handle that but it still happens
Could it be that 2 allies always just have a higher speed that dictate that they start the turn?
Maybe the speed calculation is somehow influencing the outcome?
I’ve noticed that the Fight has it’s own timer and each character internally also has their own timer.
you use CurrentCharacter->TurnTimer at one point but do not ever clear or reset it. Is this done internally through ACombatCharacter::BeginTurn function?
No, everthing is inside UFight, the TurnTimer handle exist only in UFight, I used characters because only Actors have access to the world timer manager
EDIT: I completely forgot the characters have their own turn timer as well lol
Copilot suggested checking if TurnQueue is empty at the start of a turn, to my surprise it might have worked, because I played 3 fights like I did before and haven’t encountered those problems. Obviously the sample size is a bit too small to know for sure and that solution seem random but I’ll take whatever I can get