Temple of The Roguelike Forums

Development => Programming => Topic started by: mike3 on April 23, 2013, 08:54:41 AM

Title: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 23, 2013, 08:54:41 AM
Hi.

I just finished programming an attempt at a “component-based” roguelike system, for practice. It was done over the last 4 days. You can get it here:

http://www.mediafire.com/?61s2vlh9dqiz73v

The code is rough and isn't meant for production work, just for practice, and I've got some questions because there were a number of things I wasn't quite sure how to do “right”, especially not with the new style of architecture I was triying here. It's a simple “curses”-based terminal program and the compile script is for Linux and similar systems – since I use Linux for most of my computing and programming work. Though it shouldn't be too hard to modify it to make it compile on Windows as a console app, provided you can supply the curses functionality with a suitable library (I haven't tried it on Windows, though, or with MS's compilers).

The architecture also uses an “event-driven system” for the main game loop.

Sorry about the restrictive license, but that's because it's rough, unfinished, and for practice and not really serious work. I hope you understand.

Now, the questions:

There is a “renderWorld” routine in the WorldManager, which doesn't seem right – this is related to rendering... where should it be? It needs the data from the world to render it (entities, map, etc.). I also heard at http://www.gamedev.net/topic/618973-creating-a-render-manager/#entry4905254 that a graphics system should only take in basic graphical objects and not more sophisticated objects like entities or “models”, etc. (the linked post says: “Likewise, a model has no place within the graphics module. (...) a general theme is that the graphics module simply handles the commands needed to render things, and provides wrappers for textures, vertex buffers (...)”). The RenderManager works in just that way: the primitive objects it receives (RenderObjects) store simple graphical representations (here grids of characters) only. Yet something has to get that lower-level data (in this case, ASCII representation, in that case, triangles/textures/etc.) from the higher-level entity/map objects and feed it into the render/graphics system: what should it be?

There is a reference to the input manager in the player's “AI component”, which is needed because for the player entity to make decisions when its it's turn to act, it needs a command from the user. But it doesn't seem right it should “know about” the input system, does it? If not, then does that mean we should add more code to the event handler to check if the acting entity is the player entity and capture the input there and then pass it on to the entity, thereby avoiding the reference to the input manager but adding more complexity/specialization in the event handling system? But if that's bad too, where should we put the calls to the input manager (remember: we don't want input until the player's “turn to act” comes around, i.e. when the EVT_ENTITY_ACTION event with the actingEntity variable equaling the player entity is due)? Already we have a problem in that the “quit” command isn't really something the entity does, but a signal to the game to stop!

