While designing, programming, and testing, we came up with some new ideas of how to make the game better.
The dreaded phrase "ya know, this would be cool if...". Yes that. What just happened is something called requirements creep, or rather, features and things that were not part of the original design document, but have become desired enough to "add in" some extra things or at least change a couple of things that we had already designed.
This sneaky way of adding new things in to the product forces us to change code, update documentation, and start our testing all over again with the new things put in to the product. Long and sad story short, it simply means more time is required before the product can be released. WARNING: If this gets out of hand, your product will be delayed indefinitely as more and more new things keep getting piled on!
Fortunately, some of these sneaky new features that were drafted up can wait until after the game is released and we can put the new content in with a content patch later. If you've been reading along, during an earlier blog article I mentioned separating things that we need versus what we want. Requirements creep operate the same way. What must we absolutely have to have in the initial product release versus what can wait. There is a risk involved with this. The more we "must" have before initial release, the longer the product will take to get out the door... but if those new features really enhance the product and make it more appealing or playable, we certainly should include it.
For example, during our play testing, we saw that most the gameplay levels were "too easy". The player could easily fly through the game levels without much of a challenge. According to the design, this was basically as the product was designed. Well, unhappy with it, we decided that different sized bubbles should play a part of making the game more difficult as the game levels were increased. This new "feature" wasn't part of the original design - nor was the existing code ready to make such a new leap in to catering to differing size bubbles.
Because we felt that this sort of thing should be required to make the game more challenging and offered in the initial product, we accepted the new feature, and the recoding of the necessary systems began.
Since our code was relatively easily adapted to the change, it took about 4 hours to modify the existing code and test it to approve that the game now has incorporated the changed feature. If your software person/team is inexperienced, or the code you've inherited is "bad", even a simple change like this could take days to implement. You may scoff at this idea, but I will reiterate my earlier warning, even the smallest things can take a dreadful amount of time to incorporate. Even something as so much as changing the color of something can take a very long time - it all depends on how the software was designed, their existing features, and how well things were programmed, and of course there could be other unforeseen technical problems further complicating the desired changes.
During our testing and development, we also found it necessary to upgrade our core code reuse library to incorporate more graphics utility functions because of the demands on this product. This took a couple extra hours to research, code, and test. The tradeoff is such that now projects in the future can reuse this code, saving the time and headache later of having to redevelop it again.
While programming a game, or really any software, the programmer should always be aware of what they are making could be generalized in to useful and reusable modules for other projects. There is, again, a tradeoff to "just make this feature" and "generalize" it for generic use. It usually is quicker just making the solution once while specifically tailoring it for the one active project, but if another project needs that functionality, it takes more time later to surgically remove that code from the project and alter it later for the newer product. The experience of the programmer here will help them dictate when and what they should generalize.
A specific example of this - one of our products that hasn't been released yet uses a feature to flash the screen red when the player takes damage. During the development of the new product, it was mentioned "hey, it would be nice to have a visual indicator for when the player takes damage". It was quite apparent that the code from the older, unreleased project should be recycled in to this new project. Of course, this functionality wasn't generalized in to a code library; however, the existing feature was found to rely on almost no external variables in the older product, and the code was easily extracted from the 3 different functions that it was hooked in to. There were a couple of dangling variables that was required for the code to work as well, so there was some time needed to track those down and copy those over as well. These variables had to do with the time involved with "how long to flash the screen" as well as "how much red is flashed at a given time".
If the older code was sloppy, or had I not been intimately familiar with the code, a job like this - tracking down code/features to extract - can take a while. This is something that shouldn't be taken lightly when planning how long a product will take to develop. Code reuse is good and saves time, but if you have to attack another product with a scalpel to find all the code to reuse, it can be a nightmare in itself.
Ok, so, we had a requirements creep with the flashing feature. It took about 30 minutes to track down our existing code to make this happen and we integrated it in to the new product -- in theory. Remember, we need to test the new code to make sure it wasn't rejected by the new product! Sure enough, we attempted to test it; and nothing happened when it was suppose to.
A quick "oh duh" moment later, and we realized we forgot to call our new flashing code when the condition warranted it. We integrated the code, but forgot to actually use it.
We decided to call the new flash code from inside the method where players take damage and decided to test it again. Huzzah, it worked! Not only did it work, but it worked as expected!
Long entry, but take away from this that new things, small things, and even big things can, and will, come up during coding and testing. Some of these things fall in to the "need to have" category and can add substantial time involved in to the development of your product.
Next time we'll get in to the software design aspect of the product, I hope!