Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Nohup

Member Since 19 Mar 2004
Offline Last Active Feb 28 2013 10:40 AM

Posts I've Made

In Topic: Special Rules in a Turn Based Entity Component System

16 January 2013 - 02:00 PM

Well, if I'm reading you correctly, it seems the issue you have is with event communication.

 

The "Event" that is occurring is a dice roll.

Ignoring everything else,  the event taking place is a dice roll.

 

Now, from what you describe, there are a number of dice-roll types that can occur.  2-dice, 3-dice-subtract-lowest, 4-dice, etc.

Those events must be communicated to all interested components.  The most generic way to do that is to broadcast the type of dice-roll, and then the dice.

 

Broadcast(4-DICE-ROLL_ENUM, 6,3,2,6)  //where the enum tells what kind of roll, and the 4 numbers tell what the rolls were.

 

You can package the message up in a million different ways, the important part is entities and/or their components need to hear about it, and react by changing their internal state, and/or sending out their own messages.  One of the entities/components may score that roll as a hit, and set it's internal state to dead, while sending out a "Died" broadcast message to all the other entities/components.

 

So, to directly answer your question, I guess you would say you "put the logic of the ability into the components".  Because they have to deal with these events as they see fit.


In Topic: Cache friendly dynamic allocation

14 December 2011 - 08:18 AM

I think there's an issue with the use of the word "alignment" in your post.
That word has a slightly different meaning than what you're considering. It's more to do with the exact placement of something within the memory banks of a machine along certain boundaries (byte, word, page).

If I read you right, then you don't really care about exactly where a thing is placed.
You're more concerned that all the things you make are placed in an orderly manner, and tightly packed, to get better cache utilization.

If that's the case, then you were going along the right path with your thoughts of using a vector to store your components.
The problem with a vector is that all the types in a vector must be the same. And from your code-snippet, you were thinking more of using a common interface to a set of different derived classes (components).

Your code snippet shows that you want to store pointers to various types of components. That's a pretty common method. But I'm afraid, that it is unlikely that those components will ever be near each other in memory (cache coherent).

The best you're likely to get, is having all of your components of a certain type together in memory. For instance, the "Health" components can all be pre-allocated in a vector/array, and can be tightly packed together.
Your entities will store pointers to those components (as in your boost:unordered data structure).
Then, if you can structure your code to run all of the entitiy's "health" processing at the same time, your cache-utilization will be very good.
Do this for every component type, and you should get most of what you're looking for.

Now, managing a whole bunch of vectors for every component type might be a bit daunting. Every time an entity is destroyed, you will have to remove it's components from their storage vectors, or somehow mark them as free. That can be a bit of a pain, and could lead to a lot of bugs. My advice is to use a freelist or some pooling allocator to do the job for you.
(Game Programming Gems 4 has a good article on freelists, and boost::pool has a nice implementation that you could use to help manage the lifetimes of the components

Once you have all the components in their homogeneous vectors, you might start looking for a way to just iterate over all the components within those vectors, without even considering what entity they belong to.
Like the health example, you could check all the healths to see if any are <0, and if so look up that health's entity ID, and create a message for that entity to "die".
Lots of flexibility in this setup, it's a lot like what I've been toying around with for a while.

good luck.

In Topic: Threading / Message Queue

29 November 2011 - 09:24 AM


Something that's working well for me right now to do a similar thing is a library called Zero Message Queue. (or ZMQ, or 0MQ)


While I don't dispute that message queues are great ways of moving messages around, they are not at all efficient for communication within a single process. There are several orders of magnitude more overhead in using a message queue, than using an in-process mechanism like a producer/consumer queue or a lockless FIFO.

Message queues are great when you want to move messages between different processes, and want to have certain guarantees about accepted messages being received by "someone."


All very true.
Although, zeroMQ does have an "inproc" socket, which is really a thin wrapper around a lockless FIFO.
It should surely be fast enough to move packets between the game and network threads.
It sounded like the OP was looking for a quick, easy, off-the-shelf way to move data between threads.
I use this to do work-queuing on a project now, it's so dead-simple to use, I just had to mention it.

In Topic: Threading / Message Queue

28 November 2011 - 10:59 AM

It seems like you're main question revolves around a good (efficient/safe/whatever) way to move data between two threads.
There are many ways to do this, some are easier, some are faster, no way is really wrong as long as it works.

Something that's working well for me right now to do a similar thing is a library called Zero Message Queue. (or ZMQ, or 0MQ)

It's another API to learn, but it's simple. It's fast enough for everything I use if for.
It's free, and extensible, so if you ever want to break this out into two processes, or two computers, instead of two threads, the API is nearly the same for both.

It's something to look at, I've been pretty happy with it so far for a similar application.
I wish someone would have pointed it out to me sooner.

Good luck with your project.

In Topic: Events and entity communication

28 August 2010 - 06:42 AM

"I think this would work well, but the issue is for a lot of things, everything gets everything. I could sort it, but then it would be a lot of manual setting and registering of types."

The way I'm dealing with that particular part of the entity-system problem is to have components which act as filters for messages.

I read a lot about the actor model while dreaming up my system. The way it's handled in that model is for an actor to filter and forward messages to other actors. I liked the flexibility of that, and came up with an idea like this.


1) Player causes explosion at (x,y,z)
2) EXPLODE(x,y,z) goes out to every entity who is registered, _BUT_, the only one who's registered is a "localizer" entity, who knows where all entities are located. His job is to forward a message to all the entities who are close to (x,y,z) in the form of NEARBY_EXPLOSION(x,y,z) Those entities can deal with the NEARBY_EXPLOSION message in any way they wish.


I should mention, that my component/entity system is 100% for fun, experimental pie-in-the-sky, and will probably be too slow to ever be used in production code. It's sometimes been called a "Flurry of Messages" system. Just wanted to disclose that in case you try to do something similar.

PARTNERS