Animations got slower!

This older Phaser issue seems relevant: Tweens running slow an a specific PC on Chrome? - Phaser 2 - HTML5 Game Devs Forum

If you read down to the bottom, it seems that someone discovered that Phaser’s Tweens run differently depending on the framerate of the monitor. Works great on 60hz monitors, but not on 144hz monitors. That would potentially explain the behavior I’m seeing. My older computers are all laptops with 60hz monitors. The newer computer on which I’m seeing egregiously slow tweens is a 240hz monitor.

So, what part of the Tween code is incorrectly connected to the monitor’s frame rate? I’m scanning the source code to Phase 2.6.2 right now, but haven’t yet spotted it.

Has this ever been fixed? If so, what version fixed it?

It should be optional ( frameBased option).
That’s why I didn’t see slow animations, because I tested on 60Hz. But my sound is still messed up…
Btw, your whole game is probably 144/60 as fast, The default Phaser update loop uses RequestAnimationFrame, so unless you took that into account…

Maybe it’s something related to this issue.

1 Like

By adjusting my monitor’s refresh rate, I have confirmed: Time-based tweens run more slowly on monitors with a faster refresh rate. This is a reproducible Phaser bug, and you can see it for yourself by adjusting your monitor’s refresh rate.

This is the exact opposite behavior of what you might intuitively imagine the problem to be. With frame-based tweens, a faster frame rate would result in faster tweens (because the update loop is running faster). So this is something different. This appears to be a bug in Phaser’s time-based tweens, that causes the tweens to run more slowly when the monitor is faster. The docs claim that the whole point of time-based tweens is to ensure they run independent of frame rate. So, if you say the tween should take 800ms, it should always take 800ms, regardless of the frame rate.

As far as I can tell, this isn’t affecting anything other than tweens, which makes sense because Phaser’s frame rate is limited by default to 60 fps, even when the monitor’s refresh rate is faster. So it seems to be a bug in tweens specifically, where some line of code incorrectly uses the monitor’s refresh rate rather than the game’s limited frame rate to do its calculation.

Reading through some of these related older issues, it sounds like some people resolved it by switching over to frame-based tweens. But this seems like it would just reverse the problem, making the tween speed directly dependent on the speed of the computer. Frame-rate based tweens might not be a problem on fast computers, which are being rate limited by Phaser to 60fps, but it seems like it would slow the tweens way down on slow processors (such as mobile devices) that run slower than 60 fps, which is certainly not desirable.

One user said he believed the culprit was this line in Phaser: phaser/TweenData.js at v2.4.6 · photonstorm/phaser · GitHub

Anyone know if this was fixed in a later community edition release? In general, how compatible are later community releases with the 2.6.2, which was the last officially supported release of Phaser 2?

Once I’ve solved this problem, my next agenda is to tackle the new audio issues that Milton noted in my legacy Phaser game running on new browsers, saying “Another thing that changed in the last couple of years is the media autoplay policy…”

Any ideas how to address Phaser 2.6.2’s inability to play audio until “after a user gesture on the page”?

This has nothing to do with Phaser. You have to wait for a user gesture (e.g. onClick).

Try with

game.forceSingleUpdate = false;

Audio: But waiting for a user gesture isn’t the whole story. As you experienced, the audio doesn’t necessarily start working the first time you click in the window. Sometimes you have to refresh the window or do other things to get it to work. Once it kicks in, it works well. But prior to that, it’s simply unreliable. There’s got to be a better way, right?

@Engelberg could you try this please? phaser-test.js.zip (634.3 KB)

In place of phaser.js.

Thanks, can you explain to me what this file is? Is it Phaser 2 CE, or have you made additional modifications? Is this to address the Tween issue, or the audio issue, or both?

Much appreciated.

@samme I dropped in the phaser-test.js you shared. It does appear to solve the Tween issue. What change is responsible for fixing that? Is this something that was already patched in Phaser 2 CE, or is this an additional patch you just added on top of the existing Phaser 2 CE?

What minifier is usually used to minify the phaser.js file? I usually use phaser.min.js, so if the long-term solution is for me to use the phaser-test.js you posted here, I’d like to run it through the same minifier.

On the audio front, the behavior is a little strange… there is a sound effect that is meant to be played during the initial startup, but instead the sound is held up until the first time a user makes a click. It’s odd to hear a sound effect from several seconds earlier the first time you click. If it’s not possible to play a sound before they click, I think more desirable behavior would be to simply cancel any sounds played before the first click, rather than queue them up. How do phaser games usually handle this?

Since my audio question is unrelated to the tween issue, should I repost it as a separate thread?

Thanks.

(Posting from my wife’s account because I hit the 24 hour limit)


Theory confirmed!

I just changed my monitor’s frame rate on my newer computer down to 60hz instead of the usual 240hz, and the tweens worked great.

