Related to the fact that I’m having slow project progress on Stop That Hero!, I wanted to expand upon this thought:
Iโm using Test-Driven Development on this new version of the game to ensure that bug fixes and game updates are as easy as possible. If a paying customer finds a bug or if I release a new feature, I want to make sure that new code works and that old code doesnโt break.
I also wanted to discuss over-engineering.
Estimated Project Progress
This chart shows my estimated burn down if I was working at the ideal rate of 20 story points per week, assuming my project doesn’t exceed 80 story points.
In the last two iterations, I’ve found that I’ve only accomplished 7 and 10 points. Assuming I can continue at 10 points per week, here’s my updated chart:
It might be a bit hard to tell since Google Docs don’t give me much ability to change the axis in these charts, but in the first case, I am well on my way to hitting the October 31st date. In the second case, this project won’t be finished until the end of November.
With Thanksgiving coming and plans to move out of my apartment, November isn’t an ideal development month either, so it’s more likely that it will be December before the game is finished. And what about playtesting and game balancing?
Yeesh. Well, the solution is simple, isn’t it? I just need to do 20 points worth of work each week. Quit being so lazy, Self!
In all seriousness, though, the 20 points was an estimate of the points I could complete each iteration, and that estimate wasn’t based on hard data yet. Two weeks later, armed with some data, I was able to generate a few charts such as the ones above and analyze them.
My Analysis
My original estimates didn’t take into account how much time I’d spend getting the basic infrastructure of the game under test. More importantly, I didn’t specify how data-driven this game would be at the outset.
The more data-driven the game is, the easier it is to modify, configure, and improve. I read that a game such as Age of Empires literally used a database to specify each entity in the game. It allowed designers to modify the database values for various units and see those changes in the game quickly.
The original Stop That Hero! is almost completely code-based. The only data loaded is the level layout, and out of all of the things I could tweak in the game, that level layout was the easiest to change. The level was loaded based on this image file, which is blown up to make it easier to see:
I could update that image in an art program, then see the update the next time I ran the game. It would have been even faster if I could reload the file on the fly instead of having to restart the game. Still, the point was that it was easy to change the terrain and the location of towers and treasure chests without recompiling the game first.
But what about the enemies in the game? They are all implemented as instances of the same class. In fact, the Hero is just another instance of that class. Couldn’t they be loaded from a file, too? Sure! I could load a file that specifies what sprite to use, the dimensions of the monster, the speed, the strength, and a number of other attributes. If I had done so, I’m sure balancing at the end of the Ludum Dare Jam would have been easier and more effective.
Variables such as enemy stats, resource costs, and chest contents are great to put in configuration files and scripts, but how far do you take it?
Ideally, even game logic could be loaded at run-time. Instead of hard-coding that you win when the Hero has no more lives left, why not make it a specific instance of a Victory Condition? This way, I could create other Victory Conditions for different kinds of game modes. I could make a tutorial level where the Victory Condition involves creating one of each type of monster, for instance.
And speaking of levels, the original game only had one. How do I create multiple levels? I’d have to create some kind of level collection or campaign, and each level might have its own Victory Conditions. And if I’m going to be able to do so much configurable work, I might as well let the players come up with their own mods, too! I wonder how quickly someone would make a Tower Defense game out of Stop That Hero!…
Yes, the more data-driven the game is, the more interesting it could be. Bug fixes, patches, expansion packs, and feature updates can be as simple as adding or changing data, and if code is needed, it should be relatively simple to write.
The thing is, to get to such an ideal data-driven game in the future, I’d have to do a lot of work NOW. Maybe later balancing and game play tweaks and entire rule changes can be easy to implement, but for now, I’d need to lay down a lot of infrastructure.
Infrastructure and Over-engineering
The biggest source of stress for me is the oscillation between wanting to implement just enough of the game to sell a complete copy by October 31st and wanting to implement a game that I can easily update.
Again, October 31st isn’t a hard deadline for my business. It’s a deadline for an inspiring challenge, but missing that deadline isn’t the end of the world. Besides, once the game is finished, there’s still a lot of work to do. Customer support and maintenance are my chief concerns.
If I really want to hit the challenge deadline, I probably can’t make the game very configurable or provide multiple game modes. Still, if it means having a finished game out and selling sooner, maybe lassoing in the scope is a good thing. After all, I could always update the game later with new features, and I can even have the benefit of customer feedback. “Release early, release often.”
On the other hand, I might implement the game in a way that is hard to change. After a weekend of Ludum Dare, I have a rigid, hard-to-change game. If I make this new release fairly rigid as well, what happens when customers complain about bugs? How hard will it be to fix them? I could always add features later, but how much more effort would it require if the code isn’t set up to make it easy?
By taking my time, I could end up with a much better game. It can be slow-baked to perfection instead of being rushed out. It would be easier to configure and mod, and I believe it would result in a much better value proposition for the customer.
Of course, it’s all speculation. It could be that I’m putting in all this effort and over-engineering the implementation for nothing. While it is good to think long-term, what if I don’t need to do everything now? I could forget about creating configurable Victory Conditions and other rules for the moment. If I focus on loading variables from files while assuming that the rules are still the same, I could go a long way.
I think you could only say that something is over-engineered if it anticipated future needs before they became real needs. In this sense, making the game configurable is a real need, and so writing the code to allow it wouldn’t be over-engineering.
But I’d have to make such a need explicit, and I don’t believe I had at the start of the project. Oddly, I felt torn between two different assumptions: I’m releasing at the end of October with as good of a game as I could make by then, and I’m releasing the game only when it full-featured and highly polished. My anxiousness about wanting to develop just enough to release something soon versus wanting to make something with more value was because I hadn’t spent much time on project specifications.
It sounds more formal than it is. Basically, I haven’t decided on exactly what game I’m making, and I was hoping to offload that work to the configurable nature of the engine I’m writing. I wanted to make the game so easy to modify and change that I can experiment quickly and see what works best. While it can ultimately work out really well, it’s a recipe for taking as much time as I am allowed. Of course, I work for myself, so no one is there to hold me to a deadline but me.
A concern is that until I start earning income from paying customers, I’m relying on my savings to live and work. I can’t afford to spend 3 years on a single game, but even spending six months in development would translate into losing a huge chunk of my savings. It’s too risky. On the other hand, I don’t want to try to churn out lots of games in mere days or weeks. I can’t see making anything worth being paid for in that time frame, and spending months releasing poor work isn’t a good use of my time, either.
In the case of Stop That Hero!, releasing it sooner, even with fewer features, is better than spending forever trying to make it perfect. I can always make it perfect with the benefit of customer feedback, and earning any potential income sooner rather than later is a nice bonus, too. B-)
6 replies on “Balancing Current and Future Needs”
I over-engineer. Then I have to remember, nobody can buy something I’ve never released…
I tend to err on the over-engineered side as well. I think that’s a common trait among engineers. ๐ Knowing when to say “screw it, this gets hard coded” is an art that one only learns with time.
Although I usually do my heavy work on frameworks rather than specific applications, I’d say “build for extensibility” rather than build for configurability or flexibility. For instance, you need to get your monster data from somewhere. Do you need to spend the time writing a configuration file format and parser? Not now, but you want to later.
So abstract that to a MonsterList class/object/package that gives you back a list of monsters and their properties. Then have one version of that class that is completely hard-coded quick’n’dirty. That takes very little time. Build your other code around that, and keep that abstraction intact. Hard-code whatever you want behind that abstraction wall in whatever way is fastest.
Then later, when you have time, or get a feature request, or want to introduce some great new features for version 2, you can easily write another version of MonsterList (same interface/base class/whatever it is in your language) that reads from a config file. Spend the time then on a good config format, or even a user-friendly monster editor. Keep the interface the same. Now you can very easily swap out the hard coded class with the new one, possibly even at runtime if you built it right.
Fortunately, that dovetails wonderfully with TDD and good modular development practices in general. In a sense, your first draft implementations *are* the mock version of those classes. Version 1.0 is 2/3 mock objects. ๐
In the open source framework world I play in, I’d even make it possible for other developers to swap in other MonsterList classes without talking to me. You may or may not want to go that route, but if you have properly abstracted the “get me a list of available monsters” logic away from the rest of the system you *could*, without impacting the rest of the system.
Designing for flexibility doesn’t necessarily mean implementing flexibility the first time around. ๐
Oh, and one other thing. Remember Asimov’s Law: 2 is the least likely number in the universe.
There will be things in your system that you’re reasonably sure will only ever appear once, or exist once.
There will be things that there could be any number of.
There are no other categories. You will never have only two of something, or only three of something. There are only two numbers, 1 and n. If you find yourself hitting a case where you need more than one, it means you need n. Refactor accordingly immediately rather than implementing logic based on only two possibilities. If done early it doesn’t take a huge amount of time but will save a lot of complexity (and therefore wasted time) later on.
At least that’s been my experience. Switch statements are evil. Loops are your friend. ๐
Thanks for the advice! I think what you described is what I wanted to do, but I didn’t follow it very well. In the effort to make the game as data-driven as possible, it seems every single variable I come across can be implemented in a general way, and so I start to feel overwhelmed with all of the code that pretends to configure something.
Configuration objects that hide hard coded variables – two thumbs up from me too!
Although, I loved this article where the game implements a generic “value store” where everything is kept and a server exposes any and all of them on request, so a separate windows app (or telnet) can get a list of all configurable values so you can tweak them in real time. The same value store dumps them all into a generic xml file so they aren’t forgotten. Obviously a bit of work up front to set it up though. And yes, I haven’t gotten around to doing it yet – doh!
http://gamesfromwithin.com/remote-game-editing
Release early, release often – people respond differently to games when they know they are expected to pay for them. Getting them to pay might mean turning all your expectations upside down, can’t tell unless you get something out there, but you can call it an alpha so it doesn’t need to be too polished. This guy is making a reasonable living releasing a game a month and selling at 69pence!!
http://radiangames.com
He could build a PC version and sell through paypal for ยฃ1 leaving him a similar 69p profit, why doesn’t he? Would a PC audience go for a ยฃ1 small game like that, do they expect more?
All great comments.
Given the wide reach of web applications and online app stores (such as the iStore) and online delivery infrastructure (such as Steam), I think players are becoming more accustomed to “frequent updates” and may not be as big of a deal as us old schoolers are making it out to be.
If you can market your product with the clear message that they are NOT alpha (or beta) testing your code then I think you can find your clientele that doesn’t mind paying a smaller fee while you get your main feature set polished and delivered.
My current mindset for what I’m working on is that the earlier a player supports my product the huger his / her rewards. Maybe a “lifetime discount” on any future product I release for example.
When you’re Indie and you’re “the boss” you can create any exciting incentive program you want. (You just have to be able to sell the vision).