Skip to main content
GameDev.net gamedev.net
🔒 Locked

c++ Entity system- please try help if you understand entity systems

Started by j0rdant13 Mar 10, 2013 at 2:25 AM 18 replies 5.2k views
Original Post
j0rdant13
j0rdant13

Hi, i created an account to stress my problem. I have got a good grasp of C++ and i want to create a simple text game to put to use what ive learnt. Ive just finished(after many hours) learning about 'Entity systems'. Although i have read alot i have not seen someone give an example or a tutorial for beginners. Literally all i want to do is have a silly text game/engine which i can learn from and add to what ive learnt/learning.

To the point. If someone can help me and post in here a barebones entity system- using a hash table i would be over the moon! All i want to use it for is to learn about the whole system and to add to it and hopefully do this: i want to use it to create a text game. Create objects, create monsters, a player and have them interact- like attack, lower HP etc and display the outcome to the command window and then progress it further. So yeah, if someone can wrote me up some .cpp and headers for what i need i would be so happy :) .

Thanks!

Nercury
Nercury

A good grasp of C++, simple text game, many hours learning.

Literally all i want to do is have a silly text game/engine which i can learn from and add to what ive learnt/learning.

Ok, it is easy enough. Find C++ compiler which can build your program and start putting things you have learned in practice.

Maybe what you think "Entity System" is will turn out to be something simple, like a class hierarchy.

j0rdant13
j0rdant13

A class hierarchy is what i dont want to do, i want to stay away from inheritance because it will create spaghetti code when creating more and more code. I just wish there was an example of a basic Entity system

Xelvair
Xelvair

From my own experience, you shouldn't go for Entity-Systems, especially if you haven't created games in C++ before. Some time ago I've made my own framework that resembled the Artemis framework for Java. But the problem with Entity-Systems is that

  • You'll be copy-pasting code all over the place, writing millions of getters and setters just to create your classes without any functionallity.
  • There are a few ways to do communication between components, but all of them have drawbacks.. either you increase dependency, or you have to do some expensive tasks like message dispatching etc.

You stated that you dislike the oldschool Hierarchy approach to game development, and indeed, it does have its drawbacks as well. But as long as you stick to this one important rule, you should be totally fine:

Favor composition over inheritance

Basically, whatever you can achieve through composition, do that. And if you really have to fall back on inheritance, then there's probably a very good reason for that. Remember: Just because inheritance isn't good when used all over the place, it's still a very handy tool in quite a bunch of cases!

Greetings,

Xelvair

Khatharr
Khatharr

You'll be copy-pasting code all over the place, writing millions of getters and setters just to create your classes without any functionallity.

.1294201057429_27924.jpg

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
larspensjo
larspensjo

Have a look at entityx.

It is a library that implements the ECS pattern. I have tested it, like it a lot and found it to be very efficient. At the readme (found at the link), you will also find a tutorial that shows how to use the library.

There are some possible disadvantages with this library:

  • It is written in C++11, which can make it harder to understand if you don't know the language.
  • It depends on some external libraries, (Boost and Glog), and on cmake to install. (I have a patch that removes the dependency of glog).

Please ask if you are uncertain or have problems!

I suppose you want the hash table to make an efficient search for entities using specific components? One the one hand, it should be possible as the implementation of Entityx creates a unique id for each component. On the other hand, the library allows for attaching a variable number of components to entities, and provides iterators that finds all entities for this variable list of components. A discussion on the possibilities here would be interesting, and I am sure the library can be extended if a good design is found.

WillTice
WillTice


So yeah, if someone can wrote me up some .cpp and headers for what i need i would be so happy

I don't think anyone is going to hold your hand and give you a bunch of code, either here or on the Allegro forums. You need to make some effort to understand the concepts yourself and at least attempt to solve the problem.

If you're interested in learning, I found a couple interesting posts about entity-component-systems.

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

http://www.chris-granger.com/2012/12/11/anatomy-of-a-knockout/

Xelvair
Xelvair


You'll be copy-pasting code all over the place, writing millions of getters and setters just to create your classes without any functionallity.

.1294201057429_27924.jpg

Im curious, how do you suggest writing getters and setters without writing getters and setters?

