1
\$\begingroup\$

First, I would like to say that I have no experience with this and am still getting my head around OOP, so if something is really obvious, just point it out :)

I am designing a game and I am not sure of the best OOP design patten to use or if I am going on the right track. I have entities, but I don't know the best way of storing them. I am going to put them in a vector based on what I have seen on GDSE, but am not sure where to put that in my games code. I thought of putting them in a singleton manager class, but have read up on singletons and don't think that it would be wise to use them.

Or could I store entities in a world object? Like here ?

Is a singleton entity manager class fine in this case, or can you point me in the right direction for a different way of managing them.

EDIT: Oops.Even though I did multiple searches only now have I seen this (http://tinyurl.com/kv963nu) Although this seems to tell me to use global variables or singletons..

\$\endgroup\$
5
\$\begingroup\$

A singleton works. A global works. I'll stand by that statement. I don't think they're the best solution for this particular case, though.

Yes, you can put all your GameObject instances into a World of some kind. The World then likely needs to be managed by an object if you plan to have more than one of them, e.g. some kind of WorldManager. This manager might itself by managed along with another collection of managers in some kind of Engine or service locator or the like. That object can be created on the stack by main().

You want to avoid too many layers of cruft but you don't want to remove layers that you need to stay flexible.

Example:

class GameObject final
{
  World& _world;
  vector<unique_ptr<Component>> _components;

public:
  GameObject(World& world) : _world(world) {}

  World& GetWorld() { return _world; }
};

class World final
{
  vector<unique_ptr<GameObject>> _gameObjects;

public:
  void Spawn()
  {
    _gameObjects.emplace_back(make_unique<GameObject>(*this));
  }
};

class WorldManager final
{
  vector<unique_ptr<World>> _worlds;
};

int main()
{
  WorldManager worldMgr;

  // initialization code

  // main loop

  // cleanup code
}

The tricky part comes in to other managers that some components might need access to. There's lots of contortions you can put yourself through so e.g. your PlaySoundOnEventComponent can actually play a sound via an AudioMgr constructed in main(). A global might end up being a far easier and more efficient option for things like that, though.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the response, I have seen a few of your answers on the topic here before :) Alright, I could use managers, but I am not sure if that is the best way to go. Might Entity Component system be better? And if I used that, where could I store my vectors? If nothing else comes up I might use that, thanks. I am afk for 1hr so I will be back then to see if somthing might be better. Thanks :) \$\endgroup\$ – 5Mixer Oct 25 '14 at 5:57
  • 1
    \$\begingroup\$ I don't see a new question that hasn't already been asked. What part are you still stuck on? If you're looking for the "best" way, you're out of luck; there never has been and never will be a "best" way to structure code. \$\endgroup\$ – Sean Middleditch Oct 25 '14 at 6:06
  • \$\begingroup\$ I'll probably use managers then, thanks for your time :) \$\endgroup\$ – 5Mixer Oct 25 '14 at 10:31
  • 1
    \$\begingroup\$ Entity component systems are a solution to an OOP design problem you won't experience until you've hacked away at traditional OOP designs for a while. Keeping in mind that you can use OOP to build ECS and that they are not mutually exclusive I'd recommend getting your head around OOP first. \$\endgroup\$ – Patrick Hughes Oct 25 '14 at 14:47
  • 1
    \$\begingroup\$ @Mixerman123: you can. The service locator could be global or an object you pass in to your managers so they can use it. There's pros and cons to every approach; pick whichever seems to make the most sense to you or which seems easiest. It sounds like you're suffering from design paralysis. Just pick something and go. If you end up disliking it, you can always refactor later (though be wary of ending up in a loop of constantly refactoring old code that doesn't strictly need it instead of writing necessary new code). \$\endgroup\$ – Sean Middleditch Oct 26 '14 at 3:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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