Some time ago I announced my LinkSphere project, with a deadline for alpha-release in mid-to-late May (for the sake of my friend's college music course, as he was doing the integral music).
That Alpha release was completed in early June, but it's clunky and buggy and poorly coded and I'm not particularly happy with it. I certainly don't feel like publishing that particular fruit of my labour.
LinkSphere was very much a learning project for me. When I started, I'd just about got my head around the concepts of OO programming, I'd finished blowing the dust off the mathematics I learnt during my Physics degree and started to polish it up a bit. I felt ready to start a slightly larger project.
Of course, understanding OO concepts and applying that knowledge efficiently are two different things. Coming to C# from a procedural background, the code that gradually built up was full of static methods, arrays of array-indices and long complicated control structure blocks. I did USE inherited classes, polymorphism and the like, it's just that I hadn't really got my head around the idea of fully OO design yet.
Also, the whole thing was unplanned from the start, aside from a few basic mind maps to figure out which order I should code things in.
As I continued to code, two things happened. firstly I built up more and more classes on this hodgepodge patchwork of existing classes and the scale of the project became proportional to the (over-)complexity of it. Secondly, I styarted to understand the ground rules of good OO design better.
Both of those things led the project inexorably to a single point: refactoring hell. Actual progress ground to a halt as I rewrote classes, renamed classes, objects, filenames and namespaces, re-re-re-re-rewrote classes, decided they were better as they'd started out, moved objects between existing projects in the same solution, changed naming conventions over and over again etc etc etc...
In the end, I *just* got the Alpha out in time, but it felt like more of a quick hack than it did a successfully written program, as the structure was still a complete mess (although some semblance of order had finally started to creep in). I haven't touched it since. The latest revision in my svn repo doesn't compile, and it won't until a certain amount of major refactoring has taken place. And then I'll have to iron out the bugs again...
So I learnt some very important lessons with LinkSphere.
1. I learnt what OO really MEANS. I don't need a long switch/case structure checking an entity type if I use polymorphic class inheritance and simply call entity.Foo(Bar bar). I don't need to store all my entity objects in arrays and then refer to them by array position if I just reference the objects themselves directly. I can save function call overheads if I use event delegates proerly, etc etc.
2. A project should be carefully planned beforehand, and to think about how it needs to be structured.
3. Refactoring, while obviously invaluable to a project needs to be approached with care. It should be taken at a slow steps (one thing at a time, thoroughly tested along the way, then commited to svn, rinse, repeat). It's also silly to waste much time worrying about whether a field is called number_of_channels or numberOfChannels. Consistency is nice, and it pays to follow a convention, but it's not worth going through an sizeable project changing everything to follow a given convention when you could actually be doing something productive X-D.
4. Don't take on your friends' deadlines. :-p
Going forward, I built up a GameEngine project when "designing" LinkSphere which I'll continue to build as I code more projects. I've written a couple of messing around projects since and improved on it, and will continue to do so.
I love a good RogueLike, (NetHack is the one thing I'll keep on coming back to) and one of Objarni's texture fonts inspired me a few weeks back. I'm brewing ideas for a game with text-based graphics and a few fun OpenGL effects thrown in.
I haven't started coding anything yet, though. I've been thinking about structure first, jotting things down in idle moments. When I do start, I'll be building a framework of empty classes first, to see what it looks like.
One question, for design reference...
If I have a tree of inherited classes for every item that could exist in the game (eg. ProjectilePistol : ProjectileGun : Gun : Weapon : Item), how might I select one of these classes at random to create on object from?
One solution I thought of was to create a list of "dummy" objects from which one could be selected at random. I suppose with this method, I'd want a system of properties which return lists of all "Weapons", or "ProjectileGuns" etc as well as "Items" , but this starts to feel very messy. Are there any suggestions for a better way to proceed?