2015/06/25

Integrating System.Diagnostics: Instrumenting

With the support systems in place, it's time to instrument the rest of the code base: Program.cs and MainGame.cs. Not a lot of work, but that's the point: By doing it now and working with the requirement of instrumentation from this early on reduces the workload associated with it.

Program.Main()

There's two things we need to do here. The first is marking the beginning and end of the session (since all sessions log to the same log file, making the break obvious is a definite necessity). I originally wanted to make a blank line in the log file, but that's not straightforward enough for my tastes (in fact, I didn't get it to work at all) and I opted for simple Start and Stop events instead.
At this point, the Main method looked like this:
Padding the messages to 128 and 129 characters respectively ensures that they have the same total length (for pure visual appeal), and padding with a dash makes these entries highly visible, which I think is really important, since they are the only thing separating different sessions.

The other thing is crash reports. If an exception manages to slip through all other layers, I want to catch it here, log everything about the circumstance it occurred under that I can get my handy on, then quit the game as gracefully as possible.
To do that, I surrounded game.run() with a try/catch block and logged the exception like so:
This still isn't perfect, obviously, because there's probably more info I could get, and because it doesn't actually quit the application gracefully.
For the former, I will implement a ReportCrash() method on MainGame that logs as much of the game state as possible (though it would be empty at this point, since there is no game state yet), for the latter, I'll simply show a message box notifying the player that the game unexpectedly crashed and give them the option to mail the log file to me.
Note that I simply rethrow the exception when debugging, which makes sense because I'm still the only person actually possessing the "game" and I might be able to get even more info from the debugger than the log. The other features I didn't implement yet because I'm basically always in DEBUG anyway and emailing the log file to me from my own machine doesn't make a lot of sense.

MainGame

is much simpler to instrument, since it matches the use case for the rest of the code base and was intended to be simpler to do. I just pass in the TracerCollection, initialize a Profiler and a TraceSource, call Profiler.BeginFrame in Update and Profiler.EndFrame in Draw, and surround the rest of the methods with Profiler.BeginOperation and EndOperation. If that was too convoluted to understand, it looks like this:
As you can see, these support systems are really simple stuff. Of course there's always more stuff you could add, but I think this is a good balance of ease-of-use and feature count.

With all that boring stuff out of the way, the next up is content management, and how it relates to user config, save games, modding, localization and, weirdly enough, game state management.

No comments:

Post a Comment