Search

Alpha Build Announcement and The Importance of Knowing Everything

Updated: Aug 22, 2019

I've spent the entirety of the last two days hunting down the nastiest bug I've had to face on this project (edging out the second nastiest, one that I've been looking at for weeks but which was nevertheless much less critical). The issue was this: suddenly, out of nowhere, every time I moved from the menu scene to the main game scene, Unity would freeze and crash.


Right off the bat, this was going to be a hard one because "freeze and crash" implies no errors actually being thrown, plus the annoying start-up time I needed to wait in between diagnosis runs. I started by populating Debug.Log statements everywhere, but I've found that they aren't always as reliable as you'd expect, due to Unity writing to the console at a specific time each frame, not necessarily at the exact time it reaches the line the statement is on. (I wasn't seeing a statement placed at he very beginning of a function I knew for a fact it was going into.) Single-step debugging wasn't much help either, due to the nature of Unity code. Trying to troubleshoot anything that happens in Update or one of the other every-frame methods will have you repeatedly hitting the breakpoint without any way of knowing which execution will be the one that fails, and although I was pretty sure the problem was elsewhere, my use of coroutines meant that stepping became weird, and in fact I observed the crash happening at a few different, completely unrelated lines while doing so.


Although conceptually it made more sense for the problem to be in the scene that was loading, I thought it was in my menu scene, because I'd been working almost exclusively in it. Luckily, I've been keeping good documentation about everything I've been doing, and even luckier, I've learned to always keep a copy of my codebase on an external drive, versioned a few days behind the current. Unluckily, it wasn't easy to re-implement things, especially asset-dependent things, and even as I did so very carefully, the problem seemed to just randomly pop back up. Sometimes it would take two or three test runs without changing anything in between to reveal itself, and that's one of the scariest problems a programmer can face.


It ended up having to do nothing with the menu, or the coroutines, or really anything that I was expecting. It had to do with the very harmless action of moving all my cows' starting positions down a bit so it didn't look like they were falling out of the sky as the game began. I have code that makes the cows pick a new wandering destination whenever they OnCollisionEnter the ground, so that they start moving A) whenever a UFO drops them and B) at the beginning of the game. If the cows start in contact with the ground, OnCollisionEnter is called on that very first frame. BUT. On that first frame, my environment navmesh is still generating, so I have a few dozen cows infinitely looping as they try to pick valid destinations on a navmesh that doesn't exist yet. I simply needed to put in a Wait command that stopped the cows from doing that until they got the all-clear that the map was ready.


The two problems in this situation were 1) my reliance on the A* pathing plugin to do all the navmesh stuff, treating it like a black box and lamenting that it doesn't have the sort of verbose error messaging that might have at least pointed me in the right direction, and 2) the OnCollisionEnter itself. I solved a very similar problem before, and in fact had code that kept the cow script from turning on until the map was ready. But callback methods like OnCollisionEnter get called even when their containing script is deactivated (only stuff like the Update and other "every frame" methods don't). I didn't know this (or at least, I wasn't thinking about it), because I'm not an expert on the intricacies of the Unity flavor of C#. On a larger team, there would be a guy who is (The Mythical-Man Month's "Language Lawyer"), and he might have spotted the problem sooner. All I know is that I'm back in business for now, and I'll be decreasing the length of time between my test cycles to try and reduce the amount of potential problem-causing things in each one.


Now, all that being said, I'm confident that I can announce that the Alpha Build will be released on schedule, this Monday, December 14. It's likely that this will be the last public build (Beta is for "special testers only), so the effort was put towards making it more user-friendly, with expanded help screens, a tutorial, and more verbose wording in places. But don't worry, there will be plenty of new gameplay features to try out as well. Start getting excited!