Search this site
Embedded Files
Jacob van Berlo
  • Home
  • About Me
  • GOAP
  • Particle Systems
    • CPU-Bound
    • GPU-Bound
  • Team Projects
    • Walter Volt
    • Spiteful Hangover
    • D4RK
    • Checkmate
  • Radix Sort
  • Contacts
Jacob van Berlo
  • Home
  • About Me
  • GOAP
  • Particle Systems
    • CPU-Bound
    • GPU-Bound
  • Team Projects
    • Walter Volt
    • Spiteful Hangover
    • D4RK
    • Checkmate
  • Radix Sort
  • Contacts
  • More
    • Home
    • About Me
    • GOAP
    • Particle Systems
      • CPU-Bound
      • GPU-Bound
    • Team Projects
      • Walter Volt
      • Spiteful Hangover
      • D4RK
      • Checkmate
    • Radix Sort
    • Contacts

Spiteful Hangover

Enemies
Collision

https://ol-milk.itch.io/spiteful-hangover

Contributions:

  • Collision

  • Enemy AI

  • Particle System

Time: 20 Weeks

Team Size: 6 Programmers, 2 Procedural Artists, 4 Artists, 3 Level Designers & 4 Audio Designers

Engine: RatTrap (own engine)

About The Game Project

Spiteful Hangover was the fifth game we made in TGA (The Game Assembly).

Spiteful Hangover is a top down Action RPG where you play as a drunk viking whos village has just gotten overrun by Dragur.
For the development of the game we had more set requirements as it would fit in with the schools game series Spite. Among the requirements was to have three different enemies, elite version of one or more enemies. A boss with three phases and a theme, which we got to build on or modify a bit on.

During the development of the game I worked primarily with Collision Detection, AI for the enemies and a CPU-bound Particle System. I talk about the Particle System on the Particle System page.

Enemies

Melee Dragur

The most basic of enemies which just runs towards the player on the navmesh to smack them

Werewolf

While they also rushed the player down like the melee dragur, they also had the ability to buff enemies in the area, including themsevels

Ranged Dragur

Our ranged enemy which moved towards the player to shoot him, but if the player got to close it tried making distance by running away.

The AI for the enemies are run by a State Machine, with each action of the enemies being their own class derived from a base class.
I defined the amount of states for the State Machine as well as which slot as State should go into based of an enumeration. Which allowed me to easily use the same State Machine but just with different state for their actions, for example Attack and Ranged Attack both was placed in the Attack slot for their respective enemy type.

Since the specific actions are dervied from the Actions class, they were stored in an Array of unique pointers. So if we wanted to know if an Enemy had been given an action we simply checked if the value in the array was null or not.

Since each enemy had a set behavior controlled by a state machine, we determined what type of enemy it was based of the tags it had on it. Which allowed us to use a single Enemy class where we at creation set what actions it would have. We also generated a random named for the enemies based of their tags to give it more flair.


This allowed us to gather all the creation of the Actions in one spot, as well as not having to define different connections and such, while also allowing multiple people working on the AI at the same time, since the Actions defined their behavior.

This is a closer look on how it was later in the devolpment where the Werewolfs have thier correct buff vfx being used.
We were also working on fixing enemies stacking on each other, which is why one of the Werewolves is running in place.

Down in the corner we can also see one of the Ranged Dragurs moving away since we got a bit to close to it.

We also made a bigger werewolf we named Garm (based of Nordic Mythology) which use the same AI as the normal Werewolf but are bigger and tougher. But doesn't fall into the same category as our other elites, but instead acted more like a Mini Boss.

Collision

Since it's a top down game, where the AI and Player walks on the Navmesh, collision was kept simple. We primarily used it to check if attacks connected, since we used behaviors to handle enemies stacking.

To keep collision simple I implemented sphere colliders since they are very easy, as well as capsule colliders since they are often used for characters in games. Which was also a good learning experience, for handling their collision detection and solving the data for it.

Sphere collision is simply just a distance check that is compared with the radius of the two spheres. Which is very simple and efficient. With the sphere collision check implemented I started working at making the Sphere vs Capsule check. Since you can visualize a capsule as simply a sphere on a limited line, I decided to set up the collision check as Sphere collisions.
Where I first checked if a sphere based of the radius on the start and end positions of the capsule had collision with the sphere or not. If they had good we solved the collision with two simple distance checks, if not we then need to do some math to get the closest point on the line between the start and end.
I also added a check to make sure the position I got was on the actual line, which in hindsight was unnecessary.
With the closest position on the line to the sphere we then did another Sphere collision check.

I then started on the Capsule vs Capsule Collision.
Since we can simulate the collision between two Capsules as Collision between two spheres on the closest points of the capsules between their start and end positions. We got the dot product based of the distances between the two colliders start and end positions. We then used that to help determine the two actual closest points on the two lines. Where I once again used Sphere collision check to determine collision.


While this works fine for our game and usage, it's limited to sphere and capsule, we also need to overload the collision function for each type of collision so we can get the correct collision check.
Another way to determine collision I could have used is the Gilbert-Johnson-Keerthi Distance Algorithm (GJK) to determine if we have collision or not.
Which would also allow use more shapes easier then just Sphere & Capsule.

Sphere vs Capsule Collision

Capsule vs Capsule Collision

Since we primarily used collision to determine if an attack connected or not, we don't need to get to much data from the collision. Primarily the dot product based of the first colliders forward and the hit entities position, as well as the hit entities ID. However since I wasn't fully sure what we wanted for collision data I made a struct where we could easily add more data to be sent if we need to add more.

While all collision checks go through the same final function, I added the option to filter collision based on tags.
This made it so we could request collision with for example all enemies that are not Werewolfs. 
This allowed use to avoid checks between enemy attacks and enemies, or having it only be against the player.

Google Sites
Report abuse
Page details
Page updated
Google Sites
Report abuse