BAsic Game State Design

Take a look at this simple state diagram.







Most games are going to follow a state similar to this.



My question is about how best to organize the peices / parts and handle interaction.



I start by assuming that each ‘screen’ is going to be a set of nodes, with their individual means of interacting (input handlers). So I have my main game loop. The first interaction starts with the main menu. Based on user input I want to switch out the nodes in the root tree from the main menu scene to some other scene. It doesn’t seem good practice that the same functionality that contains the main game loop is also responsible for switching out which scene is in the rendering tree. That would mean that it’s dependant upon capturing all the input too. For every scene. However, how do scenes within the game get to the root node if that is owned by the same functionality as the main game loop. I would think that input listeners for each scene should be contained within the part that creates the scene in the first place.



Anyhow, I’d just like to find out how other people have come up with solutions along these lines. The tutorials and demos are small enough and usually only contain one scene so they aren’t much help.



I’m really trying to get away from som 10000 line main app class :).

Here’s one solution heavily inspired by this thread but that also includes some ideas of my own. ('Cause I actually developed a very similar system independently. Strange coincidence, eh?)



public class Game {

    private interface State {
        public void start();
        public void update();
        public void render();
        public void shutdown();
    }
   
    private State defaultState = MAIN_MENU_STATE;
    private State currentState;
   
    public void run() {
        while (running) {
            //...generic main loop code stuff
           
            currentState.update();
            currentState.render();
        }
    }
   
    public void switchToState(State s) {}
    public void delegateToState(State s) {}
    public void shutdownCurrentState() {} //...possible
}



Consider each screen as a separate game State. Every State is responsible for handling input, updating and rendering itself. It is also responsible for determining to which State the control flows.

Transferring control to a new State can be handled in two ways:
Delegation to a new State pushes the current state on to the stack and control is passed to the new State. When the new State is exited, the previous State on the stack reassumes control. Useful for a linear series of options dialogs or menus, or even pushing a "Paused" screen over top of the game window.
Switching to a new State passes control to the new State without pushing the current State on to the stack. Control will revert to the default State if no other State is specified on shutdown. Useful for transitions to very different states (mission completion statistics -> new mission description).

A note on the default State: When a State is exited that doesn't explicitly specify a new state to assume control, the default State takes control.

Note that this system may require some hard-coding of the State transitions, but they could be easily extenalized into a scripting system or configuration file.

I like how you’ve separated out stuff. Where do you keep your DisplayState, in some sort of singleton main application that all states have access to?

Yeah, rendering would be managed by a central Game class. Each State would contain its own root node and would render itself by calling Game.renderNode(rootnode)*. This allows for much greater flexibility in both how a State renders itself and how the Game chooses to manage that. It leaves the possibility open for doing things like rendering both the current State and the previous State on the stack.


  • I occasionally prefer simple static access over singeltons when I’m looking for syntactic, err, short-ness. :slight_smile:

I would like to request that that if you make any mager moderations to jme let the cerent interface still work. I would be very upset if my game no longer compiled. :’(

Don’t worry, they are discussing their game design, not jME itself.

Any chance some of this control layer is abstract enough to make it into jME?



I have one game project (java port of Imperial Wars) that would definitely require it, although my RPG game is less likely to do so.



I’m lazy and I hate reinventing the wheel.



-Mike