Just like everyone who has ever attempted to do a programming project, I've encountered a lot of situations where I got stuck, where I lost my grip on the project (because of vastness or complexity), or where I had to abandon the project completely
To help people prevent these kind of situations I want to share some of the knowledge I've gained the last couple of years with the community
Note: These tips do not cover standard programming issues, and assume you are fluent with your target programming language and used programming paradigm, if you get stuck in a project because you don't understand parts of your language or if you don't understand the principles of the coding paradigm you're using (eg. OOP) it should be pretty obvious that you need to study some more
These tips also expect that you have realistic expectations in your project, if you have the illusion that you will single-handedly create the next World of Warcraft you won't gain anything from these tips (since you probably won't even get anywhere). Most of the people on these forums are hobbyist programmers, so these tips are oriented towards them.
So here it is (in all its glory):
Radikalizm's tips for medium to large scale (game) project management
0. My project is going to be an MMORPG (or any other MMO type game)
Stop right there, and read this: http://sol.gfxile.net/mmorpg.html
That is all.
1. Understand what you're writing
Tutorials are great. Even better: Tutorials are awesome!
Tutorials give us a better understanding of what we're trying to accomplish, and they save us the time of reading through tons of documentation and manuals, but (and this is a big but) they also encourage copy-paste behaviour.
When reading through tutorials, or when trying example code people have offered in these forums, make sure you understand what the provided code is trying to accomplish and how it's being accomplished; never just copy the provided code into your project praying it will work (and complaining afterwards if it didn't), because you can be sure it will haunt you in the future.
2. Use version control software
No matter the size of your project, it can always benefit from version control software. Version control software (like SVN or CVS) allows you to revert back to older revisions of your code (if you screwed up badly), branch off your codebase so you can implement features without messing up your main codebase, allows for easy co-operative programming, and just provides a really handy way to make backups of your code (together with a bunch of other features).
On a related note: Make sure your code compiles and runs whenever you're doing a repository commit. Reverting to broken code is something you want to avoid at all costs, since it essentially makes using version control completely useless. Besides this it can potentially destroy teammates' work (if you're working in a team, of course).
3. Plan your project
With smaller projects you might be able to pull it off to just start with writing your code and get a decent result out of it. When attempting a project of a larger size you'll find that this strategy will not work anymore, you will be needing a design document.
A design document contains your project's goals, and a general description of how to reach these goals. For a game this could be a document describing your underlying engine and all the game mechanics needed to build your game. Of course planning everything is impossible, so your design document has to be set up to be flexible so you can alter it in the future.
Note: As ChaiRuiPeng mentioned in the post below, don't overplan your project. Keep it lightweight and flexible, your opinions on a certain implementation may change, or you may find out that there's a flaw in your design, effectively wrecking other features depending on this implementation.
4. Document your code
Ah, the good old programmer cliché: code documentation. A lot the problems described at the beginning of this post are caused by lack of code documentation, and a lot of programmers hate the thought of having to document every single line of code they write. It all doesn't have to be this pessimistic, since there are tools like doxygen and javadoc (when writing in java, duh) to help you generate documentation based on comments inside your code files. This saves you the trouble of manually writing code documentation at the cost of having to write a small amount of comments for each function.
Always program as if the person maintaining your code is a maniac serial killer that knows where you live
5. Use an issue-tracking system
I've only been applying this tip since recently, but it has improved my productivity dramatically. Using an issue-tracking system for bugs, enhancements and possible features (eg. Bugzilla) gives a clean overview of what still has to be done on your project, and allows you to pace your development. A system like bugzilla is very easy to use, so whenever an idea pops in your head, or whenever you find a bug or issue in your code you can post it on your bugzilla system and take care of it at a later time.
Entries can be commented on, be given a priority, etc. and can be easily organized, giving you a very clean project overview.
6. Take your time for research
When starting a new project most people are eager to get their hands dirty on implementing all the awesome features they have in mind without directly thinking about optimization or checking out how others have achieved the same goals. In graphics/game development there is a wealth of resources, studies and papers available on next-generation techniques and implementations for free, mostly published by game studios or universities. In my experience, going through these to study different approaches on solving a problem or on implementing a certain mechanism improves the quality of your resulting code, effectively eliminating the need of rewriting or heavily optimizing the code afterwards.
7. Profile, profile, profile
In real time applications (such as games) it can get hard to keep track of all the code executed per update cycle, and it can get even harder to find out which parts of the code are taking up the most CPU cycles. To get an optimal performance a routine should always be able to complete its work in a minimal time complexity (we don't want any redundant cycles) so it's important to provide a profiling system for your application (maybe it's a good idea to immediately integrate one if you're writing an engine) together with an external profiling application (eg. Intel VTune or AMD CodeAnalyst).
8. Go Extreme
For those of you unfamiliar with the term 'Extreme Programming', i'll leave this link: http://en.wikipedia.org/wiki/Extreme_Programming
Although this principle might be a bit over the top, parts of it can be still applied regularly to improve the quality of your code. When working in a team the principle of pair-programming (ie. 2 programmers sitting in front of a single machine, writing code together) can improve code quality drastically and can broaden your view on a specific implementation. Unit testing is a principle which should be used without a question (if you're not using unit testing right now, you should probably start writing a huge amount of test cases), be sure to write both tests intended to succeed and tests intended to fail to make sure everything works as expected. Frequent code refactoring (if possible) can make code easier to manage and will make your life so much easier if you have to do rewrites of certain parts of your codebase.
9. Be aware (and beware) of the end-user
This is targeted more towards people writing middleware solutions (eg. engines, wrappers, etc.). A solid piece of advice I've learned throughout my programming experience is this: Never assume that the person using your project/code knows what he/she is doing
. For a middleware solution this would mean that you should try to use a total style of programming wherever possible so a client will never be able to crash the system through your code. Good examples of possible crashes could be content crashes, where the client would load in an invalid asset or file (eg. file corrupt, not the right format, wrong filepath, etc.) leading the system to crash when trying to load in the asset (content-based crashes should always be regarded as high-priority bugs!).
10. Abandon all deadlines (unless you're published)
Deadlines are evil. They have been known to cripple the greatest of projects and the most awesome of features mercilessly. Keeping this in mind, and the fact that most of you reading this are probably hobbyists and don't have a publisher breathing down your neck eager for a release, it's best not to limit yourself by setting a deadline. Even if you can comfortably work on your project for a sufficient amount of time each week right now, it isn't guaranteed that this will stay the same in the future. Your personal situation might change, your studies might eat up all of your time when in college, your work might become too demanding, you can get health issues, etc. and since you (and your possible teammates) probably aren't getting paid for the work you're doing on the project the prospect of actually making your deadline will fade pretty fast.
Release your project when it's finished, and not a day sooner.
11. Don't hype it until you've got something to hype about
This one's for those of you writing a game:
Having a website about your project can be great, maybe you've even included a developer's blog and a public forum hoping to gather interest from various outsiders (ie. people not familiar with programming themselves). I've seen a trend recently of projects which have been in development for a mere couple of months, with only some poor artwork, a logo, and some techdemo's (which in general really aren't that impressive to outsiders) which have a full blown website (or an attempt at a website) trying to create hype. The harsh truth is that however hyped you are about your project, some poor artwork and nothing 'spectacular' to show will not create any interest, and will look rather amateurish.
Wait until your game project is in such a state that it's actually playable, and where it's as good as content-complete (I'm not talking about a completely polished state yet) so people can see the image you had in your mind all along. It's at this point where you can start creating hype around your game, and expose it to the world. (Of course, showing tech demo's and exciting features to other programmers won't be a problem, since they'll actually know what kind of effort it took to implement it)
12. Think long-term, and keep it flexible
Games, and most of all game-related tools like engines, wrappers, editors, etc. are flexible systems, they should be able to adapt to the current needs of their developer(s) without breaking too much of their internal structure, therefore it is important that they be designed in such a way from the very beginning that these changes and/or additions can be easily performed while keeping at least some form of backwards compatibility to support the rest of the codebase.
Unlike many other software systems, game-related applications have to be able to evolve, certain systems cannot be set in stone from the beginning because of cross- or unforeseen dependencies; the OOP programming paradigm can be of great help here, since only a change of a class interface actually alters the structure of the system, while the actual implementation behind the interface can be altered at will (eg. Irrlicht keeps it interfaces and implementations perfectly separated, creating a clear distinction between structure and implementation).
From this we can draw the conclusion that we should keep in mind that the code written in the initial stages of the development cycle of a game-related project is highly likely to be altered (or in a worst-case scenario rewritten) in the future, and that we should design our code in such a way that these alterations (or rewrites) can be performed with minimal impact.
Beware that while this may sound relatively simple at first, it is a very difficult task to actually pull this off.
I have a lot of other tips to expand this list, but I still have to find a way of how to phrase them in an understandable manner, so you can expect updates soon
Feel free to contribute!