This week has been dedicated to edge cases and paranoia. A common issue developers have to deal with is the edge case. An edge case is a certain game state that causes an error. It does not happen all the time. Its not necessarily uncommon though. The more complex the amount of things that affect an output the more edge cases can occur that have to be accounted for.
A design choice that at this point we cannot undo because all our systems revolve around it is the mono lasers one and done implementation. Lasers are the most common object in our scene. As such making all of them constantly update would drastically effect the running speed of our game. If each was constantly running ever laser would be ray casting at all times. this would cost performance but also insure that collisions are constantly correct. Lasers would be stop at objects the player holds in the way. Currently that doesn’t happen. Very early on I ran into an issue with making the laser continue through the checkpoint. I wanted to make it continuous but Activate only got called the first time it hits anything that has an activate function. This was a critical junction. I had designed all the other laser transforms with the expectation that they would only need to know when a laser hit them the first time, Activate, and when a laser stopped hitting them, Deactivate. Unfortunately I made the wrong decision. I made it so Activate is called every time the laser hits a laser transform regardless of whether or not it was already hitting it. I did not quite understand the consequences of that choice until now.
The consequences is that for every new laser transform I create I have to handle the edge case of a laser moving only slightly withing the hit box of the transform. This means a lot of extra if statements that I did not know I needed. These issues did not come up until we tested in VR and some weirdness kept occurring that I could not figure out for the life of me. When i was testing on my own computer using some Unity Editor code to expose functions directly so I could test them I was not having this issue. It makes sense that I would miss it though. After all I was directly changing the angle to where i wanted it instead of changing the angle of a laser in small increments. Small enough increments to hit the same transform twice in a row.
In hindsight the best approach would have been to add a special virtual function in the laser transform class specifically for updating a laser transform that has already been activated. Then I could call that one every time except the first and laser transforms could opt in to handling those changes.
After figuring this all out I added the necessary code to the relevant classes that were still not handling the edge case.
The other thing I did this week, besides the usual bug fixing, also involved cases. I made a merger class. The merger class is interesting. It takes in a laser’s color and combines it into a new color. At first I considered doing this in a similar manner as Nick did with the Splitter, huge switches handling all possible combinations of color data. Instead I took some time to think about what merging really meant.
I came to this understanding: that the Primary colors, Red, Blue, and Yellow, are the most important. They act as components to all the other colors. So then I thought so what if i use their numeric values in the enumeration to calculate the composites. Like what if literally adding Red and Blue gave me Purple and adding Blue plus Yellow yielded Green. So I started checking random numbers to see if their is a good combination where the numbers added correctly without any overlapping additions. What I mean by overlapping additions is a case where yellow and blue equals green but so does red plus red. Initially I was considering any color combination that is a higher number than white to be white. However I eventually realized that there is no combination where Red < Green and Red + Green >= White but Green + Green is not >= White. So I thought how am i going to hand the case where the same color is added twice. My first instinct is just don’t do the addition. How about the cases of two Secondary colors, Purple, Green, and Orange being added together. That is when my intuition kicked in. My second instinct was that the conditions for white are that at some point all three Primaries have been added into the mix. Wait all the color combinations can be written as having Red, Blue or Yellow or not having Red, Blue or Yellow. Wait again those are 2 states. Its binary. I can write it in binary. Binary is what computers are fast at. This is great. So then I assigned Red = 1, Blue = 2, Yellow = 4, Purple = 3, Orange = 5, Green = 6, and White = 7. This allows for checking and changing colors via bitwise functions.
I finished the merger pretty quick. See you next week.