I've been thinking a lot lately about how to better structure games. One of the tough things about Airships is that because it organically grew out of a prototype, there's a lot of shortcuts and baked-in assumptions that I now have to fix. But in my experience, trying to impose a high-level structure on a game project too early just dooms it to failure as you become mired in a bunch of incorrect abstractions that make everything a lot harder than it should be.
Specifically, I've noted that up to roughly 8000 lines of Java code, I can pretty much hold a project in my head in its entirety, and work on it efficiently without getting slowed down by interactions across the code base. Beyond that, it would be very useful to have a clearer structure, but imposing this structure on 8000 lines ends up taking a lot of time and effort.
Another frequent cause of failure for my game prototypes is never finding a core gameplay loop that works, and piling on extra features in an attempt to fix things rather than addressing the game's core. This failure mode is what the original "halve and halve again" format attempted to address. By making the game simpler each iteration, I wanted to force myself to figure out its core gameplay.
But I think time was the wrong thing to halve. Instead, the new approach halves lines of code, with an extra rule for co-developing a supporting library.
You start out by making your prototype in 4000 lines of code. Having thought about how to improve it from there, you write a library for making games like this prototype that can be up to 2000 lines long. If you're writing a roguelike, for example, this library could contain data structures for the dungeon tiles and algorithms for things like line of sight.
Then, write an improved version of the game using your 2k library, in 1000 lines of code. You're not allowed to change your library once you've started on the second game, so you can figure out where its pain points are. When your 1k game is done, you can modify your library to make it nicer, staying within the original 2k limit. Then, make the game again, better, in 500 lines. Then once more modify the library and make a super-condensed version of your game that really encapsulates what it's about - in 250 lines.
This process, if it works, will yield two extremely useful things: a battle-tested core library for building your game on, and a minimal and punchy prototype that gets to the core of what makes your idea tick. That, or madness.
Anyway. I know that the distinction between "game" and "library" is pretty vague here, and you could technically cheat by implementing the game in 2000 lines of "library" and making the "game" be "library.startGame()" each time. A pretty good but incomplete dividing line could be that data does not go into the library. You can put in code for monsters, and for fire attacks, but the fact there's a monster called a "dragon" with 200 HP doesn't go in there. As for the lines of code, if you think you'll try to bend the rules too much by using awful formatting to use fewer lines, run your code through a strict formatter before counting lines.
Note that you can use data files of arbitrary length - you just have to fit the code to parse and use the data into your library or code. And maybe stay away from implementing your own scripting language in the "data", yes?
I haven't yet tried this out, but when I do, I'll report back on the useful results to madness ratio.