Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arcade physics: friction force scales incorrectly with physics FPS #4672

Closed
BenjaminDRichards opened this issue Jul 24, 2019 · 2 comments
Closed

Comments

@BenjaminDRichards
Copy link
Collaborator

Version

  • Phaser Version: 3.17, 3.18 tested
  • Operating system: MacOS Sierra (10.12.6)
  • Browser: tested in Chrome 76

Description

  • Update Arcade Physics FPS to 120.
  • Create two game objects with physics enabled, in the style of "character on moving platform".
  • Object A has gravity downward (the "player").
  • Object B is immovable, and moves side to side (the "platform").
  • Expected behaviour: object A is carried along by object B at exactly the same speed.
  • Actual behaviour: object A moves 50% faster than object B, and slides to the leading edge of B. (A doesn't ever fall, because once it moves off B, it is no longer being moved, and B moves back under it.)

Example Test Code

Quickest way to reproduce this is to fire up the friction demo at:

http://labs.phaser.io/edit.html?src=src/physics/arcade/friction.js&v=3.18.1

Then change the physics config to read like this, and run:

physics: {default: 'arcade', arcade: {fps: 120}},

This will set FPS to double the default of 60. You should see the top platform, which is supposed to have friction 1, actually pushing the lemmings ahead of it.

Additional Information

I've traced the problem to the state of prev in Phaser.Physics.Arcade.Body. This is read by SeparateX/Y when assessing friction. We see code something like body1.x += (body2.x - body2.prev.x) * body2.friction.x;, which is fine if prev is precisely one physics step ago. But when prev is several steps old, every step increases the distance between now and then, and the friction is applied for every step. This results in friction pushing too hard and moving the object too far.

I have solved the problem in my project by setting friction.x for all objects to 2 / 3. However, this is clumsy, and incompatible with cases such as:

  • Changing the physics step FPS to another value
  • Setting custom friction on some platforms

It also causes some stuttering in the movement of the player on the platform, because the friction is no longer a 1:1 relationship.

Because prev has existing use cases (e.g. users being able to do their own analysis of frame-by-frame movement), I think it should stay as it is. Instead, I would add a new property, perhaps prevStep, which is updated with every physics step. This would allow friction to be calculated more accurately, and also allow users to analyse some kinds of step-by-step movement.

I have noted that this region of the physics code has been significantly updated between 3.17 and 3.18, so I surmise it's an area of active development. I couldn't find any mention of friction in the change log or other issues, so it looks like this is an edge case that's been overlooked so far. Hopefully this helps make everything more solid!

@BenjaminDRichards
Copy link
Collaborator Author

Additional: the peculiarities of prev also seem to distort apparent velocity at non-standard physics FPS rates. With an FPS of 120, an object in a gravity field of 1000 will rest upon tiles, but report a velocity.y of 8 (where it is 0 at 60fps).

@photonstorm
Copy link
Collaborator

Thanks for opening this issue, and for submitting a PR to fix it. We have merged your PR into the master branch and attributed the work to you in the Change Log. If you need to tweak the code for whatever reason please submit a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants