Sponsored By

The point of writing is to provide insight on a practical situation in which the best approach to problem solving was to go about the problem in a different way, rather than fixing a broken implementation.

December 4, 2023

3 Min Read

The Approach

I am a developer on a game called Conquering Ciros. Our studio, Crystalline Games LLC, was formed as part of the Game Design program at Indiana University. As a programmer, I joined the team in May of 2023, after the game’s overall design had been thought out and a prototype was put together. The game is a part of the 2D auto-shooter genre recently popularized by Vampire Survivors and is developed in Unity. Most of my work has been on the programming and implementation of attacks that take the form of crystals.

The point of writing is to provide insight on a practical situation in which the best approach to problem solving was to go about the problem in a different way, rather than fixing a broken implementation. Sometimes it seems as though your current thought process should work and finding the bug is what needs to be done. In my experience, the time spent finding a fix to some broken implementation can usually be spent better by finding a new way to implement the mechanic.

The crystal ability I will be using to illustrate this idea is being referred to as the Flail. The idea of the attack is for a large crystal to swing outwards towards the nearest enemy, dealing damage when it reaches its max distance and slams down. It then returns to the player, grabbing and damaging enemies along the way. On return to its parent crystal, all enemies that had been grabbed on return receive a final dose of damage as well as status effects.

This is the information I had when approaching the implementation of this mechanic. Implementing an ability in our game had a somewhat straightforward approach: Make a framework for the ability with the appropriate variables, make a class with a particular naming convention, implement the ability interface, code the gameplay. I decided to have the Flail act in a state system of sorts where an enumerator FlailState has states Swing, Return, Finish, Cooldown. Everything worked perfectly except for Return. On the return, I would have a set speed for the mace to return along a vector direction. This direction was determined by taking the target position (the crystal) and subtracting the position of the flail’s slam position. The slam position was set by the max distance variable at the start of the script and was a transform child of the Flail. This vector pointed from the slam position to the crystal. I would then move the ball accordingly. After this block of code the flail would be rotated to point towards where it had landed to give the ball weight. This all was meant to occur in one frame. The result was a ball that never reached its target and instead spiraled outwards away from the crystal.

This issue continued for about a week of development while I fully rewrote the script, ignorantly believing this would fix the issue. Of course, it did not. The solution was to go back to the design and make it simple. It may be clear from my description that I had a middle-man by means of the slam position object. Instead of having this to base the direction of the ball off of, it would be safer to use the ball’s position. This makes the ball always move towards the crystal on return. It would also seem to give the weighted effect I was looking for.

Hopefully this was sufficient to convey the importance of not over-complicating an issue. Going back to the method of implementation and redesigning it is sometimes simpler than trying to learn why the implementation was not working.

Read more about:

Blogs
Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like