AI Behavior is Inconsistent

Hello, Recently i started to work again with behavior trees but i cant help but notice that my AI Behavior is very inconsistent, Right now the expected behavior is bots to spawn on the world, go inside a specific building (tavern) , Find an available seat that matches their race type (This is done iterating the focused room, looking into its component to find a seat and also using a Enum for the customer race type )

Now This works about half the times i hit the play button, the other half most of the Bots either dont pick a seat or stay outside, or move into the tavern / building but dont pick a seat and so on
I checked every line of code and added logs to make sure the behavior tree was running properly trough each task and it is but i cant nail why the AI is so inconsistent

This is how the tree looks right now

And here is the code for The relevant behavior tree tasks

//TTBTTask_GetSeat



EBTNodeResult::Type UTTBTTask_GetSeat::ExecuteTask(class UBehaviorTreeComponent* OwnerComp, uint8* NodeMemory)
{
	UBehaviorTreeComponent* MyComp = OwnerComp;
	UNavigationSystem* const NavSys = GetWorld()->GetNavigationSystem();

		ATTRoom* CustomerRoom = Cast<ATTRoom>(OwnerComp->GetBlackboardComponent()->GetValueAsObject("CurrentRoom"));
		if (CustomerRoom)
		{
				UTTSeatComponent* Seat = CustomerRoom->GetRoomSeats(); // Get a pointer to a seat in the current room

				if (Seat == nullptr) // if no seats available
				{
					GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Seat is nullptr"));
					return EBTNodeResult::Failed;
				}
				
				if (Seat != nullptr) // if the seat is not taken 
				{

				FVector Destination = Seat->GetComponentLocation(); // Grab its location 
				
				Seat->bTaken = true; // Mark the seat as Taken
				
				uint8 BlackboardKeyID_SeatBool = OwnerComp->GetBlackboardComponent()->GetKeyID("bHasSeat"); // Get the int key for the bHasSeat blackboard value
				
				OwnerComp->GetBlackboardComponent()->SetValueAsBool(BlackboardKeyID_SeatBool, true); // Since we have a seat, update the blackboard
				NavSys->SimpleMoveToLocation(MyController, Destination); // Tell the Bot to go to the seat location
				return EBTNodeResult::Succeeded;
				}
			}

return EBTNodeResult::Failed;
}


//TTRoom GetSeat


// getter functions
UTTSeatComponent* ATTRoom::GetRoomSeats()
{
	int32 b = 0;

	for (b; b < Seats.Num(); b++)
	{
		UTTSeatComponent* Seat = Seats**;
		
		if (Seats**->bTaken == false) // if there is a seat that isnt taken on this room
		{
		  return Seats**; // Then return the seat and stop looping trough the array
		  break;
		}
		
	
	}
	return nullptr; // No seat is available 
}

//TTBTTask_MoveToTheTavern


EBTNodeResult::Type UTTBTTask_MoveToTheTavern::ExecuteTask(class UBehaviorTreeComponent* OwnerComp, uint8* NodeMemory)
{
	UBehaviorTreeComponent* MyComp = OwnerComp;

		for (TActorIterator<ATTRoom> ActorItr(GetWorld()); ActorItr; ++ActorItr) // loop trough all the rooms in the world
		{
			if (ActorItr) // if we find one
			{
				FVector Destination = ActorItr->GetActorLocation(); // get the tavern location
				ATTRoom* Room = Cast<ATTRoom>(*ActorItr);
				if (ActorItr->bIsSpawnRoom) // If its the spawn room then mark it in the blackboard
				{
                                  OwnerComp->GetBlackboardComponent()->SetValueAsObject("CurrentRoom", Room);
				 OwnerComp->GetBlackboardComponent()->SetValueAsVector("MoveToLocation", Destination); // and save its location for later use 
				 return EBTNodeResult::Succeeded;
				 break;
			        }
			}	
               }

return EBTNodeResult::Failed;
}

As you can see in the above picture, Nearly all the bots took a seat but one of them is just standing in the initial spawn room…

So From looking at the behavior tree as soon a bot is spawned it:Goes trough the initial sequence and aborts itself after the Current Room has been set ( But the bot moves to the tavern as usual ), Then the tree runs trough the Take a seat and order a drink path (Bot moves into the race type room, but there is a weird chance once Get Seat is called ( Or Before ) That they just stand in the room doing absolutly nothing even though checking the behavior tree instance shows up that they do have a valid location for a seat and bHasSeat as true . As well there is a random chance that when i hit play AI Works perfectly and they each take a seat and show no issues…

If needed i can also provide a video showing the AI Behavior… Any help is always appreciated !

There are a lot of variables here. Debugging will probably require you figure out a test that get’s it down to each element individually.

It could be pathing issues. Try visually debugging the paths and see if it shows a path to the seat or not for the non responsive bot.

Also, are the resource’s shared between all the bots. Basically, is each bot trying to access the same array at the same time? That could cause problems.

Alright ill try debugging the paths and see how it goes, And in theory yes each bot calls the GetRoomSeats function on the current room , So yes they do try to access the same array at nearly the same time… Could you lead some light to why this could cause problems?

Thanks

Shouldn’t be a problem if it’s read only. If they are writing something, that would cause race conditions/AKA inconsistent behavior.

The closest the bots do to writting is , if the function (getroomseat) returns a valid seat, mark said seat as taken (bTaken is set to true) but thats about it… I checked the paths today and the results were…mixed…

Bots that dident got stuck in the spawn room Did went trough the secondary subtree, called each function properly but never moved towards the seat ( The paths are only drawn when the seat location is acquired and its valid )

I did another test and if i completly remove the 1st subtree ( Move to the tavern ) , And only leave the Get Seat sequence bots spawn properly and move all their way towards a seat and stay there like they should, i tested various times and it worked perfectly… still not a solution since i need them to move towards the tavern first tho…

Nevermind, after reading lots of documentation on behavior trees i figured my layout wasnt the optimal so i did a much better layout of the tree as well tweaked some tasks that werent returning the appropiate state, Still thanks for the help!