Component update evt received before a Component delete evt in a threaded env

If one system is updating a component and another one is deleting it, receiving the delete order before the update one could happen hence creating an add component order, how can i limit explosions?

It looks like an inherent behaviour of threading which makes me wonder if the problem lies more into how i am thinking a problem again, here i’m passing components as messagers but to illustrate with another type of example:

Let’s say one System is setting a Dead component and another one is removing it, same problem and it’s not a detail for the gameplay.

What am i doing wrong?

Add a new component that denotes that the one system is done processing the entity which the other system can check.

If you have two systems writing to the same component it kinda feels like a design error somewhere.

I like those answers, thanks.

I guess this is a case where i should give really concrete scenarios because indeed the Dead component case makes more sense for it to be touched only by a DamageSystem for instance.

@Empire Phoenix said: If you have two systems writing to the same component it kinda feels like a design error somewhere.

True, normally you only have one system writing and multiple others reading, you might have an indicator that you should add more components or separate existing ones.

I concur with the others.

In general, only one system should ever modify a component. Everything else should be readers. The only case where this doesn’t apply is when entities are created for the sole point of holding the component (and others) like when you must apply different types of damage or something. Then multiple systems may be applying different damage to an entity, but they are creating damage entities to do that.

So the rule is that only one system per entity should ever add/modify a component. Everyone else should be readers.

And it’s not just a contrived design constraint because nearly every case (and certainly all that I’ve come across personally) the design improves by this constraint because the ways to resolve it are also showing that there were other issues. The damage to death case is a good one because you really should only be handling death in one place… otherwise, you will have to touch a 100 different places if you ever want to add immunity or whatever. In fact, it’s reasonable to separate the damage system from the death dealing system, too (though I might combine them). ie: damage is applied and sets hitpoints… and is the only system that sets hitpoints. Some other system watches for hitpoint changes and applies death when they go below 0. In an RPG this is very flexible as when to apply death could be quite complicated (think of D&D where 0 hitpoints means you are bleeding out, so 0 hitpoints would cause the death system to add damage but only -10 or so would mean death.)

As it is a bit offtopic i moved that part in its own thread here: Delegation - what system? component or entity?


I’m bumping the thread as it’s completely related to delegation issues i got a few months back.

Moving

What i’m doing atm is something like that in a MovementSystem:

if input.left then translation.dx -= 5
if input.right then translation.dx += 5

I gather all my deltas and then a CollisionSystem will resolve everything and actually push those deltas into a CPosition component.

And all of it made sense until i tried to jump.

Jumping

My main issue is that i wasn’t sure where to put that piece of code. At first i simply added in the MovementSystem something like:

if input.up && !entity.has(CJumping) then em.addComponent(entity, new CJumping())
if entity.has(CJumping) then
    JUMPALGORITHMSOMETHING
    trans.dy -= somevalue

It’s getting uglier but still working.

But then i was wondering, WHAT IF a spring block wanted to make my entity jump - if i’m following the rule of one system per component add/update i would obviously break it when another System would have to add a CJumping component when it wasn’t its role.

So i talked to someone who advised me to go the entity way and i like the idea but not convinced about the implementation.

One way would be to go full impulse, if every movement delta is actually a new entity with a CImpulse component then jumping is just a matter of adding a new entity with the proper physics value. But that kind of abstraction implies that i actually build a little physics engine when i just want to go the arcade way. I am not particularly found of the idea of generating that many impulse entities per frame either but that might be negotiable with my brain.

So i’m back with my specific jumping algorithm idea and still not sure how to go with it.

I could do something in MovementSystem like:

if input.up then createJumpEntity()

That entity would have a CJump and a CChildOf component that a JumpSystem will look for. So i could reach the entity through the CChildOf pointer and apply some delta to the entity CTranslation component. It would solve the spring block problem but again i’m modifying a component that is reserved for the CollisionSystem originally.
So i ask myself if that’s a specific case of collision resolution… where i could actually enforce that rule or maybe more that CTranslation by definition is made to gather a bunch of deltas so it’s fiiiiine and it’s probably not; i have huge issues figuring something as simple as jumping.

It seems to be the same problem every time i need to handle states, CJumping, CGrounded, CChopping

Help

Random thing: if you are already doing the “arcade way” then my assumption would be that you already have a simple physics engine, ie: just the movement equations and basic collision.

vel = vel + accel * tpf;
pos = pos + vel * tpf;

You may want to handle jumping (which is a character input thing) differently than a spring block. Supporting some kind of impulse component (on a child entity) is the most general way I can think to handle it… and I don’t really understand why it means you’ve created any more of a physics engine than you already had. Basically you’re just adding some one-time additional velocity or something.

I don’t think this really has much to do with the original thread, though.

Sorry, it kinda made sense with the evolution of the thread, not so much with the original question indeed.

I moved the last delegation issue in its own thread here: Delegation - what system? component or entity?