So, I’m making faster progress than expected, which is good.
This has also given me time to collect more thoughts on the problem of planning.
My usual workflow is I write up a document that lists the goals of the software, and under each goal I’ll usually brainstorm some ideas for how to approach a solution, or connect it to other solutions.
I’ll usually also sketch out some simple algorithms using nested bullet point lists.
From here, I use commented pseudo-code to sketch out my data structures. If I were working with a team, I’d probably draw out these structures with images, to create more intuitive representations. I might also use commented pseudo-code to lay the foundations of interfaces, methods, basic algorithms, etc.
From here, I start coding the actual stuff, using my comments as a sort of guide.
I know some people will go as far as write out every line on paper before typing it in an actual code page, but I feel like that’s an extraneous step, especially in the world of version control.
The moment you start worrying about actual likes of code, it’s best to start writing it for real, because you’ll catch bugs and implementation errors as they would actually appear, and this is going to influence the rest of your code going forward.
I usually make a note to habitually do refactor passes, normally every four or six methods or so.
However, I have a clear separation between actual code and simple outlines, because past a certain level of detail is where outlines stop being outlines.
So, what went wrong with my previous parkour implementation?
About halfway through implementing the whole outline document, it occurred to me that there were some weird functionality quirks (sometimes bugs) which I would have never been able to predict at the outline stage. Again, this is why it’s important for me to write actual code as soon as I get more detailed than a simple outline.
The bugfixing process for this created a really weird branch of the codebase, but it was essentially an edge case at the time, so I didn’t think about it much.
I then did a major refactor pass. My instincts told me that this edge case should be refactored, but my brain quickly realized that this rabbit hole went wayyyy deeper than expected, so I made a little
TODO note to outline a proper large-scale refactor after I implemented one more thing.
Now, some of you will read that and say “Oh no. Refactoring is not something to kick down the road.” and you’re right; it’s not. However, that one more thing was an idea I had literally come up with the day before writing that
TODO note, and added to the list of goals because it was an extremely important idea that would really take the parkour system to the next level.
This one more thing also seemed super easy to implement in very little time, so it didn’t feel like I was kicking refactoring down the road at all. In fact, I thought it would be better to see how this last feature would fit in, and maybe influence the upcoming refactoring pass. After that, I had a lot of bughunting scheduled.
I got maybe two-thirds of the way through, and that last feature immediately ripped open every possible issue with the aforementioned “edge case”. It was like pulling on a thread and undoing an entire garment.
This showed me that a major refactor pass was not enough to solve the issue. I sat down for a few hours, and wrote some outlines on a possible solution, but the result kept getting further and further from the original project structure. Once I finally had something that was going to work, it required to redo everything from scratch.
All because of this one last feature.
Again, the delayed refactoring was not the cause of the problem, it was a symptom of a problem I was to discover later. This last feature actually required a full restructuring of the entire program. I would have made this same realization during or after refactoring, because a refactor would not have saved the project.
If this feature had occured to me from the beginning, I could have avoided this. Also, if a few of those early implementation bugs had been more obvious, that would have helped as well.
However, using my brand-new outline, I can proudly say that there are no edge cases, and all features will work smoothly.
If I was any more pressed for time, I might have been tempted to cut that last feature, but it was something small that would have double the possibilities of the system.
Additionally, the new structure for the parkour system makes its use a lot more flexible and intuitive, which means less documentation and an easier learning curve.