Game structure

BlitzMax Forums/BlitzMax Programming/Game structure

Paul "Taiphoz"(Posted 2007) [#1]
Iv been thinking about how I structure my games, and how I lay out everything and felt like sharing for that all important suggestion and critic that these forums are so good for.

Main.file - sets GFX mode, loads ini files, and includes all includes, also calls the intro
Media.file - holds all my loading stuff.
Intro.file - handles the fade/in-out of all the intro gfx.
Gui.file - Holds main GUI loop, an all functions used by the gui.
Game.file - Holds main game loop, and all funciton dealing with the game in general.
Player.file - all player type's and functions / methods
Bullet.file - all player and alien bullets and functions / methods
Enemy.file - all enemy functions, methods , types etc.
Powerups.file - all game powerups, functions etc..

thats the basic sorta structure of my projects, I know a few people who put all types, regardless of their content into a type.bb, all functions into functions.bb etx.. Iv not tried that because I am unsure of how clean it would be.

Anyway just wondering which route you guys take. do you split your files to make your project easier to manage or do you just lump it all in one big file.


kronholm(Posted 2007) [#2]
You're gonna need to spread it out WAY more than that if you're dealing with even a small simple game, unless you like having 20+ pages to browse through.

That's just my opinion anyway.


GfK(Posted 2007) [#3]
I work with one main file at first.

As it grows, and I'm done editing specific bits, I chop them out and put them in an include file out of the way.

I don't think you can realistically plan exactly what include files you're going to have from the outset.


Grey Alien(Posted 2007) [#4]
I don't think you need tons of files, it's a pain in the arse too. Find is pretty useful so is the function listing window at the side of the IDE.

Anyway Yavin I can see some stuff missing for a "finished" game e.g. Title screen, loading screen, options screen, high scores screen, credits screen, end game animation, map screen, meta game screen, mini game screen, other sub-screens ;-)

That's why I have a ScreenTypes.bmx which is separate from where I write my actual game screen code.


CS_TBL(Posted 2007) [#5]
I can only comment on that from an app point of view. I spend some time just thinking about what all the smallest parts are. And then I just start creating those, as neutral and independent as possible (makes for good reuse).

I've also decided that I'm lazy and that I'm bad in reading back my own code after a while, so I basically invent a way in which I don't have to read back code in order to understand the whole shebang. The lazy bit refers to designing the code so that I really don't have to think about it anymore after it's completed.

Let's grab your list. I'll add just what I think about it, sometimes not with the indication that something's wrong, just what I would've done.


Main.file no comments
Media.file
What about having all media in an XML file and simply load/process that XML file in the Main file? This way you get rid of zillions of seperate LoadImage and LoadSound commands, makes it less hardwired so to say..
Intro.file
What about making a small movie scripting engine, gfx of course come from that XML file. The only thing this Intro.file could contain is a large Type that plays back a movie, based on a script which is located somewhere in the XML file.
Gui.file I assume this refers to a non-MAXGUI gui then.. no further comments.
Game.file no comments
Player.file no comments
Bullet.file & Powerups.file I combined them as I estimated that these could actually be the same. I'm not sure tho, heck I don't even know what kinda game it is. But I'd consider something like a particle system (ONE particle system) of which the particles can act as bullets or as powerups, this is assuming this powerup is some 'thing' floating in space which you can pickup.. here I assume you're making a shmup :P
Enemy.file Actually I wonder whether I should've combined this one with the previous one. Again depending on the gametime I'd estimate that every 'thing' in your universe is nearly the same:
- a bullet has xyz coords and can hit enemies
- a powerup has xyz coords and you can pick it up
- an enemy as xyz coords and it can kill you
I'd go as far as saying that -detals aside- you could create one big particle system where each particle can fulfill a major role in your game. So rather than 3x some code, perhaps 1x a major lot of code pays of more. The advantage is that you can share some stuff: an enemy that explodes shows some explosion animation. But bullets hitting a wall could also show some (smaller) explosion. So having the same functionality in one major object could have its advantages.

*if* I'd be doing a game I'd prolly spend most of the time on these complex objects in order to make life simpler for me once that object is done. Having less different objects would imply that you'd be using less different parts perhaps.

Until that moment, I sign off with my 2 cents.. :P


jkrankie(Posted 2007) [#6]
I use Blide for editing, and make full use of the folding feature for types/functions/loops etc.

Bullet Candy has a setup.bmx file, a types file, a menu file and a main file.

I've tried separating things into smaller chunks before, but i end up forgetting where things are.

Cheers
Charlie


Paul "Taiphoz"(Posted 2007) [#7]
wow, didnt realise as many of you keep things in so few files.

One of my projects PDS :: http://www.youtube.com/watch?v=JteXMpZ-Xf0

Has about 12 includes.
Include "bmpfont3d.bb"	
Include "hud.bb"
Include "gui.bb"
Include "game.bb"
Include "player.bb"
Include "bullet.bb"
Include "roid.bb"
Include "particle.bb"
Include "keycodes.bb"
Include "gama_flash.bb"
Include "power.bb"
Include "levelout.bb"


Each include only has code relevant to that file for example all asteroids are dealt with in roid.bb, all game bullets are handled in bullet, you get the idea with the rest.

I find it really easy to find stuff like this, it also means I dont need to have like 50 thousand line long project open at one time, I can just open to relevant files for the parts of the game I am working on.

I also like it like that because I try an make my code as reusable as possible, so I can almost just grab bullets.bb and drop it into any project that uses bullets.

Anyone else do it any other ways ? I love finding out what other people do helps improve the way I do things.


FlameDuck(Posted 2007) [#8]
For once, I agree with CS_TBL.

I generally try to have one file per class (unless it's a small helper class). Why? For starters it means that we don't get many conflicts when trying to commit code into our repository. It's also much cleaner to read, and easier to find what you're looking for.

I don't think you need tons of files, it's a pain in the arse too. Find is pretty useful so is the function listing window at the side of the IDE.
I don't see how the shortcomings of the Blitz IDE, is a good reason to advocate werewolf code. Rather matter-of-factly I see it the opposite way around. The implied necessity of writing unmaintainable code in order for the IDE to be marginally useful, should be an indication that the IDE needs to be replaced / upgraded.


CS_TBL(Posted 2007) [#9]
whooo! FD agrees with me! 'Today' will now end up in my portfolio.. :P


Grey Alien(Posted 2007) [#10]
FD: Make this letter with both hands using your index fingers ad thumbs: "W"


computercoder(Posted 2007) [#11]
I agree with CS_TBL and FlameDuck. I break everything down into files. I may have end up with loads of files, but you will know what you did. Granted the IDE is capable of providing a way or two to find your code, but it also has a nifty feature called "Projects". If you "lost" where you put something, if you added a project for your app, then this will easly allow you to "locate" the code you are looking for. Also, I name the file to the name of the class. So, if i build Type MyType, then the file's name is MyType.bmx

In the end, its really up to what you are most comfortable with. I think in a team environment tho, you'd wanna break everything up for the reasons FlameDuck stated.


Paul "Taiphoz"(Posted 2007) [#12]
I like having my projects split over a lot of files that clearly define what's going to be inside of them.

Being a small indie developer, with limited resources, we don't all have access to filein/out systems and version tracking software so having say all functions/types dealing with a game object, like asteroids in my roids.bb file makes it really easy to give a team member 1 file with the relevant bits in it while i or others in the team work on the other files.

Anyway.. I will be sticking to the way I have been doing things for years thanks for all of the feedback.


bradford6(Posted 2007) [#13]
This was a very useful discussion for me.

I do both:
I start with a monolithic, monster file that has everything in it. all types, all functions, etc.

when I encounter my first bug (usually very fast), I split the proggie into files:

ThisType.bmx
ThatType.bmx
MathRoutines.bmx
Funcs.bmx

It does make things alot cleaner.

As for Versioning, I use a very sophisticated and complicated versioning system:

1. my files are named "filename-yymmdd-letter.bmx"
TVector-070421-a.bmx
Tvector-070421-b.bmx etc...

when I make a major change, I save-as to the next letter ("c" for instance) then i just change the import statement:
import "TVector-070421-c.bmx"

2. before I start a new programming day, I "roll-up" all import files to the current day's "a" file
Tvector-070421-g.bmx becomes Tvector-070422-a.bmx
(I never work directly on a. i test it then immedietly save-as "b" so I can easily roll-back to that days "a" file)
and change my import statements accordingly.
this only takes 3 mins.

It's no CVS but it works ok for me. call it "Ghetto-CVS"

EDIT: changed the date format (from Flameduck).


FlameDuck(Posted 2007) [#14]
Being a small indie developer, with limited resources, we don't all have access to filein/out systems and version tracking software
Why not? It's free.

1. my files are named "filename-mmddyy-letter.bmx"
Of course you realize the date format should be "yymmdd" so they get sorted correctly.

this only takes 3 mins.
Your program must not have many imports/files. Updating from Subversion takes 15 seconds. Even checking out a fresh repository (98 Megs'ish in out case) doesn't take 3 minutes.


bradford6(Posted 2007) [#15]
good point about the sorting. has never been an issue

also good point about the number of import files. also not an issue. maybe 10-12 files max. usually about 5.

like I said. it works for me. I will take your advice and swap the date format though. (could not hurt)


Grey Alien(Posted 2007) [#16]
yah I sort all my photos folders and company invoices by yy-mm-dd filename.


FlameDuck(Posted 2007) [#17]
When I rule the world, all other forms of representing time will be outlawed. :o>


bradford6(Posted 2007) [#18]
I have already prepared for that fateful day by changing my date format.


Karja(Posted 2007) [#19]
I find that keeping one class per file also helps with re-usability for new projects. I have a standard directory structure along these lines:

<Game>/game/
<Game>/framework/
<Game>/includes/
<Game>/main.bmx

The game-specific files are all placed...guess where. They, and the includes, need to be changed for a new project. But the "main loop" is essentially the same for all projects, and the framework contains support for generic things like audio/images/fonts/gui/logging/screen setup/particles/window handling/XML loading/etc. It's all re-usable with minimal fuss.

I've also found that it helps to split the game into clearly definable parts. I.e., "splash screen", "title screen", "minigame 1", "credits screen" and so on. I use nifty inheritance for easily plugging in new modules (that I - for some bloody reason - call Events):

Global CurrentEvent:Event

Type Event
Method Update( frames# )
End Method

Method Draw()
End Method

Method Pause()
End Method

Method Resume()
End Method
End Type

The game's main loop then only concerns itself with the CurrentEvent, and when you change module/Event, you simply change the global variable. Could use some better naming conventions, but it works pretty well.