Flipper The System

Game Project

Description

This is a local multiplayer game in cooperation with the Catholic University of Leuven (KU Leuven), and to be presented to several other universities worldwide, aimed to raise awareness and educate students about the environment, climate change, and more specifically ocean pollution. 

You and your three companions are sent to stop the pollution that is ruining the surrounding oceans of the beloved protagonist of the game: “Flipper the Dolphin”. The players will move together as a group along a predetermined path encountering conflicts along the way they will need to solve together through communication in the real world. They each have a set amount of resources that contribute to solving a conflict, but in order to do so, they have to work together.

The players come to face the choice of altruism versus selfishness. Do I benefit the group for the greater good and give them my resources, or do I keep them to myself? Each player has an individual goal to win by being the one with the most unique resources at the end of the game. Does that truly make you a winner though?

My Contributions

The Team

Artist – David Våson
Artist – Mathias Bultynck
Artist – Killian Vermeer
Programmer – Jarne Peire
Programmer – Steve Verhoeven
Programmer – Kobe De Backer

Code Snippets

Camera Cinematic Along Spline
//Early out
if (CinematicTime > TimeToCinematic)
{
	bCanTrack = false;
}

if (!bCanTrack)
{
	return;
}

// Add time to use as alpha value later
CinematicTime += DeltaTime;

// We need to determine the position along the spline to move our camera to
const float splineLength = pSplinePath->GetSplineLength();
const float distanceAlongSpline = (CinematicTime / TimeToCinematic) * splineLength;
const FVector locationAlongSpline = pSplinePath->GetLocationAtDistanceAlongSpline(distanceAlongSpline, ESplineCoordinateSpace::World);

// Determine direction from spline point to target point
const FVector targetWorldPos = pTargetPoint->GetRootComponent()->GetComponentLocation();
const FRotator desiredRelativeRot = UKismetMathLibrary::FindLookAtRotation(locationAlongSpline, targetWorldPos);

// Move camera
const FVector delta = locationAlongSpline - pCinematicCamera->GetComponentLocation();
pCinematicCamera->MoveComponent(delta, desiredRelativeRot, false);
CSV Reading PlayerInfo
bool ACSVReader::ReadPlayerCSVFile(const FString& filename, TArray<FPlayerInfo>& outPlayerInfos)
{
	//Get file
	FString input{};
	if (!GetFStringFromFile(filename, input))
	{
		return false;
	}

	//Get all data rows
	FJsonSerializableArray dataRows = GetRowsFromFStringFile(input);

	for (int i = 0; i < dataRows.Num(); ++i)
	{
		//Skip first row (is to indicate titles of values)
		if (i == 0)
		{
			continue;
		}

		//Get all values from row into an array
		FJsonSerializableArray outValues{};
		FString delim = ",";
		dataRows[i].ParseIntoArray(outValues, delim.GetCharArray().GetData());

		//Parse info to player info
		FPlayerInfo playerInfo{};

		//The CSV is formatted as following:
		// Idx 0 = ID
		playerInfo.Role = (ERoleType)FCString::Atoi(outValues[0].GetCharArray().GetData());

		// Idx 1 = Name
		playerInfo.CharacterName = outValues[1];

		// Idx 2-5 = Resource Values
		if (!outValues[2].IsNumeric())
			return false;
		playerInfo.StartResources.SocialCapital = FCString::Atoi(outValues[2].GetCharArray().GetData());

		if (!outValues[3].IsNumeric())
			return false;
		playerInfo.StartResources.Food = FCString::Atoi(outValues[3].GetCharArray().GetData());

		if (!outValues[4].IsNumeric())
			return false;
		playerInfo.StartResources.Power = FCString::Atoi(outValues[4].GetCharArray().GetData());

		if (!outValues[5].TrimEnd().IsNumeric())
			return false;
		playerInfo.StartResources.Money = FCString::Atoi(outValues[5].GetCharArray().GetData());

		//Add conflict to array
		outPlayerInfos.Add(playerInfo);

	}

	//Return successfull reading
	return true;
}
CSV Helper Functions
bool ACSVReader::GetFStringFromFile(const FString& filename, FString& input)
{
	//Create directory
	FString contentDir = FPaths::ProjectContentDir();
	FString fileDir = contentDir + "GameData/" + filename;

	//Read file
	if (!FPaths::FileExists(fileDir))
	{
		return false;
	}
	FFileHelper::LoadFileToString(input, fileDir.GetCharArray().GetData());
	return true;
}

FJsonSerializableArray ACSVReader::GetRowsFromFStringFile(const FString& stringFile)
{
	//Parse file
	FJsonSerializableArray rows{};
	FString returnChar = "\n";
	stringFile.ParseIntoArray(rows, returnChar.GetCharArray().GetData());

	return rows;
}

Trailer

Gameshots

Conflict Solving
Flipper (with dialog)
Visuals of Island