Categories
Game Development

Putting Off Procrastination

Fighting Procrastination: The Local Maxima Problem describes how procrastination might be a symptom of a project that has hit a standstill and can’t easily move forward without taking a few steps back. The Local Maxima is best illustrated by the example of the robot that wanted to go to the moon:

The Moon is way up there. That tree is higher than the ground. I must climb to the top of the tree to get to the Moon.

So the robot climbs up the tree and sits. Yes, it may be closer to the moon than it was when it was standing on the ground, but it won’t actually reach the moon. To actually reach the moon, it would need to climb down the tree and get inside a space shuttle or rocket ship; however, the robot might not want to go down the tree. After all, if the moon is higher, why would going back down the tree, going lower, help?

Jay Barnson experienced this same problem with his own project. He had created a working prototype, but to make progress he would need to tear out functionality and replace it with something else. I’ve experienced this same problem myself, and the fear he refers to is real. Who wants to work productively only to have to say, “Ok, those results were nice, but now they don’t matter, and I’ll need to do it over”? So procrastination becomes a real problem.

I use Subversion for my projects, and I think that it has helped alleviate this problem quite a bit. I could experiment with code, go in different directions, delete and change functionality, and if I fall into despair with no hope of returning with a better product, I can essentially hit the reset button. My last working build is returned to me in pristine condition, and I can start again, only now I know what not to do. The worst case is that I am back where I started with more knowledge of the problem domain. The best case is that I now have an improved code base.

It is probably easy to think that a project’s progress is simply a linear series of accomplishments. Maybe people who have tons of experience can do it based off of a perfect design document, but I can’t. For instance, I had hardcoded variables to get certain functionality up and running in Oracle’s Eye. Originally those variables helped move the project forward. Otherwise, I would be writing abstractions before I know what abstractions are needed. Trying to write code that works in more than just your specific case is great and all, but it is also a great way to stall what you are specifically trying to do. And in my case, I didn’t even know what I was specifically trying to do, so how could I hope to write code that will work for all cases as well as mine?

Later, as I gained an understanding of what I was doing, I had to tear out the old hardcoded variables and analogous functions to replace them with something better. Essentially, I would need to break my project to make a better project. It isn’t so bad when you can change a small function or change a variable, but if your change impacts three classes and fifteen functions, you might be a bit wary. I was. There was the temptation to think, “But why should I go lower when I need to go higher?” Even with the safety net that Subversion provides, it was scary to dive into my code and change it so fundamentally. Even scarier was not being able to compile it for hours.

I did go through it, however, and came out the other side with great progress on Oracle’s Eye. When I hit the next local maximum, I hope I can remember Barnson’s post.

6 replies on “Putting Off Procrastination”

One thing that helps, I find, is to design for replacement. Write your code in such a way that it becomes easier to rip out and replace large parts of it. It’s an extension of “plan to throw one away”, in that you design your system to be internally disposable. 🙂

In practice that means discritizing as much as possible. Your own program should be several layers of thin but flexible internal APIs, with as few internal dependencies as possible. You’re always told that encapsulation and such is good. Take it to an extreme, and make each component as small as possible. Add convenience functions liberally (even if their only goal is to make your syntax easier, they’ll also, as a side-effect, centralize interesting code to one easily-editable place.)

If you build your system to be easily replaceable, then it will be easy for you to replace it piecemeal. It takes some practice to get to that point, but it really is very rewarding in the long run. Your one-line get_setting_var() function that just returns one global value will slave you hours later on when you switch that global value to a complicated set of rules.

Remember, there is no problem in computer science that cannot be solved by adding another layer of indirection (except the context switch costs of a microkernel architecture).

I wasn’t sure if I should comment here or on your post about trying to make your code “correct”. In any case, some time ago I was working on some collision detection routine, and it just didn’t seem to work right. So I junked it, and tried again, it also didn’t work right. So I kept doing this till about 7 or 8 iterations, finally I got it to work flawlessly. It made me think later that I should do that with alot of my code. Plan to rewrite it on purpose so it can just get better and better with time. I have a feeling that if people did this, their code would be less buggy. And eventually you’d start writing correctly early.

Only problem is, I haven’t done anything like that since. (totally just start from scratch again, on purpose).

But I did see the improvement in my code. If I get a chance to code my own games again I might try this again.

Keith

Keith, the funny thing is that Oracle’s Eye was supposed to be a one month project, and part of the reason was so that I could then spend another month reworking it. I thought that once I had a finished game, I could tear it apart and rebuild it with a lot more expertise.

I have redone parts of my code a few times, and I do learn quickly when I do so. Why do I need to change this code? What would constitute an improvement? Should I leave it be? It allows me to think about my code until I am satisfied that it is correct. Even if I write something to forget about it, I tend to look back and see if I can make a small improvement.

Comments are closed.