Einar

NameEinar
Short DescriptionEinar is a single-player 3rd person hack and slash based on Norse mythology.
CategorySchool Project - Year 3
Total Development TimeSep 2016 - Jul 2017 (~10 months)
Joined Development TimeJan 2017 - Jul 2017 (~6 months)
EngineUnreal
RoleLead AI Programmer
Team Size32

About

Einar is a 3rd person hack & slash game based on Norse mythology where you play as Einar. His village has been overrun by draugrs, the enemies in our game, and Einar is tasked with killing them all. He can do so with the powers he has gotten from three Norse gods: Freya, Thor, and Thyr.

AI Programming

In Einar, I worked on creating and implementing an AI system called the Overseer. The Overseer is an AI system inspired by Assassin’s Creed and Shadow of Mordor where enemies circle you and don’t all attack you at once and contains three main systems: spawning, attack management, and circling.

Spawners

Initially, all enemies in the level were placed in there manually. This resulted in the enemies being active at all times which is not performance friendly and didn’t allow for enemies attacking in waves or ambushes which were two things we wanted to have. To give the designers the control they wanted I created the spawners.

The spawners are blueprints which have a C++ class as a parent. The C++ class contains an Instanced TArray of spawn types as well as several methods and events that are called in blueprint.

AI Spawner Header

 

The TArray allows designers to control which USpawnTypeCPP subclasses to use as well as tweak the variables inside it from the Details window. The USpawnTypeCPP header is set up as follows. It contains an override for GetWorld which it gets from its outer/owner and three virtual methods which can be called from the spawner blueprint.

Spawn Type Header

 

Spawn Type Distance Class

 

In the blueprint code, spawners get registered in an array on instantiation and are then updated through the Overseer.

The spawner blueprint contains several other variables which are used to configure the spawner and the spawned enemies. The spawner controls if the enemy has a path to follow once it spawns, in which area it spawns, how long it takes to spawn, which enemies spawn and many other things.

There are a lot of variables to tweak for the spawner so it’s important to make sure the level designers know what each variable is. To ensure this, I wrote a document explaining what each variable does.

The document also describes the other parts of the Overseer system.

Attack Management

Attack Management is the least complex part of the Overseer. It consists of several counters and an array which together keep track of how many enemies are attacking at any time split by type. The attacking enemies are split up in ranged and melee and each enemy can have an individual weight assigned to it which can be used to allow several smaller enemies to attack while only one larger one is allowed.

Attack Management Variables

When an AI is able to attack, a decorator in the AIs behavior tree calls a function in the Overseer called CanAIAttack which then returns true or false based on the count.

At the start, a check is done if the enemy is already attacking which allows enemies which are alone to continuously attack. Then, a switch is made on the enemy type and the counters are checked. If the enemy is allowed to attack, it’s registered and runs the attacking tasks in the behavior tree of the enemy.

One thing that complicates attack management is that in certain cases, the enemy should always attack. When an enemy is shotit should attack you regardless of the amount of enemies that are already there. The same thing should happen when you get really close to an enemy. Additionally, enemies have to stop attacking when they are far away so enemies  that are closer can attack. Maintaining whether an enemy was in an attacking state or not across the overseer, the behavior tree and animation blueprint with several different situations for an enemy to start or stop attacking was very complex.

Circling

When enemies are not allowed to attack, they shouldn’t just stand around waiting for other enemies to go away or die. Instead, they should swarm the player and circle around him. The circling in our game consists of several segments (like in a pizza) and each segment can contain a single enemy. If all segments are filled up, there are more layers which have an increasing distance to the player.

The problem with a circle based system is that you need to calculate the position using sin and cosine which is very heavy to constantly have running for a lot of enemies at once. To keep the performance impact down, the position in the circle based on the location of the player is never calculated. Instead, during startup, the circle offsets are calculated from 0, 0, 0 and then at runtime, the position of the player is added to that. If the enemy has to take a position in a higher layer, the position increased using a multiplier which makes the enemy stand further away. This way, the position is always relative to that of the player and there is no need for sin and cosine at runtime.

