7
\$\begingroup\$

I'm writing a basic Asteroids implementation as an exercise in learning how to think in entities and components, and most of it is fairly straightforward. But one thing I keep running into is situations where a given system needs a certain entity/component and I know there's only ever one of it. Examples:

  • MovementSystem needs to know the bounds of the World component so it knows when to wrap to the other side of the screen
  • LevelSystem needs to know the GameState component so it knows whether it should create new asteroids
  • InputSystem needs to know the state of the Keyboard component

(etc.)

The ECS I'm using is hand-rolled but conceptually similar to Adam Martin's Entity System RDBMS Beta - Java. What I find myself doing repeatedly for cases like the above is asking the EntityManager for "all" components of the given type and taking the "first" (aka only) one:

World world = entityManager.getAllComponentsOfType(World.class).iterator().next()

This works but seems clunky, and makes the code annoyingly non-obvious. Alternatives I've thought of:

  • make each system loop over 'all' of these components, just as they would any other component type
  • add explicit support for 'singleton' components to the EntityManager
  • don't use components for these things; inject them into the systems some other way, and live with the fact that this makes the design significantly less pure

Is there a typical or well-known solution to this problem?

\$\endgroup\$
14
\$\begingroup\$

Remember to not get carried away with entities and components. It's totally fine to not have your World as a component. If you know for sure there's only going to be one of something, it doesn't make much sense to make it a component. Components are made to be reused in numerous entities, combined with other components.

This doesn't make the game less pure, it makes the code cleaner. Entity systems are just a tool for part of your game, it doesn't need to be all encompassing to be a good system. Use it only where it makes sense to you.

\$\endgroup\$
  • 2
    \$\begingroup\$ Really good answer. Remember at the end of the day, if you don't finish your game, then no one will play it. Do what works to get the job done. \$\endgroup\$ – wes Jun 18 '14 at 18:36
  • 4
    \$\begingroup\$ +1 Just because you have a hammer doesn't mean that everything is a nail =) \$\endgroup\$ – Patrick Hughes Jun 19 '14 at 5:12
1
\$\begingroup\$

As others have said, singletons don't have to be implemented as components. Storing that data directly in the systems or some external singleton class is fine, as long as only systems are accessing it. However, if you really want to keep your design 'pure' (it makes serializing the whole game state much simpler if all the data is in components, for example), consider using a static field or getter in the component directly, e.g. "World.instance".

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

One way of doing that is to implement a messaging system in your application. You can then generate events on the creation of specific components.

MovementSystem can simply register to the event manager for the event WorldComponentCreatedEvent and when you create your world component, the MovementSystem will receive the event which can hold a ref to the world as the event data.

\$\endgroup\$
  • \$\begingroup\$ A messaging system is a good idea for some things, but here these 'singletons' probably shouldn't be components on entities \$\endgroup\$ – ThorinII Jun 18 '14 at 22:27

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.