Vertebrave

Vertebrave is our 5th game project at The Game Assembly, made by Tombstone Interactive. It is a fun and quirky top-down adventure game inspired by The Legend of Zelda: A Link to the Past. You play as misunderstood skeleton Skelly who only wants to become friends and play with the humans in the village. In order to prove that Skelly has a good heart, you have to help Skelly defeat the fellow skeletons and the army headed to the village.

  • Top-down adventure game
  • 8 weeks half time
  • The Game Assembly's in-house game engine TGA2D
  • Written in C++

For this project, I wanted to try something new (yet again), and I realised that I was yet to work with a large game-play area. I have previously worked on the systems underlying the game-play loop, such as scene handling and menus, and only slightly touched upon game-play via pickups and player systems. So, for this game, I was determined to work on a more significant game-play area and I ended up with the exciting task of working on the enemies and the boss.

Enemy Components

The programmers decided to use an old project's game object and component system. This would allow us to manage all game objects very generally, with the ability to store them in the same vectors and having the benefit of following a standard of how to create components. This way we would easily understand each others' work. I started the project off by making a simple melee enemy with a sword while trying to keep in mind that I want to expand this system, hence keeping the components very generalized would be to my benefit.

I created an EnemyComponent that would hold the most general data and behaviour, such as collision data, health and orientation in the world. I then wrote an EnemyPatrolComponent that would add the ability to patrol an area to the basic enemy . I thought this might be a good idea because I knew that I wanted two other enemies (one ranged with bow and arrow and one melee enemy with a ball and chain) that also needed to patrol. The patrol paths were either a default squares or it was derived from a list of points that the level designers placed in the world. This made the enemies' patrolling more versatile and less repetative.

I then created an EnemyMeleeComponent that would be useful for both the melee enemy with the sword and the one with the ball and chain. I continued this approach for the ranged enemy with an EnemyShootingComponent which was accompanied by ArrowComponent for the arrows. This would not only cover all the three main enemies, but also the minibosses, which were stronger versions of the original enemy.

Boss with Phases

The boss fight is made up of three phases and involved three different attacks. The first phase would be an introduction for the player to realise that you need to parry the boss's bolts and avoid lightning strikes. The other phases would cause the boss to spawn more and harder enemies onto the battleground. All of this would require for a larger system than the ones mentioned before.

I decided to create a main component that would take care of the phases and timing. This class was to be called the FinalBossComponent and this would accompany the EnemyComponent like the rest of the enemies. I then added components for the specific attacks: shoot bolts, lightning strike and spawn enemies. These were then activated depending on the state of the FinalBossComponent.

The bossfight required a lot of tweaking for it to work like expected. I had been working and staring at this boss fight for a few weeks and knew I was not the right person to tweak it. The programmers were all very persistent on allowing the rest of the group to adjust variables of anything in the game, so naturally I exposed the timing, spawn rate, damage and other variables concerning the boss fight to a json-file where the rest of the group could try things out. The group used the nlohmann library in this project.

Problems I Encountered

I feel like I ran into quite a few problems during this project and some I fixed; however, I would say that quite a few made their way into the game. I would say that I went into this project quite naive about the scale of things that I would take on. It turned out to be a challenge at times and perhaps a lesson would be that I should not be afraid to ask for help.

One main problem that you will see in the game is the "shaking" of the enemies when colliding with each other or with environment. We did not use any pathfinding in this game, and I had yet to learn about state machines and behaviour trees, so I kind of winged it. The shaking was a result of me trying to desperately push the enemy away from an object once it had collided with it. When pushing an enemy away, I added a velocity in the opposite direction of the current one, making the animation change. By the animation changing so drastically, the solution turned into a very visual bug. If I were to solve this now, I would try to use my newly found knowledge within grouping behaviour and pathfinding to try to avoid the collisions all together. I would also try to avoid making games where the animations only work for four directions, making shaking a massive eye sore.