Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Good day everyone,

By far the biggest problem that has always dawned on my when programming games is how to structure my code. It just becomes an incredible mess after a while. The reason for that is because I have no idea how different classes should interact with each other. Let's have an example.

Say I have a class Player, a class PlayerInput and a class Map. The player class contains information as to the location of the player, whereas the player input class handles changing that location, but by first making sure it's within a walkable area from the map class. How to structure this?

My usual approach is to pass those components as parameters in the constructors of the parameters that need them, like so:

var map = new Map(); var player = new Player(); var input = new PlayerInput(player, map);

The problem with that is that it quickly gets messy, when you add new components you have to go through your constructors and update them, and it doesn't work well if you have mirroring references:

var physics = new Physics(input); //Oops, doesn't work
var input = new Input(physics);

So, how do you guys usually manage this?

Thanks.

share|improve this question

3 Answers 3

up vote 10 down vote accepted

No lie, architecting games (or any other simulation-style program) is harder than your average business app. When you have lots of different entities that all need to interact then in the code they'll need to, well, interact. Letting them do that in a maintainable way is tricky.

A component pattern can help, but even then figuring out how to wire the components up is non-trivial.

To your specific question:

Say I have a class Player, a class PlayerInput and a class Map. The player class contains information as to the location of the player, whereas the player input class handles changing that location, but by first making sure it's within a walkable area from the map class. How to structure this?

In this case, I generally order the dependencies by how the information flows:

  1. User input comes in. That defines how the player wants to move.
  2. The player's behavior and animation modify that to determine how it can move (things like preventing a jump if you're already in the air).
  3. The collision modifies that to determine how the player does move.

So collision refers to animation which refers to user input. Any of those dependencies can be decoupled by hiding them behind an interface. So, for example, the animation system just needs to know the direction the player wants to go. It doesn't care if that's coming from user input or from something else (like AI, a replay script, or demo mode) so all it needs is an instance of some IPlayerMovement interface.

and it doesn't work well if you have mirroring references:

If you can't avoid a circular reference altogether, you can always break it by introducing an interface:

// Problematic:
class A {
  A(B b) { /* ... */ }
}

// Bad:
class B {
  B(A a) { /* ... */ }
}


// No more cycle:
interface I {
}

class A {
  A(I i) { /* ... */ }
}

// Bad:
class B implements I {
  B(A a) { /* ... */ }
}
share|improve this answer

In your particular example, typically one system is more "important" than the other, or somehow the relationship is not exactly symmetric (one relies on the other more), and that's the opportunity to do something like the following:

var physics = new Physics();
var input = new Input(physics);
physics.attachInput(input);

This is not uncommon; for example in Java's Swing GUI system, the BoxLayout LayoutManager requires knowing about the component that it is laying out; so you must first initialize a component (which assumes a default LayoutManager), and then initialize a BoxLayout passing it that component, and finally do a setLayout of the BoxLayout on the component. It looks like the following (taken from this Java documentation page):

JPanel listPane = new JPanel();
listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
share|improve this answer

Good question. One away around these types of interdependency on subsystems, like input, physic, rendering, etc, is to use the services & singleton pattern together. Each subsystem could be modeled as a service, and the game only has one instance of that service at a time (sub system) that gets created when first called.

At some point though, your going to have a chicken and egg problem if the creation of your subsystems depends on the creation of another subsystem that depends on the creation of the other.

So, avoid the above circular creation problem, and also use static singletons. For example: Input.getInstance(), Physics.getInstance(). Both of those getInstance methods could create and return the subsystem on the first call, but then return the sub system on other calls (singleton pattern). So the first time Input needs the physics sub system it gets it via the singleton service call. Read up on the Gang Of Four Design patterns for more information on those patterns.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.