Obstruction optimizations & bug fixing

Obstruction Optimization

While many of the optimizations created for occlusion are shared with the obstruction system, there are some obstruction-specific optimizations that had to be made to reduce unnecessary overhead. Like occlusion, a movement check is performed before obstruction is calculated to determine whether the player or emitter has moved a greater amount than the specified tolerance. This optimization is reused for obstruction but with the modification of a 2x multiplier for the tolerance. This is done to reduce the number of async pathfinding requests to a greater degree than occlusion is updated while using the same macro.

Another previous optimization made for occlusion is the ‘Dynamic Occlusion State’. As this check will detect whether an emitter instance is entirely occluded in the majority of likely scenarios, it is suited for use with obstruction calculation.

This ENUM state is checked before updating occlusion to ensure that the emitter is not currently in a ‘clear’ state; this would denote a clear line of sight between listener and emitter, making updating obstruction likely excessive.

Bug fixing

Throughout this project, I have had to resolve many issues of varying severity. My process for diagnosing the cause of a bug typically consists of debug log printing and visualization, starting from the resulted issue and working my way backwards to find the root cause. To ensure consistency and efficiency, I have adopted a bug fixing methodology outlined by Yadav in his article ‘Bug Fixing in Game Development‘ (Yadav, 2022). This method was demonstrated while fixing a significant issue with the movement check for both occlusion and obstruction, where a ‘Moved’ result would be returned regardless of player or emitter location.

I began testing with logging the output of the movement check macros, which functioned as expected, with the ‘Move’ execution pin being triggered regardless of player or emitter movement inside the movement check macro. I queried the branch results, leading me back to the ‘Prev Listener Location’ variable stored on the Director component.

This variable was being updated at an inappropriate time, bypassing the movement check. Referencing and updating this variable in the proper position on the Emitter component completely resolved this issue. The same process for identifying and resolving bugs and issues was used throughout the development process.