About a year ago I made an effort to start looking into design patterns more formally, however other than a few particular cases (MVC, FSM and Factories) I haven't really found it to be nearly as useful as I first thought it would. Although I am very aware that this is probably due to my limited understanding of most patterns, and I expect that at some point I'll probably have an "aha" moment and realise what I'd actually been missing.
However I did (by a rather roundabout route) end up much more interested in refactoring, in particular because lots of the techniques were ones that I was basically already doing - just more sloppily and without clear names for them. For me refactoring is a great help, and when dealing with existing code (which unless you're a special case, is much more frequent than writing new code) it makes it easier to think in terms of discrete refactorings to achieve a goal rather than going from start to finish in one big step.
I also came across a fantastic piece of advice from reading about XP - when adding a new feature, refactor until adding it is trivial, then add it. This may sound silly but it is more powerful than it first appears. By refactoring the existing code in the area you're about to work you remove all (or at least some) of the 'cruft' that has accumulated there. You remove the dead code, simplify that which is still used and bring it all better in line with the current thrust and ethos of your codebase. This refactoring also has the side effect of making you understand the code better - you're now more aware of the special cases which need to be handled, the dependencies and structuring already in place, and so on. You're also likely to have seen an alternative (and usually better) way of adding that new feature of yours. If you haven't seen a better way then you've probably still had a few present themselves but you can now be more confident that your initial plan was the best.
I find this a very powerful way of developing code - I've never really been a fan of the Big Design Up Front method, and this way I'm free to do a simple high-level design at the start and let it evolve over time to fit the (probably changing) requirements. It's important not to get too attached to the initial design, things can and will change. Rigidly sticking to the initial design assumes that I knew better then than I do now. This is obviously nonsense - I've now had several weeks/months/years extra experience on top of when I wrote the original.
My final point from this is that you shouldn't be making lots of big, hard and difficult design decisions up front. Avoid the big design documents (even if they're just in your head). Instead refactor mercilessly, listen to your code and never be afraid to deviate from your initial design. By doing so you can 'grow' your engine/library/game in ways that you never expected - and it'll be more robust, more flexible and more useful to boot.