Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

After asking two questions on Entity Systems (1, 2), and reading some articles on them, I think that I understand them much better than before.

But, I still have some uncertainties, and mainly they are about building a Particle Emitter, an Input system, and a Camera. I obviously still have some problems understanding Entity Systems, and they might apply to a whole other range of objects, but I chose these three because they are very different concepts and should cover a pretty big ground, and help me understand Entity Systems and how to handle problems like these myself, as they come along.

I am building an engine in Javascript, and I've implemented most of the core features, which include: input handling, flexible animation system, particle emitter, math classes and functions, scene handling, a camera and a render, and a whole bunch of other things that engines usually support.

Then, I read Byte56's answer that got me interested into making the engine into an Entity System one. It would still remain an HTML5 game engine with the basic Scene philosophy, but it should support dynamic creation of entities from components.

These are some of the definitions from the previous questions, updated:

An Entity is an identifier. It doesn't have any data, it's not an object, it's a simple id that represents an index in the Scene's list of all entities (which I actually plan to implement as a component matrix).

A Component is a data holder, but with methods that can operate on that data. The best example is a Vector2D, or a "Position" component. It has data: x and y, but also some methods that make operating on the data a bit easier: add(), normalize(), and so on.

A System is something that can operate on a set of entities that meet the certain requirements, usually they (the entities) need to have a specified (by the system itself) set of components to be operated upon. The system is the "logic" part, the "algorithm" part, all the functionality supplied by components is purely for easier data management.

The problem that I have now is fitting my old engine concept into this new programming paradigm.


Lets start with the simplest one, a Camera.

The camera has a position property (Vector2D), a rotation property and some methods for centering it around a point. Each frame, it is fed to a renderer, along with a scene, and all the objects are translated according to it's position. Then the scene is rendered.

How could I represent this kind of an object in an Entity System? Would the camera be an entity or simply a component? A combination (see my answer)?


Another issues that is bothering me is implementing a Particle Emitter. For what exactly I mean by that, you can check out my video of it: http://youtu.be/BObargIMQsE. The problem I have with this is, again, what should be what. I'm pretty sure that particles themselves shouldn't be entities, as I want to support 10k+ of them, and creating that much entities would be a heavy blow on my performance, I believe. Or maybe not? Depends on the implementation, but anyone with experience: please, do answer.


The last bit I wan't to talk about, which is also bugging me the most, is how input should be handled. In my current version of the engine, there is a class called Input. It's a handler that subscribes to browser's events, such as keypresses, and mouse position changes, and also it maintains an internal state. Then, the player class has a react() method, which accepts an input object as an argument. The advantage of this is that the input object could be serialized into JSON and then shared over the network, allowing for smooth multiplayer simulations. But how does this translate into an Entity System?

share|improve this question

5 Answers 5

up vote 19 down vote accepted
  • Camera: Making this a component would be pretty neat. It would just have a isRendering flag and depth range like Sean said. In addition to "field of view" (I guess you might call it scale in 2D?) and an output zone. The output zone could define the portion of the game window that this camera gets rendered to. It wouldn't have a separate position/rotation like you mention. The entity you create that has a camera component would use the position and rotation components of that entity. Then you'd have a camera system that looks for entities that have a camera, position and rotation components. The system takes that entity and draws all the entities it can "see" from it's position, rotation, depth of view and field of view, to the specified portion of the screen. That gives you lots of options for simulating multiple view ports, "character view" windows, local multiplayer, different layers of GUI and so on.

  • Particle Emitter: This too should just be a component. The particle system would look for entities that have a position, rotation and particle emitter. The emitter has all the properties needed to reproduce your current emitter, I'm not sure what all those are, stuff like: rate, initial velocity, decay time and so on. You wouldn't have to make multiple passes. The particle system knows which entities have that component. I imagine you could re-use a good deal of your existing code.

  • Inputs: I'd have to say making this into a component makes the most sense given the suggestions I make above. Your input system would get updated every frame with the current input events. Then when it's going through all it's entities that have the input component, it will apply those events. The input component would have a list of keyboard and mouse events all associated method callbacks. I'm not really sure where the method callbacks would live. Perhaps some input controller class? Whatever makes the most sense for later modification by users of your engine. But this would give you the power to easily apply input control to camera entities, player entities or whatever you needed. Want to synchronize the movement of a bunch of entities with the keyboard? Just give them all input components that respond to the same inputs and the input system applies those move events to all the components asking for them.

So most of this is just off the top of my head, so it probably won't make sense without further explanation. So just let me know what you're not clear on. Basically, I've given you a lot to work on :)

share|improve this answer
    