AgentC
AgentC

If the components are totally just data containers they could be structs with public data. Alternatively the systems acting on them could be declared friend classes.

However, IMO it's too rigid to always have components with no functionality and just systems acting on them. In some cases it makes sense that a system updates a mass of components (physics, particles, animation) but eg. a game logic component could just as well update on its own.

Unity provides a fairly sane component-based scene implementation. I don't think one will go terribly wrong by copying it to some degree.

LorenzoGatti
LorenzoGatti


Im curious, how do you suggest writing getters and setters without writing getters and setters?

Obviously, by not needing a lot of trivial getters and setters.

In good design, there are about 4 cases:

  • Getting or setting the property isn't really needed, so adding getters and setters is positively harmful.
  • You access and modify object state from a closely related class or function (in C++, probably declared as friend) that is allowed to depend on the internal details of your class, so you can get and set fields directly without gratuitous complication.
  • You access and modify object state in a way that ensures proper encapsulation, using high level and nontrivial methods (e.g. character-character collision tests rather than querying position and size and figuring it out) rather than fine-grained getters and setters.
  • You really need an important operation that reduces to getting or setting some field, but it is a special case of good API design, not boilerplate.

It should also be noted that creating boilerplate code is the perfect job for C++ templates and macros: if you really want useless and dangerous trivial getters and setters you can (and should) write them without writing them.

Omae Wa Mou Shindeiru
larspensjo
larspensjo


There are a few ways to do communication between components, but all of them have drawbacks.. either you increase dependency, or you have to do some expensive tasks like message dispatching etc.

This is an interesting problem, and maybe one of the important issues with Entity component systems. I think it is possible to design an ECS solution that is robust, efficient as well as easy to read. For high frequency data, you use the usual components. For example, the render function would use a "Position" component to know where to render. This, and similar things, are time critical tasks and must be fast.

Then there is less frequent things, which can be managed through events (message dispatching). As you say, they are more expensive from an efficiency point of view. However, you would not use them in high frequency tasks. You would use them as special events, e.g. when a monster is killed, when someone is hit by a weapon. That way, the extra cost could be negligible.

There is also this recent discussion: http://www.gamedev.net/topic/639810-component-programming-i-think.


You'll be copy-pasting code all over the place, writing millions of getters and setters just to create your classes without any functionallity.

Copy-paste code is a certain sign of problematic design. But I think some ECS implementations don't use getters and setters for components. The component is just a minimal PlainOldData container.

For example, if you have a position component declared as


struct Position {
    vec3 coordinate;
};

Then there isn't much use for a getter to hide the implementation. I realize this is in some conflict with object oriented programming. But the idea is to move the logic to the Systems, from the data containers. One thing that you lose with ECS, is the principle of having the logic packed together with the data (encapsulation)?

Six222
Six222

A class hierarchy is what i dont want to do, i want to stay away from inheritance because it will create spaghetti code when creating more and more code. I just wish there was an example of a basic Entity system

And how do you know this, have you tried writing an application in this way? Yeah it CAN lead to spaghetti code only if you design it poorly. You should never just take advice from the internet and say that it's bad beacause somebody said so..

larspensjo
larspensjo


And how do you know this, have you tried writing an application in this way? Yeah it CAN lead to spaghetti code only if you design it poorly. You should never just take advice from the internet and say that it's bad beacause somebody said so..

Please don't be so negative. The OP started this thread with the intention to do an implementation and learn from it. In my opinion, that is the best way to learn, when combined with reading and discussions. Not just reading what other says, but actually assess for yourself. This should be encouraged, and I hope to learn something myself from the effort of others.

freeworld
freeworld
Granted ive never built a full blown entity system... major use of composition isnt quite the same thing. But even just from theory... the idea of more than one getter or setter seems odd to me I. The context of an entity/component system. Since everthing need to be arbitrary and vague it doesnt seem logicical toe to have finite even concrete getters and setters.

Youre getter should be something alng the lines of get (string variableName) and thats all. If a compone t cant handle get (health) thats because it doeant have that value. Why should you allow every component to have a getHealth () function... sounds more like youre trying for inheritance... but decided you still wanted every object t have the sameemebers just a different name.

