Delegation - what system? component or entity?

Having a bunch of issues delegating some of my character movements.


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.


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
    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


This thread is actually a repost of a digression i made from another thread to keep things clean.

Pspeed answered

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.

My question

My physics is actually even simpler than that but yes i would probably have iterated that way. Now for the impulse entity, i like that, but do you mean to handle every movement through that entity? So if i hold the RIGHT key for a second it will create 60 impulse entities? If so problem solved.

If not and you only meant that for the jump move, then two different system will have to touch the CTranslation component and i’m back with my delegation problem.

An aside: I would argue that your “physics” system is more complicated than what I listed since those two lines would work for any moving body, input or not… and input then just becomes setting the velocity (or acceleration if you want that). It’s even simpler if all you want is velocity… but I digress.

Jumping is part of an input state like moving left, right, etc… So I would include it in that. You have some set of flags that denote the intent of the player… jumping is one of those things. Your simple physics system could take these into account just like they do now.

I think your biggest original “mistake” was trying to treat a spring block like a jump block. It’s not… since it has nothing to do with input. It’s better handled with a separate impulse concept… likely an entity. Then you could even trivially deal with blocks that send you sideways, too, for example.

Another argument for separating jump, think of many platformers that will change the magnitude of the jump based on when the player releases the key. If it’s just another input state like any other movement then you can easily handle that. Spring blocks would have no such concept… their magnitude is in-built to the block.

I would have player input handles the same way as the rest, then introduce a SpringBlockJump component to the player when he is on the springblock. That component is created by Springblocks, consumed by your physicssystem. Your physicssystem then combines this with the rest of the player input.