Another great answer! Thanks! Now, my only problem is storing and retrieving entities quickly, so the user can actually implement a game loop/logic... I'll try to figure it out by myself, but I must first learn how Javascript deals with arrays, objects and undefined values in memory to make a good guess... That will be a problem because different browsers might implement it differently. –  jco Jul 21 '12 at 17:14
    
This feels architecturally pure but how does the rendering system determine the active camera short of iterating through all the entities? –  Pace Apr 3 '13 at 12:26
    
@Pace Since I'd want the active camera to be found very quickly, I would likely allow the camera system to keep a reference to the entities that have an active camera. –  Byte56 Apr 3 '13 at 14:31

Here's how I approached this:

Camera

My camera is an entity like any other, which has attached components:

  1. Transform has Translation, Rotation and Scale properties, in addition to others for velocity, etc.

  2. Pov (Point of view) has FieldOfView, AspectRatio, Near, Far, and anything else required to produce a projection matrix, in addition to a IsOrtho flag used to switch between perspective and orthographic projections. Pov also provides a lazy-load ProjectionMatrix property used by the rendering system that's internally calculated on read, and cached until any of the other properties are modified.

There is no dedicated camera system. The Render System maintains a list of Pov's and contains logic for determining which one to use when rendering.

Input

An InputReceiver component can be attached to any entity. This has an attached event handler (or lambda if your language supports it) that is used to hold entity-specific input processing, which takes parameters for current and previous key state, current and previous mouse location and button state, etc. (Actually, there are separate handlers for mouse and keyboard).

For example, in an Asteroids-like test game I created when getting used to Entity/Component, I have two input lambda methods. One handles ship navigation by processing the arrow keys and the space bar (for firing). The other handles general keyboard input - keys for exit, pause, etc, restart level, etc. I create two components, attach each lambda to its own component, then assign the navigation receiver component to the ship entity, an the other one to a non-visible command processor entity.

