Bug/regression? Riding a moving body ignore collisions

Hi,

The following behavior change is affecting versions from 3.10 (tested with each minor from 3.0 to 3.23):
Made a quick video of it.

I call it a bug given the following rules I would consider “de facto” about platforms moving horizontally:

  • as a player, my body should be transported by the moving platforms that I ride, provided that:
    • these platforms move by means of velocity (not by replacing their position every step)
    • these must have frictionX set to a positive value (1 is most likely)
  • as a player standing on that moving platform, if my body hits a wall while being “transported”, I expect to be blocked by the wall - and not ride the platform through that wall.

Example of the “good” behavior in this codepen using 3.9:

  • let the moving platform bring the top lemming against the wall.
  • observe the lemming being stopped by the wall.

Example of the “bad” behavior in this codepen using 3.10:

  • let the moving platform bring the top lemming against the wall.
  • observe the lemming is not stopped by the wall
  • retry this time using the right arrow on your keyboard
  • the wall stop both lemmings

Possible cause: is friction transferring position differences to the “riding” bodies in 3.10+ instead of adding its velocity to that of the riding body like in 3.9 and below?

1 Like

I think friction has always been accomplished by the position delta, but the delta calculations may have changed in v3.10.

You could try doing your own velocity transfer in the collision callback.

Hi Samme,
Thanks for your answer; I’ll experiment with the collision callback, but I still think it’s a regression/breaking change.

I’d love to know what’s the take of @rich on this behavior though. It was working the “way I needed it to be” until 3.9 included. Maybe the behavior change between 3.9 and 3.10+ was intended, and not a bug like I’m tempted to call it. I simply wish to be on the safe side and not create a workaround for bug that was waiting to be detected.


N.B. I’ve ported my game to Phaser from a whacky cocos/chipmunk stack because I had to hack and patch those libs way too often… I haven’t had to write a single “hack” with Phaser in spite of being new to it. I started 1 month ago… such a clean lib is what got me puzzled when I saw the friction/riding/collision behaviour, that’s what made me dig in earlier versions.

Thanks for pointing that out @samme.

I’ve come to a solution, I guess. It’s perfectible, but seems stable enough.

Adding the collider with a callback, as we know:

this.physics.add.collider(
  this.actorsGroup,
  this.movingPlatformsGroup,
  (actor: GameCharacter, platform: MovingPlatform) => this.objectStandsOnMovingPlatform(actor.body, platform)
);

The callback itself simply checks a custom property such as “should this platform apply its velocity onto the riding body? or had it been given friction knowing no walls will be traversed?”

  private objectStandsOnMovingPlatform(freeBody: Phaser.Physics.Arcade.Body, platform: MovingPlatform) {
    if (platform.transferVelocity && (freeBody.blocked.down || freeBody.touching.down)) {
      // Add platform's velocity
      freeBody.velocity.x = platform.body.velocity.x;
      // Negate the riding body's drag
      if (platform.body.velocity.x) {
        const [lastDelta] = this.sys.game.loop.deltaHistory;
        const direction = platform.body.velocity.x > 0 ? 1 : -1;
        freeBody.velocity.x += (direction * (lastDelta * (freeBody.drag as Phaser.Math.Vector2).x)) / 1000;
      }
    }
  }

Still, I hope to have our dear lead dev’s take on whether it’s normal or not.

Thanks for your time and attention!

1 Like

You can certainly add an issue for it. I agree it’s undesirable, I just don’t see a way around it given how the deltas work now.

Thanks for the advice @Samme, I hadn’t thought of the github issues. Here it is!
Thanks for your attention!

Quick question @samme. Have you created a PR for this please? Thanks a lot in advance for your follow-up!

Will do.

Thanks a lot :+1:

Linking to Samme’s solution: