2
\$\begingroup\$

I am developing a top down 'thing' in SFML and C++ and was wondering about how best to handle so called Entities in my game.

An entity, for example is defined by me as an object in-game, such as a door to a house, that can be interacted with, can be animated, can act on user input, can be affected by physics etc.

I was thinking of handling this system by a series of classes and subclasses.

For example, the base class of Entity would contain the methods Render, Update, HandleInput and such as these are the most basic methods that all entities will contain. Variables of the main class could include isVisible, isPhysical, drawDepth and so on.

A new class for MapObject would use inheritance to take the methods from Entity and may also add other methods and variables such as tileTexture, tileHeight and tileWidth.

Abstracting(?) from that again could be the DoorTile class which would handle the item specific level of input handling and interaction.

Is this a valid way to handle objects in-game? Are there and glaring errors?(Bear in mind I've been awake for many many hours :p)

Sorry if this is somewhat long-winded, I wanted to be specific as to how my proposed system would work.

\$\endgroup\$

3 Answers 3

9
\$\begingroup\$

The real problem with your approach is class proliferation. See Mick West's seminal article on why CBEs (component-based entities) are better. Also see Wikipedia. A quick example for a game is as follows:

Given a space shooter where you can pick up combinations of different equipment and powerups, consider the following:

  • You pick up the Ooze Cannon (weapon slot).
  • You pick up the Ablative Armour (armour slot).
  • You purchase the Ion Emission Drive (engine slot).
  • You lose your starting Newbie Radar in combat (radar slot).
  • You pick up the Garbroozian Nat Swaffler (miscellaneous slot).
  • You swap your Ooze Cannon for a Laser Cannon.

All of these slots are defined "roles" for your game's ships. In order to reliably perform key operations on each of these components (eg. weapon.fire(), radar.ping(), etc.) you have have a known method in a known place, to call. Through inheritance, this looks something like player.fireWeapon() or player.pingRadar(). So far, so good.

Now every time you add (or remove) a component, you then have to extend (or de-extend!) the player entity class. In order to do this, you need a proliferation of different combinations, eg. OozeCannonAblativeArmourIonEmmisionDriveShip, vs. LaserCannonAblativeArmourIonEmissionDriveShip, to modify implementation of just one component(!).

With object composition instead of inheritance for such cases, you instead have one generic entity class that carries (usually public) data members for each role/slot. So you have weaponSlot, engineSlot, and so on. Then you can just call player.weapon.fire(), (you could wrap this as player.fireWeapon() -- which will call this.weapon.fire(), or do nothing if the weapon slot is empty).

Only use inheritance where you know there will be no such proliferation. A good example of where to use inheritance in games is utility classes, for example a RemoteConnection class that could take one of many forms, eg. TCPConnection, SerialPortConnection.

\$\endgroup\$
0
3
\$\begingroup\$

Highly recommended: a component-based system. There's a lot more information available online. I personally think it's a much better approach for games.

\$\endgroup\$
1
\$\begingroup\$

This is a valid way to handle entities. That is, it would function. And this is the traditional way it's done in many engines.

That doesn't mean it is good.

Inheritance-based entity systems tend towards very fat interfaces. You often have a base class that has all of the properties of the derived classes, even though some of them don't make sense on some objects.

Consider a containment-based system. For example, entities aren't renderable; they instead store renderable objects. The rendering system would have the list of objects, and all entities would do is maintain the position of those renderable objects. Renderable objects would also be owned by the render system, so they will get rendered when the render system is rendered.

Similarly, the relationship between entities and AI should be that the entity stores an AI. AI's control entities. An entity should not handle "input"; the player should have an AI, which during the AI update is given input. And the player's AI would interpret this input and control the player entity.

Just something to consider.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Something worth mentioning is that implementing JD's original design might be just fine if it's a simple project. Sometimes its nice to grow into something so you understand why it's better. Depends on what the goal is I guess. \$\endgroup\$
    – Raptormeat
    Oct 2, 2011 at 6:13
  • 1
    \$\begingroup\$ I agree that a simple implementation for a simple game is not bad. But he is already building quite a hierarchy. It won't be long till he reaches inheritance-hell. Plus, I don't believe component-based systems are that hard to grasp. There are many was to architect one, from the most basic ones (components = data + behavior) to more complex ones (components + systems). \$\endgroup\$
    – pek
    Oct 3, 2011 at 3:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .