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

I started to write some code for a small 3D environment. This week I wanted to start with my entities and when I thought about it again, I stumbled across some unmet requirements. My design works fine concerning the game loop, but I missed the logical relationships between distinct entities.
To show what I mean: my entities could interact through a common interface (my base class) but they lack the ability to react to a specific environment, e.g. imagine you have a simulation with some different animals. Some are carnivores (pretator) and some herbivores (prey). When I thought about my design, I somehow missed to include the ability to catch an entity's surroundings. My prey cannot find out about the predators near them ('am I in danger of being eaten? should I flee or am I safe? ..'), nor can the predators actually hunt their prey.

So I am looking for a design that is able to manage all entities through a single interface (game side) and allows information about the environment (entity side). Besides these, there are some more conditions:

  • thread-safety
  • expandable via dll (I'm using C++)
  • effectivity

Side notes: my entities don't need to change properties during runtime (like in ECS) and I want injected entities (through dlls) to work properly with the original ones (e.g. if someone adds a lion through a dll, any prey should properly react to nearby lions as they are a kind of predator).

share|improve this question

2 Answers 2

Some years ago, I read an inspiring book which opened my mind to new approaches when creating software. The book is named "Turtles, Termites, and Traffic Jams: Explorations in Massively Parallel Microworlds (Complex Adaptive Systems)" and it explores the idea of having a non-static world but one which is modified by the creatures living on it. I think you can apply this approach to your case.

You can make all your creatures to leave a stench wherever they passes by. Each creature will have a different stench and it can be of a given intensity, have a given lifespan, etc. The creatures will have the ability to perceive stenches and react differently based upon it. So, in the end, the creature both affect and get affected by their environment, which sounds quite logical.

Stenches will be applied on the world, not on the creature, so creatures become independent one from another and you can easily add more types of creatures as when creating a new creature by plugin, it just needs to define which stench they lay on the world. Stenches can also be plugins easily.

You can have a base abstract class for the stench and define many specializations of it as needed (maybe the one for predator and the one for prey is enough for a test, but you can create one for carnivores, herbivores and so on).

About being threadsafe, this approach I think could be, as stenches are applied to the world, which has to be threadsafe beforehand.

I know I am not giving much details. Hope somehow helps, though.

share|improve this answer
    
This is a very interesting idea but I don't think it fits for several reasons. - I guess you'd implement the stenches as some kind of areal trigger? Now given that the animals are managed with a base interface too, you still can only interact between the two base classes. - If all animals continuously leave stenches the effectivity would drop enormously. Besides many animals would have to leave several stenches or a more complex one (e.g. a prey just wants to know about predators, a lion might want to know about other lions, so all lions would have to leave 'predator' and 'lion' stench. –  rootmenu Sep 15 '13 at 12:57
    
Another drawback to this idea: how do animals react to non-animals? Think of a herbivore looking for food. Should trees for example also leave a 'tree' stench? And as the AI updats/reacts only once or twice a second, some kind of query would be more appropriate. –  rootmenu Sep 15 '13 at 13:08

You can use the same technique used in MMOs:

1) Every "entity" derive from an Item class;

2) World is divided in Regions (a grid for example);

3) Each Region has a subscribing mechanism. All Items can subscribe by passing a callback to a Region. Regions call these callbacks whenever them changes (for example after a move() function of an contained Item);

4) All relevant changes on Item are notified to the Region that contains it;

5) The "surroundings" of an Item are encapsulated by an InterestWindow which is a box or circle that subscribes the Item with whatever Region it enters or unsubscribe it with whatever Region it leaves.

share|improve this answer
    
This is similar to my approach. A space-partitioned world with entities managed via a base class with an 'interest' radius. The problem with both still exists. How does an entity react to a certain kind of entities around it? –  rootmenu Sep 15 '13 at 13:20
    
It's all about assynchronous computation. An entity E must signs when it enters a Region R. Whenever E moves it also must signal R, which will broadcast the event for all entities subscribed to R. For example suppose an Avatar A0 with InterestWindow I0 and an Enemy E0 outside Region R0. Also suppose that R0 is outside I0 (so A0 is not subscribed to R0). Now suppose the following happens: 1) E0 enters R0. Now E0 belongs to R0. 2) A0 moves so I0 intersects R0. Now A0 is subscribed to R0. From now on, when E0 moves, it notifies R0, which broadcasts the event to A0, since it is subscribed to R0. –  dsilva.vinicius Sep 15 '13 at 17:26
    
I allready got that from your answer. Still, if you take the messages on a detour to the region, you lose all information about your entities. As I said in the question I want injected entities to work properly, so a region can only work with basic 'Entity's that subscribed to it. If your 'Enemy' E0 moved, it notifies R, but R only realizes an 'Entity' 's move, not an 'Enemy' 's move. Now R broadcasts the event to A0 without any information if E was an 'Enemy' or not. Besides, assynchronous computation leads to the false direction. –  rootmenu Sep 15 '13 at 17:55
    
Imagine you have 3 enemies in range. If you compute E1 and notify A0, A0 might steer away from E1 and directly run in E3's direction. Computing E2 and E3 sequentially might finally lead to A0 running straight in E1's direction although the appropriate action for A0 could be to simply turn around (relative to its original direction) and make a run for it. –  rootmenu Sep 15 '13 at 18:00

Your Answer

 
discard

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

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