Project Necromancy

Play it on Itch.io!

Project Information

Project Necromancy is a project I started together with Dirk de Kok as a graduation project. It was my intent of creating a game from scratch with a small team and learning C#.

Because of the coronavirus, finding an internship was hard for a lot of people which gave me an opportunity to find teammates for this project. Over the course of 5 months, we managed to create a proof of concept, which has been published on Itch.io.

I created the concept, based on the Necromancer class fantasy from games such as Warcraft 3, Diablo 2 and Path of Exile. I was also responsible for most of the design and managing of the team.

MY ROLE WITHIN THE PROJECT: Project Lead, Game Designer

PLATFORM: PC (Released on Itch.io)

DEVELOPMENT TIME: 5 months, proof of concept

TEAM SIZE: 6

 ENGINE: Unity

My Work In The Project

Controls, Camera & Character

The initial concept that I came up with shared a lot of similarities to Warcraft 3’s gameplay. To prove the concept, I made a quick prototype in a day inside of the Warcraft 3 engine. With this prototype, I noticed a couple of issues:

  1. RTS controls feel good for the army, but not so great for the player character. As my army of Minions grew, I quickly lost control over my Necromancer or would just leave it behind while microing my Minions.
  2. Waiting for the Raise spell cooldown and mana cost was boring and took out the pacing of the game.
  3. Raising different units was fun, especially if they stood out from the rest.
  4. Microing different types of Minions with different skills was fun but quickly became too much to control effectively even for an experienced RTS player.
  5. I stopped using the necromancer character when my army grew too big.

I took this data and made some changes to the controls:

  1. Players could control the Necromancer with WASD. The minion control would be on other keys.
  2. We removed mana and cooldowns for the Raise spell but added a minion cap.
  3. We would have diverse enemies with different roles.
  4. Minions could not be controlled individually, but rather as the entire group.
  5. The Raise spell would be an AoE effect around the Necromancer. That way, players would always have to move in close to fallen enemies to raise new minions, and having the Necromancer’s controls on WASD would keep players responsive. Their attack was also melee range, so if players wanted to be as efficient as possible, they would join combat with their Necromancer too.
WK3 - Camera Director Flowchart (Roy) (2)

Early flowchart of the Camera Director.

Prototypes, First Problems and Solutions

After this prototype in Warcraft 3, we quickly moved on to making a prototype in Unity. We wanted to see if we could pull the AI and army controls off without our code and the design becoming too complicated. We finished the prototype and noticed some more issues:

  1. The camera, solely focused on the necromancer, often did not give enough information, as things were happening off-screen quite often.
  2. Minions would often run into their own deaths because of their ‘free will’ and desire to attack everything they considered enemies.
  3. The player’s army would snowball very quickly, making the game very easy.

We brainstormed a bit on these issues and we came up with the following solutions:

  1. The camera should move with the mouse and the army in mind. This would be done through ‘focus’ points. 
    1. The main focal point being the player character, which always had to be on-screen.
    2. The second focal point would be the players’ cursor, so players can look in a direction to see what is ahead of them.
    3. The third (and optional) focal point would be the current body of the army, which would take all of the minions’ current positions and generate a centre focal point.
  2. Minions should have their own ‘free will’ attacking whatever comes close. However, when testing with some environmental hazards, we quickly established that we needed a direct override command. We tried a couple of different solutions but eventually settled on a Recall command. The Recall command would: 
    1. Recall all minions back to the player in a doughnut shape, serving as a wall of bodies to defend the player. Minions would not engage in combat but rather move with the player.
    2. The recall command would also be called automatically for a minion if they exceeded the maximum range between the Necromancer and that minion.
  3. A much more difficult problem to solve was snowballing minions and controlling a huge army felt fun for the player but was almost impossible to balance and thus, removing any challenge from the game. We settled on a couple of designs:
    1. A maximum minion cap, which could be increased over time. This would allow us to control the challenge level a bit more but still allowed for big armies over time, which was something that we definitely wanted to keep.
    2. Enemy designs that would not yield corpses. These would impact the player’s growth negatively since they do not yield a ‘corpse reward’ but still had to be traversed. We added a couple of mechanical enemies to the game (which can be seen to the right):
      1. An arrow guard tower, that would shoot arrows which would instantly kill a minion and deal a lot of damage to the player.
      2. A Molotov-tower, which would throw out Molotov cocktails that leave behind a patch of burning ground, dealing damage to all of the players’ units over time that would stand on the flames.
      3. A ballista, which would fire a big spike into the players’ army, removing a line of minions instantly. The maximum number of minions penetrated was set to three, so these ballistae had to be used sparingly by the level designer.
      4. We had planned for additional mechanical units, such as robots but those did not make the cut.

