3
\$\begingroup\$

I'm a new indie game developer, and I've made a few games, but often times when coding I wonder "Is this the way most people do it? Am I doing it wrong?" because I'd like to become a game developer some day, and I really want to get rid of bad practices in time.

The way I'm doing it right now is like this:

#include <some libraries>
#include "Some classes"

    int main()
    {
      Class1 a;
      Class2 b;
      Class3 c;

      a.init();
      b.init();
      c.init();

      // game logic;
    }

Now as I see the game grow, I have more and more classes to initialize and create instances of. This is clean but I'm not sure if this is standard practice. Is this a regular way of creating instances of your game classes or is there a cleaner and more efficient way to do it?

\$\endgroup\$

4 Answers 4

5
\$\begingroup\$

Correct me if I'm wrong, but what I'm getting from the question is that you're declaring each object within the game world as a new variable. Generally when a game grows it will move away from the code and towards outside files for level creation etc. Once this happens you can't continue creating new instances of classes within the game itself.

The best way (that I've found) to manage a lot of this stuff is to use Lists. Abstract classes (as mentioned in Mihai's answer) also tend to come in handy when doing this. If you're going to have 50 enemies in a level it's a lot more viable to say "Update all enemies" or "For each enemy..." than to write exhaustive lines in that way.

In your example you could have Class1, Class2, Class3 be subclasses of GameObject, then have something like this:

List<GameObject> objects = new List<GameObject>();
objects.add(new Class1());
objects.add(new Class2());
objects.add(new Class3());

for(GameObject o in objects){
  o.init();
}

// game logic;

I don't often use C/C++ so you may have to look into how lists work in the language you're using.

\$\endgroup\$
1
  • \$\begingroup\$ In all of programming in general, we count 0, 1, n. If you count to n, consider using a List (or Array or Map or whatever collection type is appropriate for how you need to use the data). Of course, this only applies if there is some operation that you want to do to each of those n objects, or have them sorted some specific way so that you can look them up quickly according to some criteria. \$\endgroup\$
    – jyoungdev
    Dec 18, 2012 at 14:05
1
\$\begingroup\$

The Best practice is to keep things as SIMPLE as possible . so if this is enough for you it's ok .

But when will make a bigger game with hundreds or thounds of objects this will no longer be manageable.

So what you will do is create a GameObject class and then derive other classes from it with different functionality . You will put all these instances in an array of GameObjects like this

std::vector<GameObjects*> m_objects;

Then you will have a GameLevel class which will manage your objects

In a GameLevel::Init methods you will iterate over your objects and init them then you will do the same with your Update and Render methods

Then after many years and many games ship your hierachy will become very deep You will have derived many objects from from many other objects everything will be tightly coupled and all your code will be Spaghetti Code

And then you will look into Component Systems and you will check out this https://stackoverflow.com/questions/1901251/component-based-game-engine-design and this Component-based game object systems in practice

\$\endgroup\$
1
  • 3
    \$\begingroup\$ I voted this down because of the lack of backing and rationale for any of the suggestions, all of which could lead to bad practices because none of them are silver bullets. \$\endgroup\$
    – user1430
    Dec 16, 2012 at 19:20
0
\$\begingroup\$

I'm not 100% sure what your asking, is it the having to call the init method or something else? Your class constructor should do most of your init logic, unless you need to the object constructed before calling init, though this only happens in a few situations. So if you just left it as

Class1 a;

That would call the default constructor for your class. So place all the logic for your init function in there.

EDIT

Generally your main will have maybe an instance of GameWorld class which lets say manages all the entities in the world. It may also have an instance of level and inside level we have instances of blocks that make up the level or something like that.

The main point there, is that we tend to have composite classes which are made of smaller classes to make up more complex classes.

\$\endgroup\$
1
  • \$\begingroup\$ Initializing of classes is not my problem, what I'm asking is, if it's normal to just make a huge list where I create an instance of a class, one by one. This can get really big in video games so I was just wondering if I was doing it right, and if there was a better method of creating the class instances which you need to use. Sorry if the question is a bit vague \$\endgroup\$
    – Bugster
    Dec 16, 2012 at 16:59
0
\$\begingroup\$

It really boils down to what these classes represent.

If these classes represent systems of your game such as Rendering or Sound, you can easily get by with this type of initialization structure. Even as you start adding systems to your game like networking, it's acceptable to simply leave these as member variables of a framework-like class because you often need to refer to these systems directly to use their exposed interface API and placing them into a list only adds unnecessary complexity. Nothing would stop you from having them derive from a common ISystem class though and keeping them in a list, but having specific references would minimize that list's lookup time when they were needed at the cost of a few bytes of memory.

If these classes represent game objects, or what I call entities, then generally there is a core system that is responsible for managing these instances. You simply ask this system to create you an instance, it wires it up and manages the memory and simply hands you back a reference to work with. For example:

// Game Object System Interface
struct IGameObjectSystem {
  // Create game object with a specified name
  GameObject* Create(const std::string& name="");
  // Create game object based on a template type with a given name
  GameObject* Create(unsigned int templateTypeId, const std::string& name="");
  // Create game object with given parameter list
  GameObject* Create(ParameterList& params);
  // Deallocates a game object
  void Destroy(GameObject* object);
};

class GameObjectSystem : public IGameObjectSystem {
public:
  /* implement the IGameObjectSystem here */
private:
  std::vector<GameObject*> mObjects; // list of objects in use
  static unsigned int mNextObjectId; // next object id to assign
};

The benefit is that now you can create as many game objects as you want. You could go as far as creating Factory classes for all the various types of game objects in your game and then this object system can use those factories to create a specific type of game object. You've centralized the creation/destruction of game objects and abstracted away storing them in a list too.

But keep in mind this is only one way to manage Game Objects.

As Mihai points out, Component-based design often has varying designs around game objects. Some prefer to have a GameObject class like the above examples which has a collection of components that make up it's feature-set while other implementations prefer to treat game objects as simple unsigned int values that reference specific indexes in a well designed system of arrays to quick, constant time lookups and retrieval.

The great part of all this is there is no real "right" way that works. There are some best practices but even those are going to vary from implementation to implementation all depending upon the framework being used - is it built in-house or licensed, etc. But don't be afraid to go with what works for now and improve upon it later as you get a better idea of how things all come together.

\$\endgroup\$

You must log in to answer this question.

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