KISS and dont look back.
freeworld
freeworld



And how do you know this, have you tried writing an application in this way? Yeah it CAN lead to spaghetti code only if you design it poorly. You should never just take advice from the internet and say that it's bad beacause somebody said so..

Please don't be so negative. The OP started this thread with the intention to do an implementation and learn from it. In my opinion, that is the best way to learn, when combined with reading and discussions. Not just reading what other says, but actually assess for yourself. This should be encouraged, and I hope to learn something myself from the effort of others.
freeworld
freeworld



And how do you know this, have you tried writing an application in this way? Yeah it CAN lead to spaghetti code only if you design it poorly. You should never just take advice from the internet and say that it's bad beacause somebody said so..

Please don't be so negative. The OP started this thread with the intention to do an implementation and learn from it. In my opinion, that is the best way to learn, when combined with reading and discussions. Not just reading what other says, but actually assess for yourself. This should be encouraged, and I hope to learn something myself from the effort of others.

Talking isnt learning... rethink your post. Ill agree with six. Less talking more coding. When you have a problem... then ask for help. For jow this reads as the thousands of post ive made then discards before posting. A thoght in the head and you just jeeded to say it outlud to fully grasp it.

And im jot discouraging the op in any way. I say code this system now. Then look at it... then youll know how it actually works and probably how you can make ot work better.
phil_t
phil_t

Youre getter should be something alng the lines of get (string variableName) and thats all. If a compone t cant handle get (health) thats because it doeant have that value. Why should you allow every component to have a getHealth () function... sounds more like youre trying for inheritance... but decided you still wanted every object t have the sameemebers just a different name.

If we're talking about entity/component systems, typically you would have something like a "health" or "stats" component that would have a strongly-typed Health property on it (along with other things that might make sense to go along with that, such as MaxHitPoints, or Condition). It's certainly not a case of every component having a Health property. If those things don't apply to a particular entity, then it simply doesn't have a "health/stats" component attached to it.

What you seem to be describing sounds more like a property-centric architecture, where each entity is basically just a property bag. While that is a valid approach too (the book "Game Engine Architecture" describes a system like this), it's not what I've typically understood entity/component architectures to be.

You'll be copy-pasting code all over the place, writing millions of getters and setters just to create your classes without any functionallity.

I don't quite understand what you mean (or how this is specific to entity/component systems). Also, if you use Systems for all the logic and have Components simply represent data, the Components can simply be dumb structs. Even if you put get/set accessors on them, I don't see that as a big deal.

There are a few ways to do communication between components, but all of them have drawbacks.. either you increase dependency, or you have to do some expensive tasks like message dispatching etc.

As I think I mentioned in the other ongoing thread about this, Systems (which operate over Entities that have a certain set of Components) go some way to solving this. If Components are simply data, then there is no need for them to communicate. I've still encountered similar problems with Systems needing to communicate with each other though: basically, one system generating temporary per-entity data that is useful for another system to use. One example would be the system that generates the final transform for an entity - this information then needs to be used by other systems, such as the rendering system.
pinebanana
pinebanana

One example would be the system that generates the final transform for an entity - this information then needs to be used by other systems, such as the rendering system.

Wouldn't you just update the system that transforms an entity first, and leave rendering to the last system that wil be updated.

anax - An open source C++ entity system
phil_t
phil_t

Wouldn't you just update the system that transforms an entity first, and leave rendering to the last system that wil be updated.

Yeah, that's basically what I do. Then the question is, do you store this data back in a Component, or do you store it in the system and have one system request it from the other? (I do the former in this scenario).

Another example is I have a system that assigns entities to partitioned space for efficient line-of-sight queries. Other systems then communicate with this system to make line-of-sight requests. In this case the data is stored in the system.
larspensjo
larspensjo


Another example is I have a system that assigns entities to partitioned space for efficient line-of-sight queries. Other systems then communicate with this system to make line-of-sight requests. In this case the data is stored in the system.

I suppose this could also be done with a partition component. That way, you don't need to communicate between systems. I don't say it is right or wrong, just two ways of doing it.

One example I can think if where using a partition component could be a problem, is if there are very many entities. You would need to iterate through all of them, even if you just wanted to access those in a specific partition.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.