SHUT UP ABOUT THE SHADOWS ALREADY!
Incase you missed it, I was pretty productive today (compared to other days anyway; see last entry.) So, I decided to spend a little time on my side project - Project Asrion. I coded up a little test terrain system and its pretty nice if I do say so myself. It requires several different files for a single map, but it eases stuff and allows for a pretty nifty effect. At the moment I have the system split up like so:
bool Can Enter
bool Can Exit
int Tiles Per Row
int Tile Width
int Tile Height
Tileset* Current Tileset
int Column Count
int Row Count
And there will be a Map class. This setup will allow me to instantaneously switch from one tileset to another on any given map and also to reuse my the same terrain (but the first was the reason I separated it like so.) This will allow me to have a variable like Season for example. And when the player is entering, if Season == Winter, I can set the tileset to winter and boom, insta-snow. If it turns out to not be that useable I can always concatenate Tileset and Terrain into a single file.
Anyway, its time for a screenshot of Project Asrion:
Not too shabby for about 30 minutes worth of work [grin].
(On a side note, this is the tile-based engine that I'll be developing in my article.)
Everything below is my opinion not a fact, rule, or standard
Time for another discussion, yay!!! This time I'm going to discuss making a code base. Your code base should consist of all the little tools that are either required or make life a lot simpler. For instance, take the above terrain system. Before it would have taken me around an hour and a half to code it because of tedious terrain code, vertices, device creation, etc. But, since I have all of that in my code base, I was able to get a stable tile engine that will render any size map from a file done in about 30 minutes.
Q - What should be in the code base?
A - Well, I follow a simple rule to dertermine what goes in my code base: If it doesn't change at all or very little, then it goes it. Timing system, random number generators, and resource manager are some good examples that follow the rule. Wow, I almost forgot the most important - logging. A simple loggging system will help immensely, but a nice in-depth logging system will save your life. I personally have an HTML log system ( which I'm going to be releasing soon (free of charge of course)) which allows me to color different messages differently (i.e. warnings are yellow and errors are red.) But, a debug log should be the first thing that is put into your code base, even if its just a simple function that outputs a string to a text file.
Q - What about stuff that gets updated every now and then (APIs for example)?
A - This is where a nice API independant system comes in handy. Even if you only plan to stick with one API or the other. If you have the independant interface available in your code base, all that is required is that you make a new library when the API gets updated.
Q - Shouldn't I have some sort of string or container class in my code base?
A - If you're reading this because you don't know what you should have in your code base then no, just use STL. If you already are experienced then why the hell are you reading this? Just kidding, if you're already experienced then you should know that sometimes a custom container/string class is better than STL, but on the norm STL is the way to go.
Q - What about game specific stuff like maps and such?
A - Game specific stuff follows a much stricter rule. I only add game specific stuff that isn't specific to a genre or dimension (timers for instance.) If you have game specific code that doesn't change a lot, put it in a game library under an uber-cool name.
If you plan on sharing your codebase (or using it in a library that you plan on sharing), try to steer clear of macros and such. IMHO its pretty rude to assume that someone won't use the name UBER_COOL_MACRO_THINGY. If you do use them, put some sort of suffix on it (for example, if I put any macros in DragonForge Technology, they'll use the suffix DFT_.)
The API independant interface setup was just a suggestion. I personally don't use it and will just redo/modify my Graphics class for later releases of DirectX.
Wrapping is your friend, but forwarding is not. Again, this is just my opinion, but adding functions to your class like the following is a sign of lazyness/unwillingness to type which is bad:
void SetTexture(int nStage, IDirect3DTexture9* pTexture)
Instead you should already have a texture wrapper and you could wrap the functionality of this function like so:
void SetTexture(int nStage, GfxTexture* pTexture)
if(m_pTextures[nStage] != 0)
if(m_pTextures[nStage]->GetFilename() == pTexture->GetFilename())
return; // this texture is already set
m_pTextures[nStage] = pTexture;
This function has more purpose than saving the user from typing GetComPtr(), it stops the user from setting a texture into the same stage over and over again.
Follow a strict naming convention. For example, if I wrap a COM interface, the main COM pointer gets the name m_pComPtr (i.e. my Texture class has IDirect3DTexture9* m_pComPtr;). Having several naming conventions or even just 2 can be very annoying and hard to follow.
As an extension to the above, code the way that YOU like and the way YOU'RE comfortable with. If you like suffixing your classes with the letter C, do it. Don't listen to the people that say 'drop the C, its redundant, blah blah.' If its how you like to code, then do it since they can always use someone elses or make their own. Just remember you can't make every one happy, there will be someone who complains about your naming convention or the fact that you use hungarian notation, etc, just ignore them (unless of course its your boss, team lead, or anybody else that could fire your ass, because you should DEFINITELY listen to them.)