Things that will hold your game from being completed
There are too few projects that I’ve finished. I cannot say “Here, this is my fully completed project. You can take it and use it.” And I’ve got so much such projects that I can see some patterns in reasons why they won’t complete and make list of rules how not to do things when developing games.
Do not make from scratch
Use off-the-shelf tools. Do not write physics from scratch, instead look up for free physics engines like Box2D, for example. Do not make resource manager from scratch, use SFML, for example, which has some basic capabilities for that. Do not make your own map editor, use Tiled for that. Try even not to make a new game if you can do a mod for existing one. Even if you have just some code from older projects that can you can reuse - do it. That’ll be much more effective. Each tool you make for your project, takes your time bringing nothing back except for fun - but you it is your game you make for fun, not some tools for it, right? And it’s one thing when you know how tech is working from inside and completely another when you invent things which already have been invented by someone. That being said, not make tool from scratch only if your goal is to make this tool from scratch. Don’t trade experience for time - you can make experience whenever you can but you can’t bring lost time back. And when you’re using some technology for some time and know how things work - then you can try to implement them yourself. For fun sake.
Do not make general-purpose engine
It’s doubtful that you will make games like your current one. If your goal is to make a specific game - make a game. You can hardcode values, if you won’t allow game modifications - and you probably won’t. You can hardcode levels and maps, if you won’t make a map editor - and you won’t. You can even hardcode enemies’ behaviour, if you know their setting from start. It will make them more alive and attractive than some predefined components which turn them into identically behaving zombies with only distiction being a name or a strength of hits (unless that’s what you want, of course). Only when your game is done and you’ve decided that you can make something similar - then you can extract level editor from the game into a stand-alone utility, make component-based enemies, make a game engine. Even if you’ll make a game first and then turn it into an engine - it’ll be more effective than creating an general-purpose engine with bunch of features that no one will ever use. You could even not pass the ‘engine-building’ stage in this case, because you’ll be tired and lost all the fun - for what, some boring abstraction instead of interesting game? Or, moreover, you can lost in abstractions and forget what you’ve had initially in mind. You know, a game.
Use technical debt
Let yourself to make a mess. Forgive yourself for non-critical errors. If bug won’t affect gameplay - leave it, you can always come back and fix it. But it’s better to fix bugs when you have completed, fun game than be buried in endless bugfixing and refactoring and turn game developement into merely a bugfixing. Your goal is to make a game, not to be making a game, right? You want it done. Of course, you should not slip into extremes and leave all bugs, you should fix them bit by bit. For example, a rule that I’ve seen in some article: 5 days for introducing new features and sixth day for bugfixing and refactoring (to prepare code for next iteration). And seventh day is good for resting from development at all - it’ll refresh your mind and may bring some new ideas and such.
Two ways of development
Most popular (and mistaken for the only true) development process is upside down. I.e. you write your system in abstract terms (top level), then fill every unit’s content - the same way, from more general to the specifics. TDD or prototyping are perfect for that case - you set behaviour of the system not concerning what’s inside and how it works. Obvious drawback is that the only people who understand it completely are smart dudes that write books and blog posts (yeah) but don’t apply their knowledge in practice. Because in real life you’ll have need to redesign almost in every case. And you will do that for each level of abstraction from up to bottom. And if your mistake was on top level, you’ll need to rewrite you project completely.
The opposite for that is upwards design which can help to start development from details and complete the whole picture with them. This method could help to make fully-working, tested and debugged product right away. So what if it is not usable and has no functionality - features can always be added but product is safe to use. Personally I think this way is more natural, because evolution itself works like that: some objects are gathered and suddenly there is a system with new qualities. But unoftunately this approach is useful only in conditions when inventions or research is needed, and when you have goal to make specific product with certain features and you nurture your system like stalagmite - drop by drop - it’ll take time exactly like to build one.
Therefore, as usual, the best approach is combination of both ones described above. For example, write minimal functionality which complete product basic idea, make prototype, turn it into working application. Remembering that is should be as minimal as it can be (we’re not writing general-purpose engine, right?) - e.g. when creating a rogue-like all the stuff that’s required is a player character moving on map and fighting enemies. Everything else is supplement. We don’t need even classes or abstraction at all - a cell array, an enemy list, player position and player health. But when we finished with basic functionality, we can add new features (reusing as much as we can - libraries, components, algorithms etc) and accumulate them into top-level units - for that sixth day (described above) should suit the best.