Saturday, August 17, 2019

Single-frame Bugs

The past couple weeks have been very busy. There have been many changes and bug fixes. Changing one thing often can break or require a necessary design change with another feature.

For example jagged blade special gems destroy all armor of a random enemy, which nullifies the usefulness of the Tiger's ability to destroy armor of a targeted creature. I opted to keep the jagged blade, and change this Tiger's skill to something else.


The code that evaluates the board for matches was revised a couple times too. There are many ways gems on the board can be manipulated, so I had to insert the proper checks to ensure they can be hijacked and controlled by some other routine. Otherwise, bugs can occur where gems overlap during complex chain reactions, some of which are difficult to test because it all can occur in a single frame where order of execution matters.

There was also a very rare bug where bunnies and enemies in the main screen were not moving correctly. I think I narrowed this down to a single-frame bug, where a certain component for movement being destroyed was attempting to be reused for new behavior. It would get destroyed anyways, causing these creatures to stay put. This is potentially fixed, by checking if the component is being destroyed which I flag manually. Destroying a component at least sets enabled to false immediately, which can be an alternative way to check but can provide false positives of being destroyed.

The rest of the fixes were easy and straight forward, like updating the user interfaces. There are still bugs, but at least I have been able to play through the entire game on fast-forward mode, while adjusting the difficulty curves.

I really admire how references to GameObjects in Unity are set to null automatically. I strongly prefer this over the other approach where objects stay alive until all references are set to null, which can cause annoying memory leaks. However, the GameObjects are not set to null immediately, so a proper check is to check if null, and, use the overridden Equals method. This detail can be very important in some cases.

No comments: