Agree. When I'm not familiar with what I'm implementing, I tend to plan a bit too much and end up repeatedly going "wait, I need this too" and "hang on, this isn't actually what I want" or "oops, I overlooked such and such dependency and now need to redesign everything", which wastes a lot of time.
The problem with planning ahead is that only experience can give enough information to plan a software design properly. So, in a domain where you have good experience (i.e. many completed programs), you might plan ahead and be mostly right.
In my experience, you want to start small (don't start making plans for every little feature you add, or you'll get overwhelmed and will just give up). Plan the core, then add the rest later on when everything works. Make heavy use of stubs if that's your thing. Always try and keep your code as modular and self-contained as possible, so that adding another feature does not interact (and hence, cannot break) other features on the same level of abstraction. Most of your code should be reusable, ideally you should be able to plug in and out features, if that makes sense for your project.
For instance, your game might end up looking like a tree graph, with each node being either a "feature" (for leaves) or a "manager" (for nodes). The tree is strictly going down, so leaves do not interact with anything except utility functions, and nodes only interact with the leaves they use (like the graphics loading manager might use the PNG loader feature to be PNG-enabled or something - dumb example though). This is all very simplified of course, in the real world relationships are much more complicated...