A Game's Structure

Started by
5 comments, last by Digivance 11 years, 4 months ago

Hello, I have been programming for some time and I created a text based RPG game and moved on after a while to create a 2D RPG game. I was fully capable of making it but it was the biggest mess of code I have ever seen and I had the worse method of progression through the story. All in all, I know how to actually program but how exactly would I structure a game.

Alot of people say things like Check for collision, player detection, rendering, but how exactly would that work with a 2D RPG or a RPG in general? Im gonna start from scratch again and by that I mean a text based RPG but I want to find a suitable way of creating a structure for smooth progression through the game and that way I wont end up with a huge mess of code. Any help would be appreciated

Advertisement

What kind of problems did you run into, specifically? There's a lot of different aspects to organization, so if you can address specific problems that arose one-by-one we can talk about ways of dealing with those issues.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

Well for example I had one big while loop for the game, and inside the loop there would be a switch, the different numbers would each mean a room but it started getting too complicated this is an example:


while(!done)
{
switch(state)
{
case 0:
menu();
break;
case 1:
Game_Start();
case 2:
About();
case 3:
Close();
}
}

This was basically my while loop and this is an example of Game_Start():


Game_Start()
{
switch(location)
{
case 1:
town;
break;
case 2:
inn;
break;
case 3:
quest;
break;
}
}

Then my quest() would be the same thing as Game_Start() just a switch statements and it ended up with every single function having a switch statement and there was no organization at all. The only thing I had for organization was all of the player and monster data in separate classes. Basically I dont know how to create a organized framework or engine for the game.

Ah, I sort of expected that this would be the first thing you asked about. What you're looking for is a "state manager". Rather than just using one huge loop you create 'states' or 'scenes' (depending who you talk to - they're the same thing) that get plugged into the main loop. The logic for the section you're in is inside the state/scene.

I think L.Spiro wrote a nice article about it... Hang on a sec...

Yeah, here we go. I was looking over this while I was fiddling with my scene manager a while ago.

http://lspiroengine.com/?p=351

As for different stages/levels you can break them into data units (the map and resources, etc required for that stage) and then have your map state/scene load the data unit, run with that data until you move to another one, then just unload the current one and load the new one.

This forum formatting bug is killing me... -.-
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

Assuming the above is a menu.

How about having a MenuItem object.

Each selection inherits from MenuItem.

Then you put the menu-items in a list (which language are you using?).

Then a single function which can display and select a list of MenuItems.

That way you don't need a million switch/cases, but just one function.

My Oculus Rift Game: RaiderV

My Android VR games: Time-Rider& Dozer Driver

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown & Killer Bees

The link Khatharr posted looks pretty good. I actually implemented something like this in a game I am working on right now.

What I have is a Scene class.
class Scene
{
void Draw()
void Update(double dt)
}

Then for your game loop all you do is this.
while (!done)
{
    double dt = TimeSinceLastFrame
    activeScene.update(dt)
    activeScene.draw()

    // frame rate control here
}

Then, when you want to jump between scenes simply change the activeScene. Every scene, such as a menu a level or cutscene, is a subclass of scene and has its own draw and update code. This flexibility makes it easy to create scenes that handle transitiong or loading screens. You can also easily add new scenes without having to track down and update a any switch statements that relate the deciding what scene is active. In fact, any time you find yourself using a switch statement, consider creating a class and using Polymorphism to control the behavior. If any of this seems confusing read up on polymorphism. It is a powerfull tool that will make your code much more manageable.
My current game project Platform RPG

Object oriented programming, static / singleton managers and factories. They are fairly advanced topics and can lead to a very complex learning process but they will lead you to the best and most expandable way of coding. I would highly recommend looking into the XNA Framework for some easy examples, maybe work through some of the Flat Red Ball engine tutorials to see some more of this style of code in action.

The basic idea is that you would write classes that represent logical "objects" and systems of your game / engine. Lets take a sprite for example (since you will undoubtedly be needing them in your game) The following is not real code but used to give a bit of an example.

class Sprite()

{

var image;

var position;

var collisionRect;

...

}

We see the same basic idea's you've probably seen before. A sprite is an object that represents a character or an interactive map object. It contains variables and methods that pertain to that particular sprite. You can extend, or derive from this Sprite class to make more advanced Sprite objects later on and when all is said and done you might have many different Sprite objects that handle different kinds of in game entities (characters, switches, traps, vehicles).

Now the next thing you would want to think of is a "Manager" object that could help you handle all of the sprites you will be using. This manager object would be a static or a singleton object, that is to say that by some means there is only one instance of this object in memory. This class IS the SpriteManager.

class SpriteManager

{

vector mSpriteList;

public Sprite loadSprite("name")

{

// Loads a sprite image, creates a "Sprite" class in the sprite list and returns

// a reference to that sprite.

}

public Sprite getSprite("name") { } // Returns the reference to a sprite in the list by it's name

....

}

There we go, you start to see why this would be helpful. Basically you want to keep all of your Sprites inside the master SpriteList. Your SpriteManager gives you a means of loading and unloading sprites to that list. The SpriteManager gives you functions you can use to get a reference to one of those sprites whenever you need it. This will help minimize memory overhead and waste later on.

Besides that, also start getting familiar with callbacks and event programming as well. This will help to easily arrange your code into the correct objects but still trigger it during certain dynamic conditions. This is a bit harder to explain in simple terms but still convey the importance. Lets say for example our Sprite object has a wakeUp() function. This function defines what a particular sprite does when the character "wakes up" in the morning. You may be monitoring 1,000 Sprites in a certain map, and instead of writing a loop that at 9am every morning it calls all of the characters wakeUp and each character decides if they want to participate in the wake up you'd rather tell your TimeManager who to wake up at 9am. So when you are constructing your characters (reading them from a file or whatever) you would also add the characters to the wake up list as they are created. To do this you could add a callback handler to the TimeManager's wakeUpList. When the TimeManager hits 9am it loops through the 30 names in it's wakeUpList and calls those sprites wakeUp() functions.

Granted that's a bit of a poor example as there are much better ways of doing something like that but hopefully it gives you an idea of why callbacks are handy. It allows you to manage a list of functions to call under a certain condition instead of coding the functions to check if they should run. This will start leading to more intuitive AI coding when the time comes.

Dan Mayor

Professional Programmer & Hobbyist Game Developer

Seeking team for indie development opportunities, see my classifieds post

This topic is closed to new replies.

Advertisement