Where should the handler for game events go? Not all events (EVT_QUIT is an example – there'd be others in a real game) involve an entity acting. So putting it on the entities doesn't seem to work – or should one have handlers for those kind of events on the entities, and handlers for the other in the game? But would putting it on the entities violate the component system? If so, what should we do? Have something to translate events to messages?

Also, how would one make the part of the program that handles stuff like collisions/interactions between entities, with tiles on the map (right now, there is no collision handling and I only have an “ad hoc” stop in there (clearly marked!) to keep the player from running off the map altogether! Obviously that is a big no-no in a production program! It's just a placeholder until I can get how to work this out.), etc.? It doesn't seem right to make the physic component of an entity have full access to the map and all entities on it (i.e. essentially the whole WorldManager), does it? If it isn't right, then what should I do (that “ad hoc”-marked code is really just a placeholder because I'm not sure how to handle this dependency problem)?

And in a bigger game, where you can pick stuff up, what's the best way to distinguish a “pickupable” entity from a non-pickupable one?

I'd also like to hear a general review/comment/critique/etc. of the code – any pointers for improvement would be welcome.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: Nymphaea on April 23, 2013, 11:59:03 AM
Far from an expert, and I haven't looked at the code, but I've been looking into this myself :P

For the rendering, what I've seen other games do, and what I plan to do, is to have a "SpriteBatch" class built into the engine, not a component, and each component is passed the current instance of SpriteBatch each tick if it needs to draw something. Then just have a "SpriteBatch.render()" command to actually draw the changes after everything got it's chance. For a curses based game, you could have an array of characters, and an array of foreground/background colours in the SpriteBatch for simplicity.

So in your case, your components would have a "render(SpriteBatch sb)" method, which would be run at the end of each tick by the engine.

For the AI, just have the player AI do nothing, and the game pause while waiting for input. Then just manually tell the AI "move(DIR_LEFT)" or whatever when the left key is pressed.

For events, you could just have a global event handler that uses id's to tell what the message is for. Then have entities go "EventHandler.getEvents(my_id)" to get a list of all events referencing their id. -1 could be for game specific events(quit) and 0+ can be entity events.

Collisions... Well you could use events for this too, if the entity wants to move it gives the event to the map, the map checks if it is possible, if it is it will send an event back saying the movement was successful with the updated coordinates.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on April 23, 2013, 03:39:00 PM
Quote
Yet something has to get that lower-level data (in this case, ASCII representation, in that case, triangles/textures/etc.) from the higher-level entity/map objects and feed it into the render/graphics system: what should it be?


An asset library is just a data structure of references of models/textures/sounds that are available to use. The keys to access that data are stored on the graphics components of your entities. Nymphaea suggests a spritebatch, which is usually just an asset library all stored in a single asset image. Your GraphicsComponent will store the key of the asset and any additional information needed to render (location, facing, textures, animation sets, etc).

Your RenderWorld routine is technically in an acceptable place. Traditional game loops just iterate through entities calling entity.update() to determine the logic of the game and entity.render() to display it.

However, this may work against the design of a component system. You should try breaking all of your logic up into systems that work only with relevant components. Your engine is then just something that manages which systems are currently active.

Consider,
Code: [Select]
if(it->second->hasComponent("graphic"))
You might create a system that stores references to all relevant components. A RenderSystem, for example, may store a list of GraphicsComponents- and just iterate through those, as it doesn't need to know anything about the rest of the entity. In this way, RenderSystem can either be instanced inside of your WorldManager (if your WorldManager handles the game loop), or be instanced in the game loop directly (or you can even thread it so that rendering is done asynchronously).

Quote
There is a reference to the input manager in the player's “AI component”, which is needed because for the player entity to make decisions when its it's turn to act, it needs a command from the user. But it doesn't seem right it should “know about” the input system, does it?

This is where some troublesome entanglements can happen. Suppose the player is accessing UI menus that have nothing or little to do with game logic- how should that work? Should those UI commands also be routed through the player's entity instance? Certainly not, but that doesn't mean that we can't have a reference in the component. Components are just a way to keep your game logic discrete. The player component having access to the input manager doesn't really violate this in any way. Wait for input is part of the the player's game logic, but there should be an input handler on top of that. For example,

Quote
(remember: we don't want input until the player's “turn to act” comes around, i.e. when the EVT_ENTITY_ACTION event with the actingEntity variable equaling the player entity is due)?

What if we have real-time graphical effects? Should the player be prevented from accessing the menu or quitting the game? Probably not. Look into keybinding libraries. Instead of a 'waitForKeyPress' you'll have a 'waitForAction', or something. Where the input handler will send an actionID to the player's entity for actuation.


Quote
Where should the handler for game events go? Not all events (EVT_QUIT is an example – there'd be others in a real game) involve an entity acting. So putting it on the entities doesn't seem to work – or should one have handlers for those kind of events on the entities, and handlers for the other in the game? But would putting it on the entities violate the component system? If so, what should we do? Have something to translate events to messages?

I think that component systems and event systems don't mesh very well. The whole point of components is to isolate where the components interact with one another. You shouldn't need messages, events, or handlers-- it should all just happen in the systems relevant to those components. If your systems are arranged in a meaningful Finite State Machine, you can pass information between systems by updating components. This doesn't mean you can't use them together-- just that when you mix them, it can be hard to tell what should go where.

Technically, EVT_QUIT could be handled by any entity- the most trivial example could be by freeing memory. Regardless, if you're going down the event path, you may want to create, at the very least, an event handling abstract base class for every object in the game to use. You can override what you need for any given object, and forget the rest. You can also create a hierarchy of abstractions to more reasonably organize handlers. You don't want to start defining classes for different entity types, just for different game objects to handle different events. This will allow you to handle events and use components in a happier way.

Quote
Also, how would one make the part of the program that handles stuff like collisions/interactions between entities

All you have to do is create a collision event when a move takes place and something already occupies the space. You then call the respective onCollide handlers for those entities and determine what should happen. Should we attack? Pick up an object? Or bump senselessly into a wall? Perhaps we don't want the player to lose their turn if they bump into a wall-- etc. Entity doesn't need any information about the map-- it just acts as a way to store data for the player's avatar and for the player to interact with the game model.

Quote
And in a bigger game, where you can pick stuff up, what's the best way to distinguish a “pickupable” entity from a non-pickupable one?

EdibleItemComponent, EquippableItemComponent, PickupItemComponent-- etc. An inventory management system should figure out how an item can be used/gathered based upon the information in its components. You could have just an 'ItemComponent' with all of those details.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 23, 2013, 09:28:09 PM
Quote
Yet something has to get that lower-level data (in this case, ASCII representation, in that case, triangles/textures/etc.) from the higher-level entity/map objects and feed it into the render/graphics system: what should it be?


An asset library is just a data structure of references of models/textures/sounds that are available to use. The keys to access that data are stored on the graphics components of your entities. Nymphaea suggests a spritebatch, which is usually just an asset library all stored in a single asset image. Your GraphicsComponent will store the key of the asset and any additional information needed to render (location, facing, textures, animation sets, etc).

So then you'd suggest to store keys, not the actual graphics, in the GraphicsComponent? (Right now it stores an actual graphic (here just an ASCII character) + position to render it at.) What would have access to this graphics library? Would the RenderSystem (mentioned below) have access to it?

Your RenderWorld routine is technically in an acceptable place. Traditional game loops just iterate through entities calling entity.update() to determine the logic of the game and entity.render() to display it.

However, this may work against the design of a component system. You should try breaking all of your logic up into systems that work only with relevant components. Your engine is then just something that manages which systems are currently active.

Consider,
Code: [Select]
if(it->second->hasComponent("graphic"))
You might create a system that stores references to all relevant components. A RenderSystem, for example, may store a list of GraphicsComponents- and just iterate through those, as it doesn't need to know anything about the rest of the entity. In this way, RenderSystem can either be instanced inside of your WorldManager (if your WorldManager handles the game loop), or be instanced in the game loop directly (or you can even thread it so that rendering is done asynchronously).

So then this "RenderSystem" is something different from what that person on the post I linked to was talking about which could only be passed low-level graphical data (lower-level than "models", though I wasn't sure what that referred to -- if it referred to meshes, then that'd seem like individual triangles or something), which in this case would seem to be just ASCII characters, or sprites for tile graphics?

But then something has to get the graphics components off the entity to feed them into the RenderSystem. Which means there'd need to be a routine, perhaps on the RenderSystem itself, that "registers" an entity with it by putting its GraphicsComponents on the list.

Does this "RenderSystem" only work with GraphicsComponents -- as the map, for example, is not an entity with a GraphicsComponent, yet it still has to be rendered?

Also, if a new entity is created or an old one destroyed (monster killed, etc.) in the game world -- which is in the WorldManager -- then the RenderSystem needs to be updated to reflect that. Would WorldManager's "renderWorld" function feed entities into the RenderSystem, just as it feeds their graphics components to RenderManager now, but no longer having to know about the components within the entity?

Quote
There is a reference to the input manager in the player's “AI component”, which is needed because for the player entity to make decisions when its it's turn to act, it needs a command from the user. But it doesn't seem right it should “know about” the input system, does it?

This is where some troublesome entanglements can happen. Suppose the player is accessing UI menus that have nothing or little to do with game logic- how should that work? Should those UI commands also be routed through the player's entity instance? Certainly not, but that doesn't mean that we can't have a reference in the component. Components are just a way to keep your game logic discrete. The player component having access to the input manager doesn't really violate this in any way. Wait for input is part of the the player's game logic, but there should be an input handler on top of that. For example,

Quote
(remember: we don't want input until the player's “turn to act” comes around, i.e. when the EVT_ENTITY_ACTION event with the actingEntity variable equaling the player entity is due)?

What if we have real-time graphical effects? Should the player be prevented from accessing the menu or quitting the game? Probably not. Look into keybinding libraries. Instead of a 'waitForKeyPress' you'll have a 'waitForAction', or something. Where the input handler will send an actionID to the player's entity for actuation.

Yes, this is a simple program that doesn't have such things. In that case, though, there's then essentially two different types of "time" running -- there's "real time" which determines the running graphics, and then there's "game time", which determines the time lapsing in the game world (and the events represent things happening in the game world). Real time elapses continuously (well, at the frame rate of the graphics being drawn), while "game time" does not (it elapses like how the "gameTime" variable in the current program elapses). So it'd make sense to separate those two somehow.

The concern about UI menus is something I was wondering about, too, since in a bigger game I'd have menus. Would their rendering be handled by the same RenderSystem as everything else, or what? (which would mean the RenderSystem would have to accept more than just GraphicsComponents -- unless each UI window has a GraphicsComponent in it, but of a different type from that used in entities)

Quote
Where should the handler for game events go? Not all events (EVT_QUIT is an example – there'd be others in a real game) involve an entity acting. So putting it on the entities doesn't seem to work – or should one have handlers for those kind of events on the entities, and handlers for the other in the game? But would putting it on the entities violate the component system? If so, what should we do? Have something to translate events to messages?

I think that component systems and event systems don't mesh very well. The whole point of components is to isolate where the components interact with one another. You shouldn't need messages, events, or handlers-- it should all just happen in the systems relevant to those components. If your systems are arranged in a meaningful Finite State Machine, you can pass information between systems by updating components. This doesn't mean you can't use them together-- just that when you mix them, it can be hard to tell what should go where.

Technically, EVT_QUIT could be handled by any entity- the most trivial example could be by freeing memory. Regardless, if you're going down the event path, you may want to create, at the very least, an event handling abstract base class for every object in the game to use. You can override what you need for any given object, and forget the rest. You can also create a hierarchy of abstractions to more reasonably organize handlers. You don't want to start defining classes for different entity types, just for different game objects to handle different events. This will allow you to handle events and use components in a happier way.

So what would better mesh with events? Also, the entity would free its memory when its destructor is called. When quit is fired, it means the game is shutting down, so this has to lead to an exit of the game loop.

What would better mesh with components, insofar as getting "things that happen in the game world" to go?

Quote
Also, how would one make the part of the program that handles stuff like collisions/interactions between entities

All you have to do is create a collision event when a move takes place and something already occupies the space. You then call the respective onCollide handlers for those entities and determine what should happen. Should we attack? Pick up an object? Or bump senselessly into a wall? Perhaps we don't want the player to lose their turn if they bump into a wall-- etc. Entity doesn't need any information about the map-- it just acts as a way to store data for the player's avatar and for the player to interact with the game model.

Where is said onCollide handler? If it's in the entity object, then to make it do different things for different kinds of entity we need to make subclasses of Entity, which defeats the whole idea of the component system! In which case we might as well just scrap it and go for a traditional inheritance-based entity system.

And what spawns the collision event? It has to know about the movement the entity is going to make (which is determined by AI), the positions of all entities on the map, and a collision occurs.

And how would one do that wall-bump thing, anyway, when in the current setup the loop cycles through once the action event is handled, and another one is scheduled, which marks another turn?

Quote
And in a bigger game, where you can pick stuff up, what's the best way to distinguish a “pickupable” entity from a non-pickupable one?

EdibleItemComponent, EquippableItemComponent, PickupItemComponent-- etc. An inventory management system should figure out how an item can be used/gathered based upon the information in its components. You could have just an 'ItemComponent' with all of those details.

This makes sense.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on April 23, 2013, 11:24:46 PM
Quote
Yet something has to get that lower-level data (in this case, ASCII representation, in that case, triangles/textures/etc.) from the higher-level entity/map objects and feed it into the render/graphics system: what should it be?


An asset library is just a data structure of references of models/textures/sounds that are available to use. The keys to access that data are stored on the graphics components of your entities. Nymphaea suggests a spritebatch, which is usually just an asset library all stored in a single asset image. Your GraphicsComponent will store the key of the asset and any additional information needed to render (location, facing, textures, animation sets, etc).

So then you'd suggest to store keys, not the actual graphics, in the GraphicsComponent? (Right now it stores an actual graphic (here just an ASCII character) + position to render it at.) What would have access to this graphics library? Would the RenderSystem (mentioned below) have access to it?

Your RenderWorld routine is technically in an acceptable place. Traditional game loops just iterate through entities calling entity.update() to determine the logic of the game and entity.render() to display it.

However, this may work against the design of a component system. You should try breaking all of your logic up into systems that work only with relevant components. Your engine is then just something that manages which systems are currently active.

Consider,
Code: [Select]
if(it->second->hasComponent("graphic"))
You might create a system that stores references to all relevant components. A RenderSystem, for example, may store a list of GraphicsComponents- and just iterate through those, as it doesn't need to know anything about the rest of the entity. In this way, RenderSystem can either be instanced inside of your WorldManager (if your WorldManager handles the game loop), or be instanced in the game loop directly (or you can even thread it so that rendering is done asynchronously).

So then this "RenderSystem" is something different from what that person on the post I linked to was talking about which could only be passed low-level graphical data (lower-level than "models", though I wasn't sure what that referred to -- if it referred to meshes, then that'd seem like individual triangles or something), which in this case would seem to be just ASCII characters, or sprites for tile graphics?

But then something has to get the graphics components off the entity to feed them into the RenderSystem. Which means there'd need to be a routine, perhaps on the RenderSystem itself, that "registers" an entity with it by putting its GraphicsComponents on the list.


Nope, it isn't different.

In 3D games, the list of triangles for a mesh will be stored in specialized data structures (really just a list of vertices, normals, and UVs). We don't need to 'copy' this information to an object before rendering it. What if two entities had the same mesh? Why would you want to store multiple copies of the same mesh in memory? We can just store the reference to that mesh on an object (or really, just the key/index of that mesh in the asset list). It isn't quite that simple though- we also want to store transformation information, material data, and other things pertinent to that particular object. It's just that in the case of the actual asset, we never store it on an object. We store transformation information in the component and the mesh in the library.



It's awkward in a roguelike where there is only a single character to store, but you may want to do it anyway for creating consistency among different racial types- then you can localize color definitions within the graphics component or create another entry into your AssetLibrary for various colors/characters to be used in consistent ways.



Quote
Quote
There is a reference to the input manager in the player's “AI component”, which is needed because for the player entity to make decisions when its it's turn to act, it needs a command from the user. But it doesn't seem right it should “know about” the input system, does it?

This is where some troublesome entanglements can happen. Suppose the player is accessing UI menus that have nothing or little to do with game logic- how should that work? Should those UI commands also be routed through the player's entity instance? Certainly not, but that doesn't mean that we can't have a reference in the component. Components are just a way to keep your game logic discrete. The player component having access to the input manager doesn't really violate this in any way. Wait for input is part of the the player's game logic, but there should be an input handler on top of that. For example,

Quote
(remember: we don't want input until the player's “turn to act” comes around, i.e. when the EVT_ENTITY_ACTION event with the actingEntity variable equaling the player entity is due)?

What if we have real-time graphical effects? Should the player be prevented from accessing the menu or quitting the game? Probably not. Look into keybinding libraries. Instead of a 'waitForKeyPress' you'll have a 'waitForAction', or something. Where the input handler will send an actionID to the player's entity for actuation.

Yes, this is a simple program that doesn't have such things. In that case, though, there's then essentially two different types of "time" running -- there's "real time" which determines the running graphics, and then there's "game time", which determines the time lapsing in the game world (and the events represent things happening in the game world). Real time elapses continuously (well, at the frame rate of the graphics being drawn), while "game time" elapses in a turn-wise manner. So it'd make sense to separate those two somehow.

The concern about UI menus is something I was wondering about, too, since in a bigger game I'd have menus.

You may also want to take advantage of idle processing while the player is waiting to input data. For example-- In complex AI calculations we might be able to improve the experience of the game if we're always crunching AI algorithms even while waiting for the player. Don't get carried away though- just do what makes sense.

An inputManager on top of the game will use keybindings and 'screen focus' to determine where to send the input.


Quote
Quote
Where should the handler for game events go? Not all events (EVT_QUIT is an example – there'd be others in a real game) involve an entity acting. So putting it on the entities doesn't seem to work – or should one have handlers for those kind of events on the entities, and handlers for the other in the game? But would putting it on the entities violate the component system? If so, what should we do? Have something to translate events to messages?

I think that component systems and event systems don't mesh very well. The whole point of components is to isolate where the components interact with one another. You shouldn't need messages, events, or handlers-- it should all just happen in the systems relevant to those components. If your systems are arranged in a meaningful Finite State Machine, you can pass information between systems by updating components. This doesn't mean you can't use them together-- just that when you mix them, it can be hard to tell what should go where.

Technically, EVT_QUIT could be handled by any entity- the most trivial example could be by freeing memory. Regardless, if you're going down the event path, you may want to create, at the very least, an event handling abstract base class for every object in the game to use. You can override what you need for any given object, and forget the rest. You can also create a hierarchy of abstractions to more reasonably organize handlers. You don't want to start defining classes for different entity types, just for different game objects to handle different events. This will allow you to handle events and use components in a happier way.

So what would better mesh with events? Also, the entity would free its memory when its destructor is called. When quit is fired, it means the game is shutting down, so this has to lead to an exit of the game loop.

What would better mesh with components, insofar as getting "things that happen in the game world" to go?

An event can be handled by more than one object. Or is my nomenclature off >_>. Maybe not handled by- but react to? Whatever the case, when an event occurs, anything with an onThatTypeOfEvent method should be called on relevant objects.

We may want to do something special on a particular entity for an onQuit event. What that is, who knows- but we should be able to do it if we want to.


Well- component systems do their own work themselves. The idea is that you store relevant data in components and specific system updates the components relative to one another. You don't need events, messaging, or any of that stuff- the systems immediately handle whatever messages/events would take place. In the case that they don't, we just go to another system.

For example-- our ControllerSystem polls the controller of an entity to figure out what heuristic should govern the next action. Then we might switch to a HeuristicAnalysisSystem that runs the heuristic algorithm to determine what action should take place.

This dude does a good job of breaking it down- I stumbled upon it recently. He has numerous articles on his blog that describe how it works, though I don't really like the way he did it (I flamed him for his implementation of state management >_<). I'd read them both for some insight on the what, how and why's of components. It's well-written and very clear.

http://www.richardlord.net/blog/what-is-an-entity-framework
http://www.richardlord.net/blog/why-use-an-entity-framework

Note that this isn't a 'pure' component system, just one that does a pretty good job of hybridizing classes and components in a way that is natural for OOP style.

Quote
Quote
Also, how would one make the part of the program that handles stuff like collisions/interactions between entities

All you have to do is create a collision event when a move takes place and something already occupies the space. You then call the respective onCollide handlers for those entities and determine what should happen. Should we attack? Pick up an object? Or bump senselessly into a wall? Perhaps we don't want the player to lose their turn if they bump into a wall-- etc. Entity doesn't need any information about the map-- it just acts as a way to store data for the player's avatar and for the player to interact with the game model.

Where is said onCollide handler? If it's in the entity object, then to make it do different things for different kinds of entity we need to make subclasses of Entity, which defeats the whole idea of the component system! In which case we might as well just scrap it and go for a traditional inheritance-based entity system.

And what spawns the collision event? It has to know about the movement the entity is going to make (which is determined by AI), the positions of all entities on the map, and a collision occurs.

And how would one do that wall-bump thing, anyway, when in the current setup the loop cycles through once the action event is handled, and another one is scheduled, which marks another turn?

That's how event systems work. I mean, I've never programmed one, but I've used many event-driven APIs, and that's how they're structured.

Event Object is produced and added to a queue. Event System then takes an event and evaluates it by calling whatever respective methods for that event exist on relevant entities (which may include more entities than those colliding).

You can handle collision either in a component way or an event way- or possibly both. The event way is to make your collisionEvent and then call onCollide variants in the entities.


Did you get the idea to use event systems on 3d gaming forums? We like event systems for real-time game engines because they allow us to hide a lot of really complicated shit but still code custom behaviors into our entities directly and expect it to work. If YOU are making the engine, event systems are, IMO, a PITA.

So... In a component system, game logic takes place in a system. In an event system, your events are handled in systems but the logic is relative to the implementation of an entity.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 24, 2013, 12:42:49 AM
Nope, it isn't different.

In 3D games, the list of triangles for a mesh will be stored in specialized data structures (really just a list of vertices, normals, and UVs). We don't need to 'copy' this information to an object before rendering it. What if two entities had the same mesh? Why would you want to store multiple copies of the same mesh in memory? We can just store the reference to that mesh on an object (or really, just the key/index of that mesh in the asset list). It isn't quite that simple though- we also want to store transformation information, material data, and other things pertinent to that particular object. It's just that in the case of the actual asset, we never store it on an object. We store transformation information in the component and the mesh in the library.

However, then that means the render system deals with whole assets and not just graphical primitives, right? But how does that jibe with what the person on that gamedev.net site was saying?

  • AssetLibrary stores Data
  • GraphicsComponent stores references to AssetLibrary and other transformation information
  • RenderSystem stores a list of references to GraphicsComponents, iterates through and draws them to the screen accordingly.

It's awkward in a roguelike where there is only a single character to store, but you may want to do it anyway for creating consistency among different racial types- then you can localize color definitions within the graphics component or create another entry into your AssetLibrary for various colors/characters to be used in consistent ways.

And, I suppose, the RenderSystem also stores a copy of a pointer to the AssetLibrary so it can access it, right?


You may also want to take advantage of idle processing while the player is waiting to input data. For example-- In complex AI calculations we might be able to improve the experience of the game if we're always crunching AI algorithms even while waiting for the player. Don't get carried away though- just do what makes sense.

An inputManager on top of the game will use keybindings and 'screen focus' to determine where to send the input.

Doesn't the input manager then also have to know about all possible places it can send the input? Like it has to know about the pile of entities, so it can send input there. It needs to know about the windows on the display, so it can send input there. But isn't that making too many dependencies?

An event can be handled by more than one object. Or is my nomenclature off >_>. Maybe not handled by- but react to? Whatever the case, when an event occurs, anything with an onThatTypeOfEvent method should be called on relevant objects.

We may want to do something special on a particular entity for an onQuit event. What that is, who knows- but we should be able to do it if we want to.


Well- component systems do their own work themselves. The idea is that you store relevant data in components and specific system updates the components relative to one another. You don't need events, messaging, or any of that stuff- the systems immediately handle whatever messages/events would take place. In the case that they don't, we just go to another system.

For example-- our ControllerSystem polls the controller of an entity to figure out what heuristic should govern the next action. Then we might switch to a HeuristicAnalysisSystem that runs the heuristic algorithm to determine what action should take place.

This dude does a good job of breaking it down- I stumbled upon it recently. He has numerous articles on his blog that describe how it works, though I don't really like the way he did it (I flamed him for his implementation of state management >_<). I'd read them both for some insight on the what, how and why's of components. It's well-written and very clear.

http://www.richardlord.net/blog/what-is-an-entity-framework
http://www.richardlord.net/blog/why-use-an-entity-framework

Note that this isn't a 'pure' component system, just one that does a pretty good job of hybridizing classes and components in a way that is natural for OOP style.

Thanks for the links. I'll have a look at it.

That's how event systems work. I mean, I've never programmed one, but I've used many event-driven APIs, and that's how they're structured.

Event Object is produced and added to a queue. Event System then takes an event and evaluates it by calling whatever respective methods for that event exist on relevant entities (which may include more entities than those colliding).

You can handle collision either in a component way or an event way- or possibly both. The event way is to make your collisionEvent and then call onCollide variants in the entities.


Did you get the idea to use event systems on 3d gaming forums? We like event systems for real-time game engines because they allow us to hide a lot of really complicated shit but still code custom behaviors into our entities directly and expect it to work. If YOU are making the engine, event systems are, IMO, a PITA.

So... In a component system, game logic takes place in a system. In an event system, your events are handled in systems but the logic is relative to the implementation of an entity.

So then event systems are fundamentally tied to the "inheritance" method of construction, where you subclass entities to get different kinds of entities?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 24, 2013, 01:01:20 AM
Was looking at the links you gave -- I notice the method described there has an "update" function on the systems and components, which seems it's designed for a real-time game. How does this change in a turn-based game like a roguelike?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: george on April 24, 2013, 01:39:00 AM
How you do updates in a turn-based game depends on your 'time' system. In the most basic I go you go (player takes their turn, then you iterate through all other things and they just take their turn in order of where they are in the list), you call the update on a thing when it's their turn.

I have to disagree that events/messaging and components don't mesh that well. They serve different purposes.

The biggest mistake with components IMO is to confuse game things with code objects. That leads you to the question like you had before of 'where do I put quit-game()'? Just because you have an entity system where entities are 'game things' does not mean that your source code objects are limited to describing just entities, their managers, and the systems that act on them.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on April 24, 2013, 06:18:51 PM
Quote
However, then that means the render system deals with whole assets and not just graphical primitives, right? But how does that jibe with what the person on that gamedev.net site was saying?

Assets ARE data structures of graphical primitives. They are a set of instructions to the Render System as to how this particular asset is produced out of graphical primitives. The supplementary data provided by the graphics component tells us what transformations are applied to that data before/after it's position is evaluated in real space*.

In other words, the Render System only deals with graphical primitives, but receives instructions in the form of assets and transformations. To be clear, a transformation is typically in the form of the traditional scale, translation, and rotation matrices (but there are others that we produce from a combination of these- like shearing and... stuff >_>).

* This can get a little confusing, because our components are supposed to be shared whenever possible. We don't want to put graphical transformations on a graphics component if that same information is used by logic (such as rotation and location). HOWEVER, sometimes we actually want the logical position and the mesh position to be different-- not often, but sometimes. This just gets into implementation details. The spirit of components remains the same.

Quote
And, I suppose, the RenderSystem also stores a copy of a pointer to the AssetLibrary so it can access it, right?

Yep! You CAN store the reference to the asset on the entity instead of the key for the library, but only processes related to Asset Loading should modify that reference. Most any specialized modifications or transformations of assets for a particular special entity are handled in its various graphics components.

Quote
Doesn't the input manager then also have to know about all possible places it can send the input? Like it has to know about the pile of entities, so it can send input there. It needs to know about the windows on the display, so it can send input there. But isn't that making too many dependencies?

We don't send input to entities, we just send input to Screens, Frame, Windows, whatever you want to call them. This gets into window management-- but basically each different window may have some specialized keybindings for that window. The input manager simply maps key input to an action for whatever window has focus. In the case of actual gameplay, we aren't necessarily sending input directly to entities, but through the game window, where the action is delegated to the appropriate entity.

Honestly, it's better to learn why this is important by NOT doing it the first couple times around. Window management is a PITA that you should avoid until necessary, as it will keep you from actually working on your game.

Quote
So then event systems are fundamentally tied to the "inheritance" method of construction, where you subclass entities to get different kinds of entities?

Yes, event systems are all about letting disjunct classes do all of the work through a messaging system. Component systems aren't that different, except that all messaging is isolated to relevant components in relevant systems- so there is no classical inheritance scheme. For game logic, it's all to accomplish the same thing, components just tend to give us a more transparent awareness and simplicity into specifying the functionality of our game.

Since classes do the logic in event systems, we can easily make design mistakes-- like, say, the application of a stun effect. Where should it go? Well, the instigator should send a message to another entity to be stunned. The recipient of the stun message then determines whether it should be stunned or not (or do something else). This represents a continuum of game logic that really doesn't need to be happening in two different places.


Nonetheless, we aren't tied into stupid hierarchies with event systems, we just have to use its power intelligently http://en.wikipedia.org/wiki/Composition_over_inheritance.

Quote
Was looking at the links you gave -- I notice the method described there has an "update" function on the systems and components, which seems it's designed for a real-time game. How does this change in a turn-based game like a roguelike?

His game engine isn't necessarily real-time, it's tick-based (by default, real-time ticks). All you would do, in the Controller System, where input/AI is mapped to actions, is just throw a 'waitForPlayerAction' in there and your game is now turn-based... well, almost. You need to update each entity per system, instead of update each system per entity.



Quote
The biggest mistake with components IMO is to confuse game things with code objects. That leads you to the question like you had before of 'where do I put quit-game()'? Just because you have an entity system where entities are 'game things' does not mean that your source code objects are limited to describing just entities, their managers, and the systems that act on them.

His source code uses an event system for component interactions. It's okay to have both for GAME LOGIC, but you need to be clear about what produces and handles events and what gets handled in systems. A global game message might be simpler to deal with as an event, but a global game message isn't typically going to effect entities that don't have relevant components.

But yea-- you need to make a distinction between Game Logic Events, Application Events, and possibly even System Events. You can structure an entire application as a component system, but the DOP is designed for data-driven logic, like a game.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 24, 2013, 09:14:19 PM
We don't send input to entities, we just send input to Screens, Frame, Windows, whatever you want to call them. This gets into window management-- but basically each different window may have some specialized keybindings for that window. The input manager simply maps key input to an action for whatever window has focus. In the case of actual gameplay, we aren't necessarily sending input directly to entities, but through the game window, where the action is delegated to the appropriate entity.

Honestly, it's better to learn why this is important by NOT doing it the first couple times around. Window management is a PITA that you should avoid until necessary, as it will keep you from actually working on your game.

But how does the window transfer the input to the relevant entity? Doesn't it need to know about entities to do that? Should that knowledge/dependency exist?

And doesn't any game that's more than trivial need UI menus?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on April 25, 2013, 12:36:13 AM
We don't send input to entities, we just send input to Screens, Frame, Windows, whatever you want to call them. This gets into window management-- but basically each different window may have some specialized keybindings for that window. The input manager simply maps key input to an action for whatever window has focus. In the case of actual gameplay, we aren't necessarily sending input directly to entities, but through the game window, where the action is delegated to the appropriate entity.

Honestly, it's better to learn why this is important by NOT doing it the first couple times around. Window management is a PITA that you should avoid until necessary, as it will keep you from actually working on your game.

But how does the window transfer the input to the relevant entity? Doesn't it need to know about entities to do that? Should that knowledge/dependency exist?

And doesn't any game that's more than trivial need UI menus?


Yea- but the issue of UI menus, input and windows is basically a solved problem. There isn't a good reason to do it from scratch. Do you want to make a game, or do you want to make an application framework?


As far as windowing and stuff-- Basically, you pop a window open- the top level window is what catches input. A 'window' is just an abstraction to make a distinction between input focus (because the window also provides feedback, it will communicate with the renderer too).

Input ----> Window ---->  Logic ---> Renderer ----> [Window] <----- Input

So the window is an abstraction that facilitates the interfacing of input to logic, which then results in some kind of  rendering feedback.

The input manager will catch specific keys first-- like 'esc' to immediately exit or something. Then it will pass the input down to the window, which may also use it-- then it will call a method of the game object that corresponds to that key-binding.

I'm not explaining it well because I don't have too much experience programming these meta-application features. A framework should do all of this for you.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 25, 2013, 02:26:03 AM
We don't send input to entities, we just send input to Screens, Frame, Windows, whatever you want to call them. This gets into window management-- but basically each different window may have some specialized keybindings for that window. The input manager simply maps key input to an action for whatever window has focus. In the case of actual gameplay, we aren't necessarily sending input directly to entities, but through the game window, where the action is delegated to the appropriate entity.

Honestly, it's better to learn why this is important by NOT doing it the first couple times around. Window management is a PITA that you should avoid until necessary, as it will keep you from actually working on your game.

But how does the window transfer the input to the relevant entity? Doesn't it need to know about entities to do that? Should that knowledge/dependency exist?

And doesn't any game that's more than trivial need UI menus?


Yea- but the issue of UI menus, input and windows is basically a solved problem. There isn't a good reason to do it from scratch. Do you want to make a game, or do you want to make an application framework?


As far as windowing and stuff-- Basically, you pop a window open- the top level window is what catches input. A 'window' is just an abstraction to make a distinction between input focus (because the window also provides feedback, it will communicate with the renderer too).

Input ----> Window ---->  Logic ---> Renderer ----> [Window] <----- Input

So the window is an abstraction that facilitates the interfacing of input to logic, which then results in some kind of  rendering feedback.

The input manager will catch specific keys first-- like 'esc' to immediately exit or something. Then it will pass the input down to the window, which may also use it-- then it will call a method of the game object that corresponds to that key-binding.

I'm not explaining it well because I don't have too much experience programming these meta-application features. A framework should do all of this for you.

Ah, "call a method on the game object". That's the part I wasn't sure about.  Thanks for that.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 25, 2013, 04:21:47 AM
Also, when you talk about "windows" and "UI menus" do you mean the OS's windows/menus, or menus/popups drawn inside the game? As if it's the latter, then what kind of "framework" would one use that would allow for easily providing the necessary render routines to render that stuff?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: george on April 25, 2013, 04:35:20 AM
You're using pyglet, right? If I recall correctly there are some UI frameworks written for pyglet that you could use. Check the mailing list and maybe Pyweek. (sorry, confused you with someone else  :P)
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on April 25, 2013, 05:45:47 AM
Also, when you talk about "windows" and "UI menus" do you mean the OS's windows/menus, or menus/popups drawn inside the game? As if it's the latter, then what kind of "framework" would one use that would allow for easily providing the necessary render routines to render that stuff?

Okay--- This is where things can get tricky. Any application is designed to work with some rendering medium, which is windowed by a Window Manager.

A Window Manager, for an operating system, has implementation specific features that govern how it works. If you use the API for an operating system, you can create additional windows tied to your application but have window decorators. .NET, GTK, QT, and Java, for example, provide comprehensive UI frameworks for desktop integration of your window management. This allows us to manage each window from the desktop. We don't care about that crap for games, but its useful for applications.

Within a game, we may have a side-bar screen that shows player information, another screen that shows a minimap, and another that shows the player's position in the game world. All of these are separate screens or 'windows.' However, the focus is on the player's position screen. When we open our inventory, we open a new window, focus shifts, and now we're in 'inventory item selection'-mode, or something. Point is, we don't need a complex window managing system to make this look good in the game, we just need a concise one- typically something simple.

I don't have anything in mind if you're set on C++-- it really just depends on what APIs you're working with. I'm sure there are some good SDL/OpenGL ones out there, but I don't know about curses. Most curses programmers, afaik, just allot portions of the screen for specific data and may not bother with a window managing abstraction...

Now that I think about it further-- it may be better to do it yourself (sorry for going back on what I just said >_<). I mean-- all you have to do is create a way to manage which OBJECT in your application has input focus. This can be pretty simple for a roguelike. Press 'i' while on the game screen and the inventory screen pops up and input focus shifts. For an RL this shouldn't be too difficult to rationalize.

You can create a 'window' or 'screen' abstract base class which the input manager stores a reference to whichever is active. From there, it's like your standard finite state machine.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on April 25, 2013, 07:33:06 AM
Update:

I just got finished preparing a new version of the MiniRL now with the RenderManager upgraded to a RenderSystem that takes in graphics components. What do you think?:

http://www.mediafire.com/?f8lapm13tkk3vbl
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: Robobot on May 04, 2013, 01:12:25 AM
Very interesting topic, thanks for the input so far!
I've been looking into the concept and my main problem is how to deal with systems that have to deal with different kinds of entities.
For example, how to deal with a situation like this. We have a city building game, with buildings and peasant who will automatically react to some situations. Suddenly a building is set on fire. A peasant who currently has nothing to do should immediately try to extinguish the flames.
My first idea would be to make the system that set the building on fire emit an event, which would make an UnemployedPeasantSystem add an ExtinguishFireComponent to some peasant.  According to requerent, this is probably not the best idea, and it would be better to not mix event- and component/entity-based programming.
Another way would be to have some kind of FireBrigadeSystem that handles all BurningComponent entities. This system would then pull all jobless peasants from the entity manager and add an ExtinguishFireComponent to one of them. This seems to be the way that Artemis for Java prefers. Somehow this does not seem right to me, as one system pulls entities it did not originally subscribe to.

More generally, how do we handle updates on entities the current system is not subscribed to? Or, in a more general sense, how do we handle tasks without knowing who might handle them?
Thanks a lot!
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on May 04, 2013, 03:18:09 AM
Quote
My first idea would be to make the system that set the building on fire emit an event, which would make an UnemployedPeasantSystem add an ExtinguishFireComponent to some peasant.  According to requerent, this is probably not the best idea, and it would be better to not mix event- and component/entity-based programming.

I did say that, but at the same token-- many people have a lot of success mixing them.

One thing I dislike about events is that you need to have a strong idea of what everything does before hand. One of the advantages of components is that you don't need to know anything. When you mix them, you can add events as you go along that get triggered by component systems, but you really shouldn't have to be doing this. The system should do all the event management internally.

Edit: Most major game engines (like UDK or Unity) use a hybrid type system where component systems raise events associated with those systems-- however, this is just a tool for interfacing with an engine. It's better to have the low level access necessary to make your own systems and subvert the need for events.

Quote
More generally, how do we handle updates on entities the current system is not subscribed to? Or, in a more general sense, how do we handle tasks without knowing who might handle them?

Systems only work with specific components, not entities. They should never need to know more about an entity than what is in their respective system. A component.owner sort of thing is important though, as you may want to add components to entities within a system. This is true even when a system uses multiple components of the same entity-- it's just important to keep internal references to components parallel.



Quote
Another way would be to have some kind of FireBrigadeSystem that handles all BurningComponent entities. This system would then pull all jobless peasants from the entity manager and add an ExtinguishFireComponent to one of them. This seems to be the way that Artemis for Java prefers. Somehow this does not seem right to me, as one system pulls entities it did not originally subscribe to.

Think about what an entity represents. The problem your having has less to do with components vs entities and more to do with AI.

You have an emission of information into the game world- IE, a burning building.
You have an entity sense that emission and then adopt a particular behavior- IE, a peasant begins dousing the fire.


First we need to rationalize what a building is. Are buildings discrete entities (like in an RTS) or do they contain other entities (like in the SIMs)? I'm assuming that your buildings are discrete, but it's okay if they are not. A building and/or the entities/components that make up the building might have some kind of description to indicate who they belong to, whether it's a faction or an individual.

Then we need to rationalize what it means to be burning. We'd probably implement a fire propagation system and a burning component. This will work for discrete or container buildings, as we only care that something is burning and that there exists an entity who cares that it is burning. A fire propagation system would care about the materials of an object, the objects adjacent to it, world properties like wind and humidity, and as many other things that you may or may not want to deal with.

Then we need some way to alert the AI that they need to do something about it. The question is-- How do we alert them? An emission scheme might be more complicated than your looking for, but it would basically be a map that has sensory data that is significant to an AI. If you just need to send a message directly to all entities to clean up fire, then a FireBrigadeSystem, as you suggest, would make sense.

The FireBrigadeSystem works with AI components and Burning Components. It would just match up ownership/factions/concerns with problems, and then use whatever heuristics that the AI represents to WEIGHT a goal and add it to that entity.

So-- what you can do is have GoalComponents that are attached to entities. When we get to the DecisionSystem, we analyze that entity's goals and choose its behavior accordingly. FireExtinquishingGoal might include information about the location of the fire or a reference to a burning entity, or it might just be managed by the BehaviorSystem which could do a 'closest fire' sort of heuristic. You can nest goals in a single component if you want, but it shouldn't be a big deal.

Alternatively, you can have a set of goals that describe an entity's behavior and weight them based upon emission data. This will prevent a peasant from starving to death even though he's trying to put out a fire.



I think AI schemas work most naturally with component systems- as all we do is update weights according to emissions and our entities will act in their best interest. I posted some thoughts on Sensory Systems in another thread, which got a response that briefly discusses a way of managing AI that works incredibly well with component systems.

http://forums.roguetemple.com/index.php?topic=3289.msg27242#msg27242
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: Nymphaea on May 04, 2013, 06:18:18 PM
I have been working on a framework of my own, and will probably have more questions eventually as I get my head around the idea, but thought I'd chip in with an idea related to events.

Instead of making an event system as a whole, you could make an event component for specific systems to communicate. The first system evaluates that something is happening, so it adds the data about it to a component. Other systems check the same component, and act upon it.

I also agree though that this seems more like a mapping problem. You should have some form of map state access for all entities, so they can inquire to what is around them. You could go and ask the map "is this tile on fire?" and if it returns true, then the entity will act accordingly.


As for my own question, how would you suggest dividing up the code in a component based framework? Mine is similar to the article posted earlier, without the nodes. Engines store entities and systems, entities store components, and systems reference entities they work with, making it someone key-shaped I suppose. I was originally planning to make a LogicEngine and a RenderEngine, but I'm starting to realize that I should probably split it up even more than that, such as having a separate GUIEngine from the game's RenderEngine.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on May 04, 2013, 07:48:31 PM
Instead of making an event system as a whole, you could make an event component for specific systems to communicate. The first system evaluates that something is happening, so it adds the data about it to a component. Other systems check the same component, and act upon it.

That's the whole point. Systems are the message handlers and creators. You CAN use components as flags or put flags on components for other systems to look at, but you shouldn't NEED to do this. The transmutation of component data should be enough for other systems that use that data to perform their functions properly.

A good example is a Collision Detection System and a Collision Handling System. Suppose we're in a real-time simulation that needs super-precise continuous collision detection. For that to work, we need to have a system to interpolate the physical integration of forces over time. We also need to able to extrapolate from our current orientation to the next collision that would occur within a tick. However- the physical state of our simulation needs to update for ever collision in chronological order.

A quick solution is to make these systems co-routines that yield to one another based upon an Alpha. Essentially, we would make our game/simulation a Finite State Machine of systems- or rather, system-states. We just meander to different system-states when we need to perform some modifications to the data.

Quote
As for my own question, how would you suggest dividing up the code in a component based framework? Mine is similar to the article posted earlier, without the nodes. Engines store entities and systems, entities store components, and systems reference entities they work with, making it someone key-shaped I suppose. I was originally planning to make a LogicEngine and a RenderEngine, but I'm starting to realize that I should probably split it up even more than that, such as having a separate GUIEngine from the game's RenderEngine.

Divide it according to the minimal use-case. If a system only uses X components for something, for example, you may want to split your X and Y location components up (though it's typically okay for a system to work on a position component that contains both X and Y components even if it only works on one).

The idea is to prevent the need to duplicate any data but keep logical components isolate. A position component is used by both the renderer and the physics simulator, but a force component is only used by physics- so it should be its own component. You can rationalize it further by applying multiple forces throughout components and then evaluating/applying velocity when we need to update.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 04, 2013, 09:45:01 PM
When is each system's "update" function called, in a turn-based non-real-time game like a roguelike?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 04, 2013, 09:53:22 PM
(deleted)
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on May 04, 2013, 10:29:47 PM
When is each system's "update" function called, in a turn-based non-real-time game like a roguelike?

On each logical tick, we wait for input that will manifest as a player action. Once we get a player action, perform it and continue in the loop.

In a turn-based game, you typically want action-resolutions to occur on the same turn, in which case you're going to update each system per entity, instead of each entity per system. This literally just means inverting the game loop so that you do something like,

Code: [Select]
foreach(entityID:entityIDs) foreach(system:systems) system.update(entityID);
Where one of the systems is an input handling one that waits for user input.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: Robobot on May 04, 2013, 11:53:23 PM
Thank you, requerent and Nymphaea, very much! This makes it much clearer. Also the linked thread on sensory systems is quite interesting.
On a different note, I really enjoyed your blog, requerent. Keep it up! And as you seem to like Lua, I'm currently reading Programming in Lua, 3rd Edition and like what I've seen so far (half way through). The best part is that there don't seem to be any WTF?! moments I've come to expect when looking at a new language. Also the book is very well written.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 05, 2013, 12:42:15 AM
When is each system's "update" function called, in a turn-based non-real-time game like a roguelike?

On each logical tick, we wait for input that will manifest as a player action. Once we get a player action, perform it and continue in the loop.

In a turn-based game, you typically want action-resolutions to occur on the same turn, in which case you're going to update each system per entity, instead of each entity per system. This literally just means inverting the game loop so that you do something like,

Code: [Select]
foreach(entityID:entityIDs) foreach(system:systems) system.update(entityID);
Where one of the systems is an input handling one that waits for user input.

Though you don't want to get input for every entity in the game, just the player, no?

As if the input system waits whenever its update(<entity>) function is called, then you'll get a lot of useless waiting where it waits for input for every monster as well as the PC. So do you have some kind of "input component" on the PC that other entities don't have, and the input system checks for this component, and if there's one present, waits for input, then updates the component with whatever input is given?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: Nymphaea on May 05, 2013, 12:56:47 AM
I think it comes to how it's structured, though the component system does seem better geared to real-time / tick based games than turned based. My framework has the ability to disable systems, or even entire engines. That is probably how I would do it, disable all logic except an "InputEngine", and the rendering ones. Once that input has been obtained, enable the other systems again and let them act until they can't (the player entity sets a flag saying it needs input) and then repeat.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 05, 2013, 01:14:33 AM
@requerent: In one of your earlier messages you mentioned how one does not need events or messages in a component system. Now does that latter bit mean that I should do away with the "handleMessage" stuff on the components in my test program?

I got the whole "send messages to the components" stuff from reading this:
http://www.gamasutra.com/blogs/MeganFox/20101208/88590/Game_Engines_101_The_EntityComponent_Model.php

Quote
class BaseComponent {

virtual void Startup()

virtual void Update()

virtual void Shutdown()

virtual void HandleMessage(MessageType message) .... }

...

What do you think? Should a component just be raw data (which would mean we wouldn't even have a class... just a struct(!) Wow, that's really departing from usual "OO" ideas...!)?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: Nymphaea on May 05, 2013, 01:37:41 AM
That is the basic idea, you can add some basic access methods that would be used a lot.(for instance, there is a "move()" method in my PositionData class that adds a vector to the current position, and the command to modify health in HealthPointData won't allow it to go below 0 or above 'healthMax')

I think a good way of thinking of it, is to think of a component as a new type. It's there to store data. Some types have methods associated with them, but nothing far reaching.


As for the component code you linked, I think it misses the point. The idea for a component system is that the System contains all the logic code, and uses data from components. There shouldn't be an update method in the components. Your "BaseComponent" looks more like "BaseSystem" to me, but missing the methods to associate entities/components to it(I associate entities, the article on the first page associated nodes full of the components)
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 05, 2013, 01:54:01 AM
That is the basic idea, you can add some basic access methods that would be used a lot.(for instance, there is a "move()" method in my PositionData class that adds a vector to the current position, and the command to modify health in HealthPointData won't allow it to go below 0 or above 'healthMax')

I think a good way of thinking of it, is to think of a component as a new type. It's there to store data. Some types have methods associated with them, but nothing far reaching.


As for the component code you linked, I think it misses the point. The idea for a component system is that the System contains all the logic code, and uses data from components. There shouldn't be an update method in the components. Your "BaseComponent" looks more like "BaseSystem" to me, but missing the methods to associate entities/components to it(I associate entities, the article on the first page associated nodes full of the components)

Thanks. I'll see if I can roll out a new version of the mini program with the changes discussed so far.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on May 05, 2013, 07:59:57 PM
When is each system's "update" function called, in a turn-based non-real-time game like a roguelike?

On each logical tick, we wait for input that will manifest as a player action. Once we get a player action, perform it and continue in the loop.

In a turn-based game, you typically want action-resolutions to occur on the same turn, in which case you're going to update each system per entity, instead of each entity per system. This literally just means inverting the game loop so that you do something like,

Code: [Select]
foreach(entityID:entityIDs) foreach(system:systems) system.update(entityID);
Where one of the systems is an input handling one that waits for user input.

Though you don't want to get input for every entity in the game, just the player, no?

As if the input system waits whenever its update(<entity>) function is called, then you'll get a lot of useless waiting where it waits for input for every monster as well as the PC. So do you have some kind of "input component" on the PC that other entities don't have, and the input system checks for this component, and if there's one present, waits for input, then updates the component with whatever input is given?

You DO want to get input for ALL entities. Just try to realize that the input isn't coming from a keyboard. The input might be better rationalized as a command or instruction. The AI gives commands to their respective avatars just as the player would-- the only difference is that the human interfaces with a keyboard.

You can have separate systems for this-- Such as an InputSystem to fetch the command for the player, but realize that only the player character's entityID and components are subscribed to that system. So it's fine to call all systems on every creature's turn, because each system is only going to do anything if that entityID is used within it's internal component references. I use entityID as a way to indicate to systems to only update one entity at a time- which is necessary for a turn-based game.

Quote
@requerent: In one of your earlier messages you mentioned how one does not need events or messages in a component system. Now does that latter bit mean that I should do away with the "handleMessage" stuff on the components in my test program?

I got the whole "send messages to the components" stuff from reading this:
http://www.gamasutra.com/blogs/MeganFox/20101208/88590/Game_Engines_101_The_EntityComponent_Model.php

She's talking about short-cutting the Component-System idea for broadcast messaging. That is-- you may want to send out global, component-type, or entity-local messages that components capture to perform data transformations on themselves. These transformations could result in other broadcast messages being thrown and... all of a sudden you've begun contradicting the whole point of components.

If you need something like that, the component solution is to just make another system/sub-system that deals with that case specifically. Systems are intended to be logically discrete objects-- they can be numerous and as short as possible.

She goes on to say that you can flexibly solve a larger domain of problems by separating the logic and the data, http://www.gamasutra.com/blogs/MeganFox/20101208/88590/Game_Engines_101_The_EntityComponent_Model.php#comment76795

Code: [Select]
What do you think? Should a component just be raw data (which would mean we wouldn't even have a class... just a struct(!) Wow, that's really departing from usual "OO" ideas...!)?
Other languages have stronger ways of rationalizing data (Like SQL). All that matters is that the system is reading data in manner that is expected. You could use structs, linked lists, or tables. Having a 'Type' isn't necessary or even important. But yes- in C++, you'd most likely use a struct.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 05, 2013, 09:22:33 PM
@requerent:

Thanks. I'm wondering, though: isn't the system supposed to contain a list of components (it was mentioned that a rendering system has a list of graphics components in it and that's how it is in my newest MiniRL program)? Yet update doesn't update by component, but by entity. Yet if all the system contains is components, how does it update by entity? Or does update(entity) go through the list of components of the entity and work only on those components that are relevant to that system?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: Nymphaea on May 06, 2013, 01:27:50 AM
It depends how your system is set up. Mine personally has the entities in the system, and it just pulls the components it needs itself. For a by entity approach when the system contains components, you could have the components keep a reference to the systems that use them, so that calling an update method on the entity would go through the components and call on the systems they have. Just remember to either keep track of which systems were already called, or have the system only add itself to one of the components it uses.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on May 06, 2013, 05:19:07 AM
@requerent:

Thanks. I'm wondering, though: isn't the system supposed to contain a list of components (it was mentioned that a rendering system has a list of graphics components in it and that's how it is in my newest MiniRL program)? Yet update doesn't update by component, but by entity. Yet if all the system contains is components, how does it update by entity? Or does update(entity) go through the list of components of the entity and work only on those components that are relevant to that system?

I thought that might've been confusing.


Say we store our entities in a Hash Map or a Dictionary. The Key used for the dictionary represents the entity and it points to a list of components.


A system only need to know of components that deal with it specifically, but it also needs to know of the entity so that it can add new components if necessary. We get an access-time speed-up by keeping a local array of references in the System, and we can use the EntityID as a way to keep multiple arrays of components parallel. For example, when we evaluate Position and Velocity, we need to know which velocity and position represent an entity- we can keep an internal parallel array to do this. For a turn-based game, we need to ensure that each System's internal array of component references are ALL parallel, so using a unique EntityID is the solution. Alternatively, you could pass the entity and parse the entity data each system update, but I think that's poor data management.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 15, 2013, 12:56:10 AM
So does the System store copies of the components itself or just take references (IDs) to the entities and look them up in the entity database and work on what's in there, or something else?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on May 15, 2013, 01:23:34 AM
So does the System store copies of the components itself or just take references (IDs) to the entities and look them up in the entity database and work on what's in there, or something else?

Do whatever makes sense to you.


I think having a local array of references that use the entity ID makes the most sense to me. However, there isn't always a 'right' way to manage your data. Do what makes sense to you.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 15, 2013, 01:29:06 AM
Ah, OK. Thanks.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 30, 2013, 04:08:25 AM
So does the System store copies of the components itself or just take references (IDs) to the entities and look them up in the entity database and work on what's in there, or something else?

Do whatever makes sense to you.


I think having a local array of references that use the entity ID makes the most sense to me. However, there isn't always a 'right' way to manage your data. Do what makes sense to you.

I've come back to this recently and am confused now: "local array of references" to what, exactly? To components? And by "local", you mean local to the system, right? If so, don't we still have to loop through the main entity data on every "update(entityID)" call to keep that local (to the system) list of components "up to date" (i.e. if components were added or removed, we have to catch that)? If so, then why bother with the local array of references to components? You're still looping through the entity data to get the relevant components anyway...
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on May 30, 2013, 06:24:26 AM
It just depends on how you feel comfortable organizing your data. Just do what makes sense man. You should avoid iterating through components for each entity though- that's just a lot of wasted looping/checks.

Local references of parallel arrays is one way, unique keys for component-types is another, and I'm sure there are some other clever ways to do it. Looping through every component for every entity for every system, however, isn't a good idea.

An optimization like this, however, can be accomplished later. Make a game first with what makes sense, then you can speed things up in whatever way makes sense for your application.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 30, 2013, 06:22:26 PM
It just depends on how you feel comfortable organizing your data. Just do what makes sense man. You should avoid iterating through components for each entity though- that's just a lot of wasted looping/checks.

Local references of parallel arrays is one way, unique keys for component-types is another, and I'm sure there are some other clever ways to do it. Looping through every component for every entity for every system, however, isn't a good idea.

An optimization like this, however, can be accomplished later. Make a game first with what makes sense, then you can speed things up in whatever way makes sense for your application.

Thanks again.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on May 31, 2013, 03:46:25 AM
WOW! Just hours after that last "thanks" post ...

... MiniRL 2.0 is finished! (Architecture practice/test program)

See here:
http://www.mediafire.com/download/uv6paykwdy2qrgr/minirl-2.0.tar.gz
(edit: made a last-minute correction to the program)

Is this better now? I'm now wondering about:

1. Time management -- If one "turn" is counted as one loop through all the entities, then how do you handle, say, monsters that can act more than once per turn ("fast" monsters that get multiple attacks per turn, etc.)? Can the usual time-management techniques be combined with the ECS architecture? For example, would it be "OK" to, for example, employ some traditional roguelike time-management technique like the "speed queue" mentioned here:

http://forums.roguetemple.com/index.php?topic=3206.msg26406#msg26406

with ECS? Namely, when something has a zeroed timer, you then call all the system updates for that entity, or something along these lines.

2. Collisions -- how do we handle them? Namely, the difficulty arises with stuff like this:

Code: [Select]
...@..@...
 -->  <--

....@@....
  --><--

*COLLISION!*

This is OK. BUT...

Code: [Select]
     -->
....@@....
    -->

Both entities are to move 1 step in the indicated direction this turn, simultaneously. So they shouldn't collide. Yet suppose that the left entity comes before the right one in the update order (since the updates are done in a sequence, one has to come before the other). Then it gets its movement and collision system calls first and they register a collision with the right entity, then the right entity gets updated and moves to the right as well. Since both were supposed to be moving simultaneously, this collision is spurious (a bug). How should one do the collision detection so as to avoid this? Also, another problem: it seems the movement system must not try to move the entities in scenario 1 on top of each other, but must stop for the collision, which means the movement system "knows about" the collision in some sense. Would it be "proper" for the movement system to then raise the collision flag itself? If not, then how is the collision system supposed to know that an entity "right next to" another on the map has actually collided and not just "brushed by"?

Also, for efficiency reasons, there needs to be some way to quickly know whether or not an entity is in a given tile on the map. Yet entity positions are not stored as markers on the map, but as coordinates in position components (and if we did store markers on the map, then we'd have to somehow guarantee they are updated every time the position component is modified. Though that may not be so much of a problem -- the movement system knows of the map anyways, so if it's the only thing that changes entity positions (it should be, I'd think -- movement should be the responsibility of that particular system, no?), then it can also tell the map to update its markers). What should one do to make the check-for-entity process involved in collisions efficient?

Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on June 01, 2013, 02:43:16 AM
Oh.... Heh.... Some of my previous advice may not be entirely correct. Excuse me-- You don't loop through each system per entity for a turn-based game, you only allow one entity to take an action per looping of each system.

The system that determines which action, if any, that an entity takes (inclusive of the player and AIs), will reschedule that entity's next opportunity to take action within a priority queue (the priority being the speed-cost of the action taken). Otherwise, the game updates somewhat like a real-time game. There are plenty of solutions here, but a priority queue is elegant. You just want to make sure you only get one entity's action per turn.

There are a couple of ways to approach turn-based physics. You can have everyone pick actions synchronously and simulate, but this can make it very difficult for a player to understand what is going on. I think it's best to have a single entity perform an action per game update.

This doesn't really cause problems for realistic physics so long as you have a little foresight. You can use 'idle' states and 'moving' states to indicate that an entity moved last turn or stayed in the same position. That way, if two enemies are charging at one another, you can resolve it in a way that is consistent with their actions. Alternatively, you can store a velocity or force on an entity to be used when evaluating collisions, you just clear it out the next time the entity moves.

Your entities should be making decisions in relation to the state of the game- inclusive of the positions of other entities. In this sense, you probably want to keep a map of entities/properties cached. This should make detecting hits trivial.

Note, a Map IS also an entity that stores the relative locations of other entities. When they move, the state of the Map is also updated.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on June 01, 2013, 09:37:12 PM
Oh.... Heh.... Some of my previous advice may not be entirely correct. Excuse me-- You don't loop through each system per entity for a turn-based game, you only allow one entity to take an action per looping of each system.

You mean for every update call for every system, the entity takes an action? That doesn't seem to make sense. Also, does this mean only one entity acts per turn?

The system that determines which action, if any, that an entity takes (inclusive of the player and AIs), will reschedule that entity's next opportunity to take action within a priority queue (the priority being the speed-cost of the action taken). Otherwise, the game updates somewhat like a real-time game. There are plenty of solutions here, but a priority queue is elegant. You just want to make sure you only get one entity's action per turn.

So then the "action system" not only stores a list of "action components" (see game code), but should also store a priority queue with the speed-based timers?

And what do you mean, "you only get one entity's action per turn"? It sounds like only one entity acts per turn.


There are a couple of ways to approach turn-based physics. You can have everyone pick actions synchronously and simulate, but this can make it very difficult for a player to understand what is going on. I think it's best to have a single entity perform an action per game update.

Does one "game update" equal one "turn"? If so, then wouldn't that mean, e.g. only one monster moves every turn? (?!)

This doesn't really cause problems for realistic physics so long as you have a little foresight. You can use 'idle' states and 'moving' states to indicate that an entity moved last turn or stayed in the same position. That way, if two enemies are charging at one another, you can resolve it in a way that is consistent with their actions. Alternatively, you can store a velocity or force on an entity to be used when evaluating collisions, you just clear it out the next time the entity moves.

Your entities should be making decisions in relation to the state of the game- inclusive of the positions of other entities. In this sense, you probably want to keep a map of entities/properties cached. This should make detecting hits trivial.

Note, a Map IS also an entity that stores the relative locations of other entities. When they move, the state of the Map is also updated.

Head-on collisions (charging at each other) weren't the problem, the problem was "phantom" collision caused by the one-entity-at-a-time update when you have two entities next to each other moving in the same direction.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on June 02, 2013, 12:57:30 AM
Most games, if not all, are a simulated function of time. Turns are NOT the unit of time that a turn-based game is working with. A 'turn' is simply whenever an entity gets to perform an action. Most TB games use 'ticks' as their unit of time and a turn has a tick-cost associated with it. A player will experience time relative to how frequently s/he gets to make decision, but your game will simulate in ticks.

From a player's point of view, an enemy may move two spaces per turn. But in reality, the tick-cost for moving is simply half that of the player. The enemy's cost to move may be 50, whereas the player's may be 100-- but the game updates relative to ticks, not the player's idea of what a turn is. In this sense, your game is updating everything every single tick.

Now-- we need a system that manages who gets to take a turn. However you do it, you'll simply be waiting however many ticks before an entity gets to act, based on their action, make them wait however many ticks again. Ticks give us a lot more flexibility than basing our game on turns, but it isn't wrong to do the latter.

You avoid phantom collisions by updating the entire game every time an action is made. That way we'll know that the space is occupied before making a decision.
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: mike3 on June 02, 2013, 03:01:06 AM
Most games, if not all, are a simulated function of time. Turns are NOT the unit of time that a turn-based game is working with. A 'turn' is simply whenever an entity gets to perform an action. Most TB games use 'ticks' as their unit of time and a turn has a tick-cost associated with it. A player will experience time relative to how frequently s/he gets to make decision, but your game will simulate in ticks.

From a player's point of view, an enemy may move two spaces per turn. But in reality, the tick-cost for moving is simply half that of the player. The enemy's cost to move may be 50, whereas the player's may be 100-- but the game updates relative to ticks, not the player's idea of what a turn is. In this sense, your game is updating everything every single tick.

Now-- we need a system that manages who gets to take a turn. However you do it, you'll simply be waiting however many ticks before an entity gets to act, based on their action, make them wait however many ticks again. Ticks give us a lot more flexibility than basing our game on turns, but it isn't wrong to do the latter.

You avoid phantom collisions by updating the entire game every time an action is made. That way we'll know that the space is occupied before making a decision.

Oh, so in this case one then does an update for each system every tick like in a real-time game, not "per entity". So then our "update" functions on our Systems would not take an entity parameter, and instead they would update every entity (or at least, every entity that has been entered into that system with the addEntity() functions), just like in real-time. And each batch of updates (one per system for every system) constitutes one "tick" of the simulation. And only one entity acts per tick (or, perhaps, only those entities which have had their time-to-next-action (on the priority queue in the action system) hit zero). Is this right?

But you say "update every time an action is made". So does this mean we need a loop with core like this:

Code: [Select]
if(actionSystem.update()) // returns true iff some entity acted
{
  // update all other systems
  ...
}

?
Title: Re: Playing around with a new kind of program architecture: "component system"
Post by: requerent on June 02, 2013, 10:35:08 PM
You could do it like that.

Just realize that everything is an entity that could take actions- including propagating gas.