If you have a way to adjust your monitor’s frame rate, try it yourself and see what I mean.

So… problem identified, what’s the fix? Clearly I can’t expect everyone to run it on a 60hz monitor, this is definitely a bug with Phaser.

Sorry. That post apparently got held up a couple days for moderation.

This is an experimental build of Phaser CE, for the tween issue. It changes the core game step interval. It may introduce some new timing problems. For physics it likely does.

Phaser CE uses UglifyJS.

I think Phaser 2/CE has always unlocked sound that way. It’s better suited for background sounds/music, I guess.

An alternative you can try in Phaser v2.6.2 is

game.forceSingleUpdate = false;
game.time.desiredFps = 240;

See if that fixes the tween problem (try with both monitor speeds).

The experimental build broke other aspects of my app, such as the particle effects, so I’m going back to 2.6.2. Still working on trying some of the other ideas…

Here is a better experimental build. Physics, timers, tweens should all work together.

phaser-test.js.zip (633.2 KB)

Thanks. I’m still not seeing the particle effects with the latest phaser-test.js.

OK, I’ve retested all the suggestions, and here’s a summary of the differences:

phaser-test.js
I can’t tell any difference between last week’s version and this week’s version on my game. So the following items apply to both versions.

  • Audio that is meant to play at the start of the game is delayed until the first click, at which time it plays.
  • Particle effect animations do not show.
  • On 60hz monitor, everything looks good (except for the lack of particle effect animations).
  • On 240hz monitor, the preloader animation (which doesn’t use a tween, but just updates the angle every time through the update loop) spins considerably faster than on 60hz monitor.
  • On 240hz monitor, I occasionally notice “flickers” where something that was set to invisible flashes briefly on screen a frame or two after it was supposed to disappear.

Phaser 2.6.2 with

game.forceSingleUpdate = false;
game.time.desiredFps = 240;

The above settings don’t seem to do anything, and it behaves exactly like regular 2.6.2, meaning:

  • Audio that is meant to play at the start of the game simply isn’t heard. After the first click, sounds work normally. The early sounds are never played.
  • Particle effects work.
  • On 60hz monitor, everything looks good.
  • On 240hz monitor, animations are all slow.

Phaser 2.6.2 with

game.tweens.frameBased = true;

This was a suggestion given in another thread from years ago on this same topic. Interestingly, this almost worked. It solves the slow tween problem on the 240hz monitor, but introduces really bad “flickering” where you see flashes of objects that had recently disappeared.
So:

  • Audio that is meant to play at the start of the game simply isn’t heard. After the first click, sounds work normally. The early sounds are never played.
  • Particle effects work.
  • On 60hz monitor, everything looks good.
  • On 240hz monitor, animations are correct speed, but lots of strange flickers from objects whose visibility status is changing.

This means I don’t really have a solution to the problem yet.

Frankly, I still don’t quite understand what the underlying bug is. It seems like the crux of the problem is that Phaser is designed to limit the framerate by default to 60FPS, but somewhere in the tween logic, it fails to respect that frame rate, and somehow is basing the tween updates off of the monitor’s refresh rate instead.

Given that more and more monitors run at faster framerates, and given that this bug reportedly affects all versions of Phaser, it seems like an important problem to solve because it means Phaser animations don’t run correctly on modern computers.

1 Like

My best guess is that the culprit is the following line from TweenData.js:

var ms = (this.parent.frameBased) ? this.game.time.physicsElapsedMS : this.game.time.elapsedMS;

I think the default behavior of basing this calcuation on elapsedMS rather than physicsElapsedMS is what causes the tweens to run differently on fast monitors. physicsElapsedMS is always 1/60 of a second, which is exactly what you want when phaser is trying to run the game at 60fps. elapsedMS, for some reason is computed differently on fast monitors.

So that would explain why setting frameBased to true solves the tween slowness problem, because it forces TweenData to use physicsElapsedMS. But, unfortunately, setting frameBased to true introduces that object flickering I described, and I don’t yet understand why.

I decided to enable time.advancedTiming, so I could see exactly what is going on with the frame rate.

According to the docs on fpsMax:

Advanced timing result: The highest rate the fps has reached (usually no higher than 60fps).

So what we’re expecting is that Phaser, by default, is limiting the frame rate to 60fps, even if the computer is faster.

However, when I did advancedTiming (in Phaser 2.6.2, with no modifications) and inspected fpsMax on my 240hz monitor, fpsMax was 240.

I think this is the crux of the problem. We’re trying to find all these fixes for the fast frame rate, but the bottom line is the frame rate shouldn’t be this fast. Something is broken in Phaser’s frame-rate-limiting logic, and the tween logic isn’t expecting this, and somehow the resulting math makes the animations really slow.

1 Like