Soul Knight
Project Status On hold
Project Type University / group project
Project Duration ~5 months
Software Used Unreal Engine 4
Languages Used C++, Blueprints, C#
Primary Role(s) Tech lead / Lead programmer

About Soul Knight

Soul Knight is a project that started as part of my 2nd year at NHTV University. I took the role of Lead Programmer, implementing most of the game's functionality, some of which I feature here. In total there were around 20 - 25 people on the project. This project helped me learn a lot about Unreal Engine 4, and C++ in general.

For the teaser trailer, I keyframed each shot with Unreal's Sequencer, added proper lighting / props / animations / post-processing, shot the gameplay pieces frame-by-frame, and edited the whole thing together!

Camera System

I designed and developed a dynamic 'roaming' camera. It uses an 'imaginary circle' as reference point, which the player pushes around:

In the video there are two circles, a bigger and smaller one. The bigger one (and all its properties) is used while the player is running, the smaller one is used while the player is walking. The camera system blends between them, based on the speed of the player. This allows the camera to be more precise and close-by while walking, and gives more of an overview while running.

The circles can also grow / shrink and change properties dynamically, based on the scene for example, allowing shots which still keep the player in focus correctly while also adhering to the context of the scene.

CODE SNIPPET - Dynamic Camera

The following code is used to update the camera, calculating if the player has moved outside of the circle, and if so pushing the circle in that direction.

void FCameraRoamCircle::UpdateInnerPosition(FVector aNewPos)
	/* Relative vector from player to circle */
	FVector tInnerPosToCircle = aNewPos - mPosition;
	tInnerPosToCircle.Z = 0.0f;

	float tInnerPosToCircleLength = tInnerPosToCircle.Size();

	/* Normalized direction from player to circle */
	FVector tInnerPosToCircleDirection = tInnerPosToCircle;

	if (tInnerPosToCircleLength > mProps->Radius + THRESH_POINTS_ARE_NEAR)
		/* Player has moved outside of the circle, calculate the difference and add it to the position */
		float tMoveDeltaLength = tInnerPosToCircleLength - mProps->Radius;
		FVector tMoveDelta = tInnerPosToCircleDirection * tMoveDeltaLength;
		/* Calculate the delta rotation */
		float tPushAngle = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(tInnerPosToCircleDirection, mRotation.GetRightVector())));
		tPushAngle = -(tPushAngle - 90);

		/* Add position and rotation */
		mPosition += tMoveDelta;
		mRotation *= FQuat::MakeFromEuler(FVector::UpVector * (tPushAngle / mProps->RotationTightness));

	mInnerPosition = aNewPos;

The camera has many more features, such as the ability to add a custom offset while the player is inside of the circle, based on the axes of the circle. This can for example create an effect where the camera tilts, pans and/or zooms when the player walks backwards or forwards. Furthermore there are options for smoothing, tightness of rotation, offsets, and more.

Gameplay Mechanics

I implemented all gameplay features for the main character, as well as other characters and mechanics


The dash is the core mechanic of Soul Knight. It's used as a means of combat and traversal. The auto-aim feature calculates the angle between the player and the object he's dashing in to so that the player can aim quickly while in the air.

Other mechanics

Picking up objects


I worked closely with our FX artist to implement the wings, and fine tune the way the particle is controlled.

Boulder riding

Boulders are creatures which can be used as means of transportation. In the pre-alpha, the way the player "snaps" to the boulder is quite visible, this is something that I wanted to polish later.

Volcano Turtle

This 'explosive' turtle can be used to elevate yourself. I implemented his attack, as well as the ability to fly upwards when jumping inside the steam, and that he turns his head towards the player when he's close by. I didn't do the AI (turning around, walking around).