#7 Bug overlaps


I was stuck for ages with a swing object I wanted to add. It has a platform which swings back and forth, and the player can stand on or grapple onto the platform. I want to explore how I went about fixing bugs related to the swing, I think there's some interesting lessons. 

Issues - made things feel messy, confusing, and overwhelming 

  • There was seemingly a lot of overlap between multiple parts; player movement, the grapple, and the swing. Where did the cause come from? The part itself, or a different part, or an interaction between the part itself and a different part, or an interaction between two different parts? You can see how this gets overwhelming.
  • There was overlap between multiple bugs with similar affects. For example, the grapple would change length unexpectedly while the player was grappling onto a swing platform. Simultaneously, if the player stood on the swing platform and grappled straight down, they would be pushed away a distance unexpectedly. Are these the same issue or not? On further inspection, the former wasn't actually coinciding with a change in the grapple length, while the latter was. Ok so they're different issues, at least in part. But then after removing any instances where the grapple length was changed, the latter issue was still occurring. So it is the same issue. What's going on??
  • Also, when bugs are related to the timing of events in the engine, it can be very awkward to debug. Turns out each object's update function is run in a random order unless specified. Also, the order of the following built-in functions is fixed; OnCollisionExit -> Physics (inc. FixedUpdate) -> Update -> LateUpdate. So if your collision handling depends on the most recent physics information, you have to defer it to update; and if it depends on the result of updates of other objects, it has to be done in FixedUpdate. Very confusing to debug. 

Solutions - organising!! 

  • Most obviously, just keeping track of all of the bugs in one place. If there's multiple bugs regarding the same object, and especially if those bugs might have overlap, or have the same cause, this is a must. 
  • Organising bugs into atomic events, e.g. splitting the example from above into two separate issues. They might end up having the same cause, but maybe they won't; you won't know until you actually figure out what's wrong. 
  • Specifying how to reproduce the bug, the expected outcome, and the actual outcome. This was the most useful here I think. When you specify exactly what situation does - and importantly doesn't - lead to the bug, you can create a (hopefully exhaustive) list of the cases where those situations occur in the code, then just enumerate through them. 

I think it’s a useful practice to come to these conclusions on my own. Of course I was aware they existed before - they're pretty obvious - but I hadn't really felt a need for them. And they take up time, so if they're not necessary they are a waste of time. And it's worth noting that in a lot of cases that is true; they're not universally the best choice. But now that I've understood their value through personal experience, I'll be more likely to use them, and I'll be able to tweak them as I need in the context of my understanding of their intended purpose; rather than just because that's what your 'meant to do'. 

Leave a comment

Log in with itch.io to leave a comment.