Optimizing and Zone 1 Boss Design


Optimizations

Although I have not had any issues with optimization as of yet, I want to ensure that the game doesn't become clunky as more spells, enemies, and features/bugs are added.

The first line of work was revamping the spell system based on an idea I got while designing the enemy spell system. Here I got rid of the need for the main loop to call on the cast method of the spell object and instead all those actions are performed when the spell object is initialized (not quite an optimization but will help a ton in the future when the spells themselves perform their own checks/calls instead of relying on the main loop to do it). I then rolled the spell collision detection system into the new spell objects. This means that each spell only calls on a collision system if the spell needs it, making room for spells that don't require or use collisions (think self-targeting spells, self-healing spells, transformation spells etc). This reduced the main loop by 81 lines of code. Next I focused on moving an additional 30 lines of code from the main update loop to reside only on spells that it matters for, this includes distance checks, homing calculations and everything else that occurs each tick outside of collision detection. I used everything I learned here to finish the spell revamp by doing the same with the enemy spells.

The next agenda was revamping entities. I basically combed through and did what I had done for the spell object code in the main loop but now just for enemies. Part of this was removing contact damage being on by default and coding the individual enemy to check for collision and apply the damage. But this seemed a little sloppy still for me as now I would have to code the player health check system onto every enemy, so to resolve that I instead coding an entity damage received method. This method is now called on by the object receiving damage with the value of damage it is receiving. From here it can run just the base method which simply subtracts the health and checks if the total is still over 0, but more interestingly we can perform specialized damage calculation or add effects on damage here. Say that the player gains some damage resistance, this can now be easily calculated before damage is applied (same goes for enemies of course). I can also make enemies run away, hide, grow in size and deal more damage, etc. These changes reduced the main loop by 32 lines.


The main loop is back down to 2,628 lines of code.


Zone 1 Boss Work

Started work on zone 1 boss and the entity object reworks helped immensely for this. First I created a enemy subclass called "Boss" in order to create a template that all bosses share, things like: check if boss has already been killed when entering the room and setting basic fight variables (casting, waiting, etc). Then I created the actual zone 1 boss, who I intend to mostly use fire-based magic so I call him Salamander.

Here is Salamander as his Stand-In Asset (Created by Kenney)

I wanted to make him a little unpredictable. So I pulled inspiration from when I was designing the enemy drop system and created two dictionaries containing key:value pairs of a percentage selection rate and the action (move, idle, attack, etc). If attack gets selected, then Salamander will then randomly select an attack from his spell dictionary. In order to keep it a little more interesting, I actually coded two attack dictionaries for Salamander and the distance between Salamander and the player determines which one he will use. The far dictionary for ranged attacks and the near one for shorter range attacks and a dash. This ended up resulting in spell rapid fire because Salamander would  perform an action check every tick (60 per second) which resulted in a lot of attacks being performed, so I also added a cast and a wait timer. During the cast state, Salamander does not make any action checks and during the wait timer he won't perform attack checks. This prevents him from chaining together spells in a way that is impossible for players to navigate. 

Part of his creation involved creating the dash spell. This spell was a pain because the goal of it was to affect the behavior of Salamander while giving him temporary contact damage, the idea being that he lights himself ablaze or becomes a fireball and bolts across the screen. In order to make it work correctly, I have him blast out a homing object that seeks a wall. Once it makes contact it moves closer towards the center and Salamander dashes to it while checking for collisions to issue contact damage. I had to make the homing object move inwards because it otherwise stayed in the wall and Salamander became helplessly stuck in the wall.


Closing Notes

I have started working on zone 1 but don't have a ton of information to report on it as of yet.

If you want to stay up to date with the game you can follow the game to get updates, join our Discord server or subscribe to the devlog RSS feed:

RSS Join our Discord!

Leave a comment

Log in with itch.io to leave a comment.