Closed Gama11 closed 11 years ago
Done some tests on Windows and iPhone 4 and i'm not getting this problem.
If can confirm this, with 60 fps it does NOT run smoothly on native, I set it to 100 now and it's running much much better. Obviously it's something with the rendering engine since my monitor updates at 60Hz.
Hmm I noticed something semi-related but very serious, my game speed was originally adjusted for 60fps, now I set it to 100fps and ALL movements are slower! even using FlxG.elapsed! This shouldn't be happening. I tested with:
x += 100 * FlxG.elapsed; // should move 100px every second, independently of frame rate, but it's varying, the higher the FPS the slower it's moving
Same thing happens moving by: velocity = 100;
All Tweens are also affected.
@Beeblerox
That's not good :( That's totally not good
i'll just go mad
i think i know where is the problem, will try to fix it today
@AndreiRegiani are you sure that the game is able to maintain the target FPS? If not, then you'll experience a slowdown because FlxG.elapsed is calculated based on the target FPS but if the actual FPS is lower then the game will be updated less frequently.
I've seen a similar behaviour on a weak Android phone that was not able to maintain even a mere target 30 FPS. Everything moved like in slow motion.
This can be mitigated by removing this condition:
if (_accumulator > _maxAccumulation)
{
_accumulator = _maxAccumulation;
}
in https://github.com/HaxeFlixel/engine/blob/master/src/org/flixel/FlxGame.hx#L353 but then you loose fixed-step updates.
@goshki @Beeblerox I tested more deeply, the problem occurs only when FPS is set above 60:
I just noticed something weird that might be related, the FPS you put in the xml window tag doesn't seem to work. Tracing Lib.current.stage.frameRate always returns 60.
@PaulGene I think the configuration that counts are those on FlxGame.new(..., GameFramerate, FlashFramerate)
Yes i realise that, i've been passing Lib.current.stage.frameRate to FlxGame.
More tests, FlashFramerate is affecting on native platforms, I'm getting 60/100 FPS because I'm setting GameFramerate AND FlashFramerate to 100, it runs smooth but slows, if I set GameFramerate to 100 and FlashFramerate to 30, it runs at solid 30 FPS on NATIVE platform. Hope this can help to figure out, FlashFramerate shouldn't be affecting on native, right?
SOLVED for me: I'm getting now a smooth 60 fps, I just needed to set GameFramerate to 60 and FlashFramerate to 100 super(gameWidth, gameHeight, GameplayState, ratio, 60, 100);
Seems it was only a naming confusion, FlashFramerate doesn't mean Framerate for Flash Player.
GameFramerate: "How many times you want your game to update each second." FlashFramerate: "How many times you want your game to update each second. NOTE: This is NOT the same thing as the Flash Player framerate!"
@Beeblerox
I'm not sure, but maybe we should rename it to UpdateRate and RenderRate?
@sergey-miryanov Renaming is indeed necessary to avoid future confusions, but why are two rates needed?
Look this - http://gafferongames.com/game-physics/fix-your-timestep/, especially Free the physics section
From the forum: FlxG.elapsed as a constant? Is semi-fixed timestep really a good idea? FlxG.elapsed should return the difference from the last frame, which would make animations really frame-independent.
I'm testing a "60FPS" game on old computers/devices, it reaches ~30, but instead of "skipping frames" and keeping normal speed, it slows down the speed and renders all frames, that makes the game unplayable! Wouldn't happen with (regular) fixed time step." -- http://haxeflixel.com/forum/help/how-to-calculate-the-best-fps-in-realtime
When I have time I'll implement real fixed time step ("Delta Time") and post results here.
Done (fast implementation): FlxGame https://dl.dropboxusercontent.com/u/21553459/FlxGame.hx
Results are excellent, game running at 20FPS still playable, I will use it on my product final release.
What you guys think?
These are the lines changed on update()
var time:Int = Lib.getTimer(); FlxG.elapsed = (time - _lastTime) / 1000; _lastTime = time;
// old implementation ("semi-fixed time step") //FlxG.elapsed = FlxG.timeScale * stepSeconds;
I'm not sure why Adam chose to use fixed timestep, but I'm sure he had a good reason for it. Could very well have been the issues that start to occur with physics like the article @sergey-miryanov linked claims.
Anyway, I have noticed in the past that games in flixel that don't run at max framerate feel horribly slow, to the point of being unplayable, so that definitely is an issue. This is worth considering and more testing should be done-
That code you posted has a flaw - you shouldn't use Lib.getTimer()
. It's explained a few lines above:
#if !FLX_NO_DEBUG
if (FlxG.debugger.visible)
{
// getTimer() is expensive, only do it if necessary
mark = Lib.getTimer();
}
#end
I think @crazysam pointed this out originally, so I'm not sure how much of an impact this really has. But at the very least, this shouldn't be done twice per frame, no reason for that.
I tested this with FlxBunnyMark. It really makes a significant difference:
There's some weird behaviour when switching between the two modes.
He probably went fixed timestep because of the recording / playback system. Please don't replace fixed timestep with this, i need fixed / frame skipping ! . An option to use it would be good though.
@PaulGene Not sure about that. After all, the recording system was only introduced in 2.5.
This could be made optional fairly easily.
Why do you need this exactly? Do you use the vcr?
Exactly... older flixel used delta time...
@PaulGene Oh, ok, good to know (I actually didn't). Still, why exactly do you need fixed timesteps? For the vcr?
Not the VCR no but something similar, the async multiplayer in Renegade Racing mobile is basically a recording / playback system and unless you do things frame based it gets a bit messy. Also fixed time step is better for physics engines.
@PaulGene I'm wondering if this actually messes with nape integration, or if nape has its own update cycle?
I guess the delta time could be made the default setting, since the vcr is turned off by default. In case FLX_RECORD
has been set, or another flag FlxG.fixedStep
maybe, that logic is used. More testing, especially with physics, needs to be done though.
so modern-ish Flixel does use fixed timestep, but still provides the flxg.elapsed variable to allow you to do framerate safe coding still.
for example, you could just ignore flxg.elapsed completely, and just increment variables, etc, and it will work fine, but if you were to change the framerate later, then you'd have to alter everything in the whole game. if you use a fixed timestep and flxg.elapsed, then you can change the framerate later in development, and not have to worry about breaking everything you wrote so far (if you're worried about that)
its a bit weird but its handy for some things! i think to get true delta time, or get a nice range of min/max framerates, you'll probably have to override flxgame and make some adjustments, and yes, fixed framerates are a huge win for physics, for frame stepping, for replays, for a lot of things...
hope that helps!
Running in a fixed (or semi-fixed) time step is important for physics and networked simulations. In addition, not skipping frames can give the game a "retro" feel (old games chugged and slowed down to process every frame), and a lot of games made with Flixel are "retro-like" games that seem to target that nostalgia factor.
I think we could introduce a new haxedef: FLX_NO_FIXED_TIMESTEP
This would make the game loop update and render as fast as possible, and FlxG.elapsed would represent the "real" time elapsed between frames: FlxG.elapsed = FlxG.timeScale * (elapsedMS / 1000);
This would break recording and frame stepping, but will be disabled by default.
I need to speak with Beeblerox to make sure he's OK with it.
Made a pull request that implements this feature (optionally of course). https://github.com/HaxeFlixel/flixel/pull/526
Thanks @AdamAtomic for responding my tweet, very nice to have you here. Thanks @crazysam for the final implementation :)
@Gama11 the weird behavior when switching modes was because in my (test) implementation _time was set to '0' initially, when subtracting to getTimer(), FlxG.elapsed was set to a high value like '22867.493' in the first frame instead of a 0.015ish.
Using variable timestep is now possible by setting FlxG.fixedTimestep = false;
. This should fix the issues where perceived game speed is different on different platforms. I'm not sure it addresses the original issue though, that the same fps setting makes the game run differently on Windows and Flash targets. We should investigate this more.
Since we now have FlxG.fixedTimestep
this issue which is marked as a bug, should be closed. Great discussion here guys.
Previously mentioned in #436 by
@crazysam:
and @Beeblerox: