Implementing multiple game modes

Started by
12 comments, last by GameDev.net 17 years, 9 months ago
Hi! CONTEXT: I'm a not so beginner, and I'm designing a new game that is slightly more sofisticated than Pong or Breakout. In a Pong-like environment, 1P or 2P game mode is a matter of setting a boolean attribute of the game (for example, "bool singlePlayer") and checking the value of this attribute in some places of the code. PROBLEM: In this new game, this cannot be made that simple because there will be more than four modes (single player classic, single player time attack, two player time attack etc. etc. etc), and each one will present a very different behaviour. EXAMPLE:

// Pong
void Game::onKeyPress( Key pressedKey ) {
  switch( key ) {
    case KP_8: // Keypad 8
      if ( !singlePlayer ) {
        rightPaddle.moveUp();
      }
      break;
    // ...
  }
}

// New game
void Game::onKeyPress( Key pressedKey ) {
  switch( key ) {
    case KP_8:
      switch( gameMode ) {
        case GM_SINGLEPLAYERCLASSIC:
          // action 1
          break;
        case GM_SINGLEPLAYERTIMEATTACK:
          // action 2
          break;
        case GM_TWOPLAYERCLASSIC:
          // action 3
          break;

        // ... MAINTAINANCE HELL
      }
      break;
    // ...
  }
}

QUESTION: Some options that pops in my mind are to implement the "State" design pattern (used inside a "play" game state, for example), to create a new game state for each mode, or to use of a script language. What approach do you usually follow? What is the best way? Thanks a lot!
Advertisement
depends a bit on how complex the game is and how different the game modes are. using scripts or modules (dll/so) is great if you want a very flexible system that is easy to expand

for a simple game you can use simple states or even simple if statements like this :
if (mode == 1 || mode == 2) {
//do this
}
if (mode == 2 || mode == 3) {
//do this
}
//do this for all modes

this can get really really ugly if you got lots of modes though.
Quote:Original post by Anonymous Poster
depends a bit on how complex the game is and how different the game modes are. using scripts or modules (dll/so) is great if you want a very flexible system that is easy to expand

for a simple game you can use simple states or even simple if statements like this :
if (mode == 1 || mode == 2) {
//do this
}
if (mode == 2 || mode == 3) {
//do this
}
//do this for all modes

this can get really really ugly if you got lots of modes though.


Yes, this is really ugly and I want to avoid it at all costs (as I've said, there will be more than four modes). The game will not be anything near the complexity of Wacraft III or Half Life, and no "mod" support is planned.

Thanks!

using scripts or modules would give you some mod support but is probably the best option even if you don't intend to support mods.

the easiest way is probably to have your engine call functions from a dll or run a script whenever X happens. this is easy if the game modes are very similar (since the number of functions that needs to be in modules or scripts would be limited), if the modes are very different the module system would be more complex (and the game would become highly modable as a side effect)
Quote:Original post by Anonymous Poster
using scripts or modules would give you some mod support but is probably the best option even if you don't intend to support mods.

What do you mean by "modules" and "module system"? The terms are far general...

Quote:the easiest way is probably to have your engine call functions from a dll or run a script whenever X happens. this is easy if the game modes are very similar (since the number of functions that needs to be in modules or scripts would be limited), if the modes are very different the module system would be more complex (and the game would become highly modable as a side effect)

I don't understand why I should keep game modes inside a DLL. Can you elaborate, please?

Thanks!

PS.: Do you really need to reply as an anonymous poster? [wink]
I think the above guy with the DLLs is pulling your leg.
Thats totally unecesarry for a simple game.

ummh, off the top of my head I'd say to look into Function Pointers. and have multiple gamemode functions that can be swapped at startup depending on what mode you choose.
How about an abstract class GameMode and four implementations...

you don't have to use dlls, you could just use normal classes.

something like this for example

class GameMode {protected:    Engine *eHandle;public:    virtual void setEngineHandle(Engine *eHandle) { this->eHandle = eHandle; } //give the "module" a pointer to the engine so that it can affect stuff.    virtual void startGame(); //initialize whatever    virtual void update(float dt); //update gamestate (run each frame or timestep)    virtual void handleEvent(GameEvent e); //handles game events}then create child classes for each gameMode, you could add more functions if you feel like its necessary. such asclass DeathMatchMode : public GameMode {private://whatever variables you need for DMpublic:    void startGame() {        //init the variables etc    }    void update(float dt) {        //do whatever needs to be done here    }    void handleEvent(GameEvent e) {        if (e.getType() == e.SOME_EVENT) {            //do some stuff internally            //run eHandle->someCoolFunction            //etc        }    }}using scripts or dlls instead works in pretty much the same way but has the extra advantage of allowing your users to mod the game. (dlls give the modders more power but will also allow a modder to create a mod containing nasty code) 
Quote:Original post by Zelcious
How about an abstract class GameMode and four implementations...


This works, then with an event system you can tell the engine which class to use. Simple, nothing needs to know about anything else (technically, it can but why?) and is easy to add in more modes later.

Edit: People post as AP because sometimes they're in the industry and don't want to get into arguements with others, etc.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

abstract class could work too
but for something like a gameloop logic where lots of stuff is identical across modes, i think you'd probably end up with way too much overhead

they key here is that he's got a gameloop with multiple areas that change depending on mode, and having a switch or IfThen check at each point is ugly

I think Function Pointers cover that pretty well, they'd let you reduce the switch/IfThen check to a single point at the beggining to assign the pointer values, then at each modechange section rather than do a check just use whatever got assigned...

This topic is closed to new replies.

Advertisement