Circling Setup

The absolute position the enemy is supposed to go to is calculated as follows from the offsets array. Circle Multiplier is the layer multiplier which is set by a designer. Einar Location is the location of the player.

Circling Calculation

However, the enemy shouldn’t just pick a random segment in the circle and go there. Enemies should be smart and select the closest possible segment. There are also special situationswhere it takes priority for specific slots. For example, after missing an attack, it has to go to a position behind the player. The following blueprint gets the circle positions behind the player and then calls a function to pick the nearest from that.

Circling Behind Player

The Find Shortest Circle Location method then recursively finds the closest position from the enemy to the player in the closest possible layer.

Idling

Because the Overseer only allows a certain amount of enemies to attack at any time, enemies will regularly have nothing to do. Once they are in the combat circle, they have to wait until a spot opens up. It would look unnatural if the enemies would just stand around and wait. To prevent this, we added a branch to the Behavior Tree which only triggers if the enemy is able and allowed to idle.

There is a random chance for the enemy to either play a taunt animation or strafe in the circle. The Taunt task calls the character animation blueprint to play a random animation.

The randomly picked animation is then played from the Animation State Machine.

Once the animation is done, it calls back to the character animation blueprint which then finishes the task in the behavior tree.

Team Management

As the Lead AI Programmer, I also had to manage the AI team besides programming the Overseer system. Our AI team consisted of 3 members, one for each of the three individual character behaviors, and myself. Tasks included managing and prioritizing which tasks or bugs are worked on first, talking with other parts of the development team regarding the AI’s current and wanted features and preventing and taking care of issues.

Events & Coverage

Einar was present at Indigo, a showcase event for independent games taking place in Utrecht, The Netherlands. Our game was shown at the Epic Games stand. Throughout the day, Einar had a significant amount of people watching and playing. Overall, Einar was very popular and Indigo was a great success.

Einar at Indigo

Besides events, Einar had various Let’s Plays as well as several trailers released on Youtube.

Einar Teaser Trailer

Einar Gameplay Trailer

Let's Plays

Coalfire: Einar – So Much Potential!

Staf_52: Students make a game → Einar (First impression-gameplay fr) (French)

 

There are also articles about Einar.

Articles & Reviews

 

Reception

At the Dutch Game Awards 2017, Einar was nominated for two awards: Best Student Art Direction and Best Student Technical Achievement.

Dutch Game Award Nominees

Steam

In the first month of release, Einar was downloaded 150.000 times and played by over 100.000 people. In the 2 months after that, the total doubled to 300.000 downloads and 200.000 players.

On Steam, Einar has a review score of 60%. After analyzing the reviews, there are several aspects which people strongly disliked. The main reason for negative reviews, about two-thirds, is that there is no proper keyboard & mouse support which means you have to play with a controller. This is caused by the fact that we changed our target platform to PC very late in development which was unfortunate.

Furthermore, people are annoyed by the fact that the game is rather short. Most people tend to complete the game in around 15 minutes. There is nothing we could have done about that. The aim of our game was to make a short, but highly polished game. Which we did achieve in many aspects, it is understandable why people dislike that though.

Another key factor for negative reviews is that our game was tagged on Steam as “Co-op”, “Multiplayer” and “Open World” which is all incorrect. Going into a game assuming that and finding out the tags are incorrect is very frustrating.

Finally, many people complain about the lack of a UI, but that was a design choice from our design team to keep the game as focussed on the experience as possible.

Overall, the general idea of the reviews is that the game has a lot of potential and could become a great game if we were to put more time into it.

Download

Screenshots & More Information

  • Fishing Village
    Fishing Village
  • Light Draugrs
    Light Draugrs
  • Einar at some dead Draugrs
    Einar at some dead Draugrs
  • Promotional poster for the Heavy Draugr
    Promotional poster for the Heavy Draugr
  • Promotional poster the the Ranged Draugr
    Promotional poster the the Ranged Draugr

 

For more information about Einar and our team, take a look at our press kit.