I can remember sitting in one of my university lectures a long time ago being taught about development philosophies. It was all pretty standard stuff, we were walked through the “traditional” methods of development (basically the once through, waterfall technique) and then brought up to speed on the more modern iterative approaches. However one little soundbite always stuck out in my head and that was when the lecturer asked us who pays for rework when a product doesn’t fit a customer’s expectations? The simple answer was you, the one who developed it and it’s something that always plays over in my head when I’m working on a project, especially those ones I do at home.
I’ve been paying extensively for rework with my latest forays into the world of game development. My regular readers and Twitter followers would’ve noticed that I cheerfully announced my success in cracking the stable orbit problem. Indeed in a round about way I had, basically my Unity scripts would push the planet around until it hit a stable orbit and afterwards would calculate the required velocity before turning off completely, letting the heavenly body orbit in a near perfect circle around its star. This worked for the 2 planets I had in there but unfortunately the equations I had developed didn’t generalize very well and adding in planets at random locations with random weights led to all sorts of wobbly orbits with planets meeting both fiery deaths and cold extinctions at the cruel hand of my orbit stabilizer. I was back to square one and I spent most of the weekend trying to figure out a fix.
Eventually I came back around to the idea that my smart-ass subconscious came up with a while ago. I had tried to implement it before but I gave up in frustration when the results I got were no different than from my far more complicated “find the angle between the sun and body, increment it a bit, find the new position, create a vector to it then apply force in that direction” when in reality the fault lied in the orbit stabilization code. All that pushing and pulling that made the orbit look stable was in fact imparting all sorts of wild forces on the poor little planet, when in fact the best way is just to simply let gravity do the work for you. With this in mind I re-implemented my perpendicular force calculations and then devised a rudimentary equation that combined the mass, radius and a fudge factor that let me hand stabilize the orbit. In the past attempting to do this stuff manually took me an hour or so per planet, with this revised code I was able to do one in minutes and have developed a new equation that is able to accurately send a planet into a stable orbit no matter where I place it in the game.
This solution was far more simple and elegant than what I had been trying to do previously but the cost in terms of rework was tremendously high. I’m lucky in this respect in that the client for this is just myself and my friend at the moment but had this been for someone else with whom I had a contractual relationship with that kind of rework would’ve been extremely costly. Of course I could try to make the client pay for it but ask anyone who’s gone back to a client asking for more money after saying they could do it for a certain price and you’ll usually be laughed out of the office, if not walked out of there by security.
Working around this isn’t easy as clients will usually want to have a strict set of deliverables and time frames which seems to rule out any iterative or agile development methodology. It also pushes a team dangerously towards suffering from analysis paralysis as you agonize over every requirement to make sure it’s covered off in the final product. A healthy amount of analysis is good for any project, especially if it makes the product easy to maintain or modify, but it’s also incredibly easy to fall into a never ending spiral of pointlessness. Thankfully however I’ve noticed that clients are far more receptive to the idea of milestones these days which lines up well with any iterative process, skirting around these problems easily.
Going after the most simple and elegant solution might seem like the best idea at the time but in my experience it’s those kinds of solutions that take the longest to achieve. It’s almost always worth it, especially if all you’re spending is your own time, but when you’re working for someone else they might not be so keen for you to spend inordinate amounts of time chasing your white whale solution. This probably explains why a lot of software contains incomprehensible code riddled with bugs, but that’s a whole ‘nother ball game and a blog post for another day.
Take a good look at any big IT system and you can usually trace its roots to one of two places. The first is the one that all of us like to work with: the Greenfield project. In essence this is brand new work that has been born out of a requirement that didn’t exist before or a complete rethink of a current implementation. Talk to any consultant who’s trying to sell you some new tech and you can be guaranteed that they’ll be looking to sell you a greenfields solution, mostly because it’s cheaper and much easier for them to implement.
Sadly, and especially for those of us employed by the government, the majority of the projects that us IT guys will work on will never be greenfield situations and will usually be encumbered by some form of legacy system. This poses greater risks and constraints on what work can be done and ultimately you’re probably working to fix problems that someone else created. It’s been rare that I’ve been given the privilege of working on a project that was aimed at fixing my own mistakes, but I could put that down to my insatiable appetite for job hopping.
My own projects are a different beast as they are all my own work and thus all my own mistakes. Take for instance my intial foray into the world of web programming, Geon. Initially I decided that I’d code the whole thing in ASP.NET mostly because I could do it in C# (something I’m very familiar with) and there appeared to be a whole lot of resources available for doing the things I needed to do. For the most part that worked quite well and I was able to get the majority of the components up and running within a few weeks. Sure some of the subtleties of the design I had in my head didn’t quite work but for the most part I was able to get what I needed done, and even launch a few improvements along the way.
The transition was in fact a greenfields approach to the application. The initial iteration of Geon in Silverlight was, for the most part, a like for like system built upon a completely new code base. Whilst they share a common language the frameworks available and the UI design are wildly different. Still with a little effort I was able to replicate Geon into Silverlight in less than a weekend and everything seemed right with the world.
Then one day I had a fit of inspiration about a new layout for Geon. I quickly fired up Visio and started playing around with visual elements and cobbled together a better design. Everything seemed to be falling into place and I could see how it would be so much easier with this new design. Unfortunately this meant that the current code I had written for Geon in Silverlight was effectively unusable as the visual elements drove the underlying objects and thus couldn’t be used. The internal logic of some parts remained though and the new design took considerably less time to develop.
You might be noticing a couple patterns here. The first is (I’m going to start with the good here) that for the most part a lot of what I’ve created is reusable which is a classic example of modular programming at work. There was a bit of massaging between ASP.NET and Silverlight but thanks to Microsoft’s libraries this was fairly minimal. The second is I’m getting into a bit of a habit with starting a fresh each time I think of a new and better way of doing something, despite the amount of work that that entails.
I put this down to a form of analysis paralysis. In essence every time I’ve taken a long hard look at my code after a break from it the first thing I start to notice is how difficult it will be to get everything working just the way I have it in my head if I want to keep the current code. It stems from the way that I work on problems, by intensely focusing on a single problem until I have the solution. Whilst this usually ends up with an adequate solution to the problem I’ve often found myself spending a good 10 minutes on a function figuring out how exactly it does something. Repeat this for every function and in the end it becomes easier to just start over again instead of trying to rewrite everything so it fits together perfectly.
This all came to head when I started looking at the layout of Geon and realised that it had some inherit problems with viewing large amounts of information. Subsequently I’ve drawn up yet another design that is, you guessed it, almost wholly incompatible with the way I’m doing things now. I’ve since dedicated my weekend to developing the design and seeing how it works out but as you can imagine when I’m looking at dropping the code base for the 3rd time I start to question whether I’m really making any progress. Or maybe I’m just avoiding coding the real meat of Geon because it’s, you know, hard.
The good news is that the project manager in me isn’t going to be happy with feature creep and deadlines falling by the wayside so I firmly believe that this iteration of Geon will be the last major UI redesign before its final release on the world. This time I’ve made sure to include those “little things” like a user control panel which were strangely absent from my last 2 designs and hopefully I’ll achieve my goal of making the information much more visible than it currently is.
It really doesn’t help that my to-play list of games is getting longer every day either 😉