3
\$\begingroup\$

I am using Artemis ECS. I have the very basics of a game already. I am now trying to determine how to gracefully handle input and to a lesser extent collisions. Some people say with ECSs, everything should be a component and data driven and you shouldn't really use events/messages, or at least avoid them where possible.

Input handling in component based design covers what I am asking as well, but I would understand when and how to raise events, add components or whatever much more fully by using a game we all know (Angry Birds) as an example.

So, for Angry Birds I would have some entities with components (where components are pure data, and an entity is just an id):

  • catapult (position, sprite, state{free, available}?, clickable?, dragable? releasable?)
  • bird (position, velocity, physics{density}, sprite)
  • baddy (position, velocity, physics {density}, sprite, health)
  • box (position, velocity, physics{density}, sprite, health)

And the following systems to start with:

  • SpriteSystem (has all entities with sprite component)
  • PhysicsSystem (has all entities with position, velocity and physics components)
  • HealthSystem (has all entities with health component)
  • InputSystem (knows about keyboard/mouse events such as clicked, dragged, released, key down etc, not sure what entities should have...)

How would the InputSystem interact with other Systems to say the catapult was clicked, and if there are birds left, and none are in flight, allow it to be dragged and release/fire the bird.

Would the InputSystem modify ClickableComponent, DragableComponent and ReleasableComponents on the catapult entity? Or, should it raise some sort of Click, Drag and Release Events? What System would listen for the component changes/events? A CatapultSystem perhaps?

When the PhysicsSystem notices a collision between the bird and a baddy, should it create a Collision event, that I guess the HealthSystem would listen for? Or again, should it modify a collision Component already on the Entity?

Collision and click components would need to be cleared every game loop if I took the component approach (seems a bit naff...)

\$\endgroup\$

1 Answer 1

7
\$\begingroup\$

The entity component system (ECS) is great. There are plenty of misunderstandings about it though. For example, it's perfectly fine to use event/messages in an ECS. People often think you're supposed to completely avoid inheritance too. Also not true. The ECS methodology is just a strategy for avoiding issues that come with a large hierarchy of inheritance. It's a great system, and fun to use. But you should only follow it if it makes sense and is the easiest method for you to use.

Make things a lot easier on yourself and create a catapult control component, along with that CatapultSystem. This system handles all the input and calculations for launching a bird. The catapult component stores the launch angle, and force. With this pair you can get rid of clickable, dragable and releaseable.

All systems should have access to the current input. This can be via a global static class that's cleared each frame, or with messages.

Don't forget that birds respond to clicks too. It might be easiest to have a birdInFlight property on the catapult component that responds to clicks and sends a message to the current bird to trigger its special ability.

Collisions are handled by the physics system. And it can send messages to the health system to appropriately deduct health from baddies/birds and destroy the objects collided with.

It sounds like for the most part you're on the right track. Your ideas are good enough to move forward with, and that's exactly what you should do. Move forward with your ideas until you find an actual problem. If you're not sure, just pick a route to go with and try it out. You're only going to learn for sure if it was the right way to go or not, and it may open up new possibilities you hadn't thought of before.

\$\endgroup\$
5
  • \$\begingroup\$ Thanks. I guess I have done too much reading and have confused myself. Any steer in the right direction is much appreciated. \$\endgroup\$
    – Simon
    Commented Sep 10, 2013 at 14:58
  • \$\begingroup\$ If we could just play on the birdInFlight example you gave a bit. I guess the bird would have a component like specialPower, which would have some sort of key on it like SPLIT_INTO_THREE. The CatapultSystem registers itself for all play input events/messages. Would the flow of events be something like: bird is flung, at that point when the CatapultSystem gets 'click' messages it creates a EnableSpecialPower message for the birdInFlight entity that a BirdSystem would listen for. Bird System would then create 3 new Entities based on the specialPower? \$\endgroup\$
    – Simon
    Commented Sep 10, 2013 at 15:14
  • \$\begingroup\$ Sounds pretty reasonable to me. Like I said, you're asking the right questions. So you're on the right track. I think you just have a little case of design indecision. Go with your gut, I think you'll do fine. \$\endgroup\$
    – House
    Commented Sep 10, 2013 at 15:31
  • \$\begingroup\$ Yes I do have design indecision! I am an experienced developer but not an experienced game developer... I just don't want to go down some dark horribly wrong path and wanted to check how/when others are differentiating between creating events and when they are adding another component to an entity at runtime. \$\endgroup\$
    – Simon
    Commented Sep 10, 2013 at 15:43
  • 2
    \$\begingroup\$ Yep, it's a common thing. Don't worry too much, there's always the refactor. You're not going to get it right every time, but making mistakes is an important part of learning the right way to do things. Good luck! \$\endgroup\$
    – House
    Commented Sep 10, 2013 at 15:51

You must log in to answer this question.

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