Here's the event handler to handle keys that are held between frames that gets attached to the ship's InputReceiver component (C#):

  void ship_input_Hold(object sender, InputEventArgs args)
    {
        var k = args.Keys;
        var e = args.Entity;

        var dt = (float)args.GameTime.ElapsedGameTime.TotalSeconds;

        var verlet = e.As<VerletMotion>();
        var transform = e.As<Transform>();

        if (verlet != null)
        {

        /// calculate applied force 
            var force = Vector3.Zero;
            var forward = transform.RotationMatrix.Up * Settings.ShipSpeedMax;

            if (k.Contains(Keys.W))
                force += forward;

            if (k.Contains(Keys.S))
                force -= forward;

            verlet.Force += force * dt;
        }

        if (transform != null)
        {
            var theta = Vector3.Zero;

            if (k.Contains(Keys.A))
                theta.Z += Settings.TurnRate;

            if (k.Contains(Keys.D))
                theta.Z -= Settings.TurnRate;

            transform.Rotation += theta * dt;
        }

        if (k.Contains(Keys.Space))
        {
            var time = (float)args.GameTime.TotalGameTime.TotalSeconds - _rapidFireLast;

            if (time >= _rapidFireDelay)
            {
                Fire();
                _rapidFireLast = (float)args.GameTime.TotalGameTime.TotalSeconds;
            }
        }
    }

If your camera is mobile, give it its own InputReceiver and Transform component, attach a lambda or handler that implements whatever kind of control you want, and you're done.

This is kind of neat in that you can move the InputReceiver component with the navigation handler attached from the ship to an asteroid, or anything else for that matter, and fly that around instead. Or, by assigning a Pov component to anything else in your scene - an asteroid, street lamp, etc. - you can view your scene from that entity's perspective.

An InputSystem class that maintains an internal state for the keyboard, mouse, etc. InputSystem filters its internal entity collection to entities that have an InputReceiver component. In its Update() method, it iterates through that collection and calls the input handlers attached to each of those components in the same way that the rendering system draws each entity with a Renderable component.

Particles

This really depends on how you plan on interacting with the particles. If you just need a particle system that behaves like one object - say, a fireworks show that the player can't touch or hit - then I'd create a single entity, and a ParticleRenderGroup component that contains whatever information you need for the particles - decay, etc. - that isn't covered by your Renderable component. When rendering, the render system would see if an entity has the RenderParticleGroup attached and handle it accordingly.

If you need individual particles to participate in collision detection, respond to input, etc., but you just want to render them as a batch, I'd create a Particle component that contains that information on a per-particle basis, and create them as separate entities. The render system can still batch them, but they'll be treated as separate objects by the other systems. (This works very well with instancing.)

Then, either in your MotionSystem (or whatever your using that handles updating entity position, etc.) or in dedicated ParticleSystem, perform whatever processing is required for each particle per-frame. The RenderSystem would be responsible for building/batching and caching particle collections as they're created and destroyed, and render them as required.

One nice thing about this approach is that you don't have to have any special cases for collision, culling, etc. for particles; they code you write for every other kind of entity can still be used.

Conclusion

If you're considering going cross-platform - not super-applicable to JavaScript - all of your platform-specific code (namely, rendering and input) is isolated into two systems. Your game logic remains in platform-agnositic classes (motion, collision, etc.) so you shouldn't have to touch them when porting.

I understand and agree with Sean's position that shoe-horning things into a pattern in order to strictly adhere to the pattern, rather than tweaking the pattern to fill the needs of your application, is bad. I just don't see anything in Input, Camera or Particles that requires that sort of treatment.

share|improve this answer

Input and game logic will likely be handled in a dedicated chunk of code outside the entity component system. It's technically possible to shove it into the design, but there's little benefit - game logic and UI is hacky and full of leaky abstractions no matter what you do, and trying to force the square peg into a round hole just for architectural purity is a waste of time.

Likewise, particle emitters are special beasts, especially if you care at all about performance. An emitter component makes sense, but graphics is going to be doing some special magic with those components, intermixed with the magic for the rest of rendering.

Regarding your camera, just give cameras an active flag and maybe a "depth" index, and let the graphics system render all of them that are enabled. This is actually handy for a lot of tricks, including GUIs ( want your GUI rendered in an orthographic mode on top of the game world? No problem, they're just two cameras with different object masks and GUI set to a higher layer). It's also useful for special effects layers and such.

share|improve this answer

Would the camera be an entity or simply a component?

I'm not sure what this question is really asking. Given that the only things you have in the game are entities, then cameras have to be entities. The camera functionality is implemented via some sort of camera component. Don't have separate "Position" and "Rotation" components - that is far too low level. They should be combined into some sort of WorldPosition component which would apply to any entity located in the world. As for which one to use... you have to get logic into the system somehow. Either you hard-code it into your camera handling system, or you attach scripts, or something. You can have an enabled/disabled flag on a camera component if it helps.

I'm pretty sure that particles themselves shouldn't be entities

Me too. A particle emitter would be an entity, and the particle system would track the particles associated with a given entity. Things like this are where you realise that "everything is an entity" is absurdly impractical. In practice, the only things that are entities are relatively complex objects that benefit from combinations of components.

As for Input: input doesn't exist in the game world as such so that's handled by a system. Not necessarily a 'component system' because not everything in your game is going to revolve around components. But there will be an input system. You might want to mark the entity that responds to input with some sort of Player component, but the input is going to be complex and completely game-specific so there's little point trying to make components for this.

share|improve this answer

Here are some of my ideas of solving these problems. They will probably have something wrong with them, and there will probably be a better approach, so please, direct me to those in your answer!

Camera:

There is a "Camera" component, which can be added to any entity. I can't really figure what data should I put in this component, though: I could have separate "Position" and "Rotation" components! The follow method doesn't need to be implemented, because it's already following the entity it is attached to! And I'm free to move it around. The problem with this system would be many different camera objects: how can the RendererSystem know which ones to use? And also, I used to just pass the camera object around, but now it seems that the RendererSystem will need to iterate two times over all the entities: first to find the ones acting like cameras, and second, to actually render everything.

ParticleEmitter:

There would be a ParticleSystem which would update all entities that had a "Emitter" component. Particles are dumb objects in a relative coordinate space, inside that component. There is a problem of rendering here: I would either need to make a ParticleRenderer system, or extend the functionality of the existing one.

Input system:

The main concern for me here was the logic, or the react() method. The only solution I came up with is a separate system for that, and a component for each system, that would indicate which one to use. This really seems too hacky, and I don't know how to handle it well. One thing is that, as long as I'm concerned, the Input can stay implemented as a class, but I don't see how could I integrate it to the rest of the game.

share|improve this answer
    
There isn't really a reason for the RendererSystem to iterate over all entities - it should already have a list of drawables (and cameras, and lights (unless lights are drawables)), or know where those lists are. Also, you will likely want to do culling for cameras you want to render, so maybe your camera could contain a list of drawable entity IDs that are visible to it. You could have many cameras and one active one, or one camera that gets attached to different POVs, both of which could be controlled by any number of things, like scripts and triggers and inputs –  melak47 Jul 21 '12 at 15:41
    
@melak47, that's true, I thought about it too, but I wanted to implement it the way Aremis does it. But this "systems store references to relevant entities" seems to be more and more flawed... –  jco Jul 21 '12 at 15:45
    
Doesn't Artemis store each Component type in it's own list? so wouldn't you have exactly those lists of drawable components, camera components, lights and what not somewhere? –  melak47 Jul 21 '12 at 16:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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