A downloadable game

I built this in Unreal Engine 5.1 over a 16 week bootcamp, representing a sort of minimum viable product of a game. I was playing a lot of Remnant at the time I attempting to visualise this project, so it ended up being a big inspiration here.

Sir Dingus & Friends is a co-op network multiplayer game where players each control a knight and attempt to clear a dungeon of evil skeletons. As long as you're logged into Steam the multiplayer should allow you to connect to other players. 

 Feel free to download the game here: Google Drive Link

Or peruse the Github repo here: Github Link

 

CONTROLS:

WASD: Movement

Space: Roll

Mouse: Look around

Left Click: Attack

Escape: Quit Game


Replication

This was my first attempt at a multiplayer project, so one of the first issues encountered was that of replication.

I used UFUNCTION specifiers to force each animation had to be played on the server and then multicast out to all clients, rather than just on client that requested it.

This stopped animations only being visible for the players or entities that triggered them.



Another example where replication proved necessary was with health values. Since this was a variable rather than a function, I had to use UPROPERTY specifiers to mark it for replication instead.


I then had to mark the variable out for replication in the inherited function Get Lifetime Replicated Props.


The next major pain with replication was a group of both blueprint and C++ code that was getting called during animations via anim notifies. 

It turned out that thanks to the replication of animations much earlier it was now the case that all of this code was being replicated too, which meant sometimes damage values were applied twice and numerous errors were happening when a client attempted to access a controller that it didn’t have access to. 

The solution was as simple as checking the current net role in a few key areas and aborting if it wasn’t appropriate.


Melee Component

After finding I had too much functionality in the character class I split some of it off into different components. The Melee component in particular is responsible for ensuring that it’s owner object can attack, playing animations and performing hit detection so that it can deal damage to an opponent.

I was able to set up a notify state in the attack's animation montage to determine the exact window of any attack animation that should generate hit events, using this to apply damage to enemy characters.


This notify state sets off a timer in C++ and stops it when the notify state is ended, during which time the timer is running line traces for hit detection.


These line traces themselves use a pair of extra sockets on an attached weapon to draw lines (representing the blade) as the weapon travels ideally following an attack animation.


The weapon needs to be a skeletal mesh to attach the sockets and contain the correct number of sockets, so it’s application can be a little narrow. I may tweak this approach slightly if I attempt to add a selection of weapons later, but it works nicely for my purposes at the moment.

Action States

One thing I was sorely missing in this project for a while was the ability to restrict what a character could do based on whatever they were already engaged in doing. The simplest example of this was when a player could spam the dodge button or the attack button and constantly start and restart an animation, or where a character could begin an attack animation and then glide around on their feet during it.

The solution I found was to use a simple state system, so I created an enumerator called Action State to track what actions a character is currently engaged in.

Declaration of Action State Enumerator
Declaration of Action State Enumerator
These states are then used to form rules like whether the character can move or not, which are stored as functions in an interface class and later referenced when relevant in the character’s controller.
Declaration of Action State Interface ClassDeclaration of Action State Interface Class
Example of Can Move rule being used in Player Controller ClassExample of Rule Use

By keeping some functions virtual, notably with UpdateActionState, I change key details about the function’s implementation where it’s used. For example whenever the player controller needs to change its action state it can simply call the function as is, whereas the AI controller also needs to notify its blackboard component of any new rule values so that its behaviour tree can know what’s going on.

AI Controller Class Overriding Interface Function
AI Controller Overriding Interface Class  
Example of Can Move rule being used in AI Behaviour Tree
Behaviour Tree Using Can Move

Comments

Log in with itch.io to leave a comment.

love the name

Awesome Louis. Love the concept!