Bar Fight

A game about managing a bar created during the graduation project at Hanze University.

I was part of the 7-person team working on this project as a Product Owner as well as AI Programmer focusing on the character behaviour.

Game Genre

Co-op, Simulator, Roguelite

Platform

PC

Engine

Unreal Engine 5

About the Development

I was responsible for the AI implementation within the game using State Trees as the underlying system. I also acted as a Product Owner, managing the team, scope and goals to keep them within the graduation timeframe.

Bar Fight gameplay

Customer State Trees

Through the graduation project the 2 customer State Trees were created. One tree controls the locomotion and seat selection while another controls the ordering and consuming flow.

Both are powered by modular tasks designed to be re-used by other states.

Customer Behaviour Gif

Environment Query Test

Since the EQS system did not contain a test I needed, I created my own using C++. The test that was required was a test that would check how many actors of the selected class are around the selected object.

This was used to determine which seats within the level had least other customers around them and route new customers towards empty spaces of the bar (thus filling the bar more naturally).

Customer spread based on EQS
                        
void UEnvQueryTest_CountActorsInRadius::RunTest(FEnvQueryInstance& QueryInstance) const
{
	UObject* QueryOwner = QueryInstance.Owner.Get();
	if (QueryOwner == nullptr)
	{
		return;
	}

	UWorld* World = QueryInstance.World;
	if (!World)
	{
		return;
	}

	for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
	{
		FVector ItemLocation = GetItemLocation(QueryInstance, It.GetIndex());
		TArray<FOverlapResult> Overlaps;
		FCollisionShape Sphere = FCollisionShape::MakeSphere(Radius);

		QueryInstance.World->OverlapMultiByObjectType(
			Overlaps,
			ItemLocation,
			FQuat::Identity,
			FCollisionObjectQueryParams(ECC_Pawn),
			Sphere
		);

		int32 Count = 0;

		for (const FOverlapResult& Res : Overlaps)
		{
			AActor* Actor = Res.GetActor();
			if (Actor && Actor->IsA(ActorClassToCount))
			{
				Count++;
			}
		}

		It.SetScore(TestPurpose, FilterType, Count, 0, Count);

    }
}

Extras

Extra 1

Customers leaving due to punching (pacifying) them.

Game Screenshots

Showcase Image 1 Showcase Image 2 Showcase Image 3 Showcase Image 4