In this early version of the tech prototype, you can see the camera issue very clearly when moving down.

The Ballista enemy is effective at destroying lines of your minions.

The Archer Tower kills your minions from afar without yielding corpses. Destroy them quickly!

Enemies & Minions

In my initial designs, we would have different enemies with different abilities (such as ranged enemies) and those would yield different minions for the player to utilize. However, because of the limited time we had, implementing these became impossible, next to the tower enemies we already had decided on. I considered making enemies and minions have levels (or stats), but that would be very hard and complex to explain to the player without investing considerable time in the UI and UX.

 

We still wanted some variety, so we had to create some that did not cost a lot of development time. As a test, I copied the standard enemy, increased its health and damage and size. I quickly playtested this, and it turned out that players absolutely loved reviving these bigger units. The responses were so positive, that in the end, we added two even larger enemies to the game and even made them a shop purchasable later on in development.

This mighty bridge guardian will prove an excellent addition to your army!

AI Design

After the first prototype, we knew our AI would be relatively complex. We wanted to have an AI system that would drive both the players’ minions and the enemy characters. We created a finite state machine which allowed us to debug more easily. We divided the AI up into:

  • IDLE: The neutral state where characters would stand around. Enemies and Minions will attack anything that would enter its AggroRange.
  • CHASING: When an enemy of the character would enter the AggroRange, characters would engage the enemy character and try to get into AttackRange. Every few seconds during CHASING, the character would check if the target was still close enough. If not, it would try to return to its original location.
  • ATTACKING: The character would switch to this state if it was close enough to the target to initiate an attack. In this state, they would attack the target, deal damage (if still close enough), wait for the cooldown of its attack if it was still close enough to attack a target. Otherwise, the character would try to find a new character and engage ATTACKING again. If no targets were within the AttackRange, they would try to find a target to chase.
  • However, this would feel very rigid and non-responsive when characters got attacked. To solve this, we added a RETURNFIRE state, which would overwrite their current state if they were in CHASING or IDLE. RETURNFIRE would immediately put the character into ATTACKING or CHASING with the attacker as the target.
  • Lastly, for the Minions there is also RECALL state. This state would force the minion to make its way back back to the player and take its place around him. This state would also be called if minions stray too far from the player automatically. While in this state, Minions do not attack.

Early diagram of the state machine we made for most of the AI. Click the diagram for a full view in diagrams.net

Game Feel

For me, it was important that player fantasy controlling a horde of minions was kept intact. Hence why I wanted to make sure they attacked things on their own. One of these points was destruction.

Early on in the project, I added Cell Fracture to some models I made in Blender to make real-time destructables that would simulate physics as soon as destroyed.

I applied these to the destructables we had and along with the minions destroying an entire town, felt great for players.

Particles & UX ("Juice")

This was already a lot of fun to play around with, but there were still some things missing. I added in:

  • Hit confirmation through changing the colour of the enemy (or player) for a frame when hit.
  • A 1-frame delay when the player kills an enemy or when the player gets hit.
  • A medium screenshake on big explosions or when getting hit.
  • A tiny screenshake when an attack connects with an enemy.
  • Improved ‘OnHit’ particles when an enemy, minion or player character is hit or killed.

I noticed during playtesting that players often left potential minions behind because they did not notice them. One of the last additions I added was creating a ‘revive’ marker over fallen enemies that could be revived.

The revive marker I added in later, to give some clarity over which corpses can be raised.

Early test with character models from the asset store. Here you can see the first destructible barrier in action.

I modelled a simple house in Blender and went through the same procedure. The procedure was spectacular and a bit over the top, but everyone loved it. Later on, we replaced the simple house model with a better one.

Here you can see the final destructible barrier, as they are currently in the game.