Oct 9, 2016

Spring cleaning

So in my previous post I discussed how I had returned to this project after a 7 month hiatus. To get back on track I decided to do a bit of code spring-cleaning. Its actually spring here in the southern hemisphere, so it seems appropriate.

Before beginning work again on the game proper, one of the aspects I wanted to improve was the testability of the codebase and eliminate the global references that have spread through the codebase like cancer. Note: my codebase is written in C# in which global objects are defined as "static", so where I say "static", it's the same as global.

First step; make the static classes instantiable!

It turns out that I converted my EntityManager class to not be static at some point, so that was a huge advantage. However, it is created once, early in the life-cycle of the application and is stored in a global that is referenced throughout the app... bugger... about 500 times... double bugger.

Also I have a mixture of local server and client code that refers to the same references but use them in different ways, and some references that use [ThreadStatic] as a workaround to correct problems where different threads needs different versions of the same object. Truly the stuff of nightmares!

Because of that I'd written some truly horrific unit tests that had to start up most of the game engine in order to test something simple like the serialisation of a component. Seemed like an excellent place to start my clean up!

Dependencies to the rescue!

I refactored a lot of code to accept an IEntityManager instead of using the global reference, and over time my unit tests cleaned up considerably. I applied the same logic to other manager objects and eventually my unit tests became completely independent of the rest of the codebase, relying on mocked versions of the important managers, injected as dependencies.

I continued this initiative and carried it over to other globals, and I've managed to completely remove some of the  references entirely. The client and server code is now safely segregated and the ThreadStatics have been removed.

The aforementioned EntityManager global still has 200 references to it, but that's a great improvement on the 500+ that were there when I started this effort. Furthermore, the AssetTemplateManager is down from over 100 to just 27 references. There's still some way to go - the target is to remove all global references..

So, lessons to be learnt here? Static/Global references are bad and once introduced to your codebase they tend to spread unchecked. I've been working on this codebase for over 5 years, and I've learnt a great deal about C# and development in general during that time. Anything in the project older than a year makes me cringe, and there's stuff still in use that was bedded down in the first few months of the project. I had no idea about dependency injection or why global references were a bad idea, and now I've seen the error of my ways.

On a side note, I've discovered that Squarepusher is great for refactoring!

Sep 23, 2016

Progress Update September 2016

Where to begin? Not long after my last post, development on Bulldog stalled badly. I had a few other game ideas kicking around and after some soul searching I decided to put Bulldog on the backburner for a while and start developing one of the more promising (and less ambitious!) ones. I made some good progress, and even trialled some changes to my development process.

At my day job as a developer we've been transitioning over to a Test Driven Development process. I've embraced a lot of these ideas, such as Dependency Injection and Mocking for my part-time games development. Its really shown me where I went very wrong with Bulldog's development from the outset.

Now, fast forward 6 months or so and I'm about to abandon the new project, (code-named "Collie") and switch back to Bulldog again. What the hell?!

This is for several reasons:

  1. My design for Collie isn't really mature enough. 
  2. While working on Collie, I never stopped thinking about Bulldog, and kept coming up with cool new ideas for it, which suggests to me that my subconscious really wants to build that game, not Collie. 
  3. I've hit a bit of a wall and can't find motivation to continue on Collie at the moment. Perhaps related to #2?

So... you wasted seven months?

Not exactly. Working on a new code base, it really illustrated to me the problems I was living with in Bulldog, and as mentioned earlier, I can really see where I've gone wrong with singletons and statics all over the place.

I'm excited about getting Bulldog back on track again, and have great plans for resuming development and refactoring the codebase to correct my previous mistakes that prevent proper unit testing etc.

I've also learnt a lot about focusing on the value of new features, and developing the most crucial things first, not the coolest or hardest ones.

On this note, I came to the shocking realisation recently that Bulldog is at its core supposed to be a survival game, but after 5 years of development, I haven't coded the ability for the player to die yet! I've got procedurally generated terrain, real time shadows, pathfinding, a custom UI, status effects, loot tables etc. But if the player's health hits 0, the game locks up. What the hell?!

So yeah, I'm coming back to the project with a healthy dose of "What the hell was I thinking?", a fresh perspective, some new development skills and a renewed passion for making this game.


Feb 22, 2016

Progress Update February 2016

As is rapidly becoming the norm, I've scope-creeped the hell out of this latest snapshot. I'd intended to wrap it up just before Christmas, but here it is, 2 months later and I've still got over a month of dev to go. I made the mistake of starting work on a feature I didn't have a really solid design for. I thought I could "wing it" and the gaps would naturally fill themselves in, but I hit a few issues that basically blew that out of the water. I've sorted out the design now, but there's more work to be done before I can tick crafting off my todo list.

I changed my mind re: the UI redesign I mentioned in my last post. It is going to be much harder to change in the future, so now is the best time. It ended up taking about 3 weeks, but I've replaced my old, half-assed layout system with a newer, more flexible one that's now using its whole ass. As a bonus I fixed a few lingering layout bugs that have been annoying me, so yay!

I've got a fairly good design & plan for the next month of development. Barring any unexpected hiccoughs, I hope to put crafting to bed and move on to some of the exciting new things I've been dreaming up over the past year.

Jan 13, 2016

Progress Update January 2016

Happy new year everyone!

What have I been up to since October? Less than I would have liked. However, I've made some excellent progress on the crafting system again, taking some influence from games I've been playing recently. Unfortunately I find it way too easy to make my game systems crazy complicated.

One of the risks of being a one man dev operation is you have to be your own bullshit filter. I often get so enamoured with an idea I'm working on I don't realise it will be terribly complicated for the player until I'm a decent way in. Eventually (once the shine wears off) the sanity police rock up and I drastically cut functionality and make it sane. I just wish it'd happen sooner, so I don't waste development effort. :)

On a related note, recently I've discovered some annoying issues in my codebase that are not going to be quick fixes and are preventing me from building certain pieces of functionality. They are relatively minor presentation things, so it isn't a big deal at this stage, but at some point I'm going to have to redesign my UI system to be more flexible. Not looking forward to that at all.

On a non coding front, I recently made some major breakthroughs on the backstory front. I've broadly defined the story elements that will occur leading up to the player taking control and even had some ideas for a short intro sequence to relate this to the player. Previously I had a general idea for what I wanted but there was no clear path from normal world to the game world, narratively speaking.

In the development pipeline for the future I have: Finishing off the crafting system, as well as some technical architecture things such as a procedural content system I've been itching to get going on, as well as rendering improvements such as LOD for my terrain meshes.

Until next time!