Jump to content
A 2021 backup has been restored. Forums are closed and work in progress. Join our Discord server for more updates! ×
SoaH City Message Board

Frame skipping on GM 6.1, how?


Recommended Posts

I have a very slow pc, of 650 mhz of processor, and for better results, I solved to make a engine test for my project(that I have tested only on my other fast computer). But it had reasonless slowdowns here, even with deactivating objects outside from views(most of them), then I searched about frameskipping on game maker forums, and I found this solution:

CREATE EVENT:

set_automatic_draw(false);

alarm[0] = 2;

ALARM 1 EVENT:

screen_redraw()

alarm[0] = 2;

This worked out, the fps have increased a lot, and there are less slowdowns, but I noticed some lags of random frame skipping during the test (this is more visible on 2 frames animations). Even refreshing the screen, together with the redraw function, this couldn't resolve the random frame skipping and falling.

There's a way to configure the frameskip on Game Maker 6.1?

Link to comment
Share on other sites

OLD, but still useful.

What that function does is, it limits screen drawing to every 3rd step, instead of every step. The problem is, it doesn't stop other background processes - it only stops DRAWING. So, if your frames are fluctuating, it's because of your step code, not because of what you're drawing.

GM doesn't have a native frameskip, so manual frameskip is the only option. There's a better way to do this, and it comes from this thread. :)

CREATE Event

set_automatic_draw(false)
alarm[0]=1

ALARM Event: 0

//Takes the current fps and calculates the number of steps for the next cycle.    
   global.timing = max(3,floor(fps/30))

//Sets the time for the next screen redraw
   alarm[1]= global.timing

ALARM Event: 1

//Redraws the screen
   screen_redraw()
   alarm[0] =1

Since our eyes "work" at about 60 frames per second there is no need to draw the screen every step. Therefore, the above code will redraw the screen approx 30 times a second. (The Default Room Speed)

This approach to the speed consideration may help more in slower systems than the faster, newer ones.

Link to comment
Share on other sites

The ideal way to make auto-frameskipping would be using milliseconds instead of using the fps value, since this is updated only every second. An approach would be something as follows:

Creation event

// Declarate frameskipping variables
Frameskip        = 0;
MaxFrameskip   = 9;
PreviousTime    = current_time;
FrameCount     = 0;
FrameInterval   = 1000/room_speed;
set_automatic_draw(false);

Step event

// Increase framecount
FrameCount += 1;

// Check if we should skip this frame
if (current_time < (FrameCount*FrameInterval))
    Frameskip += 1;
PreviousTime = current_time;

// If we didn't skip the frame or reached the max amount of frameskip, redraw.
if (Frameskip == 0 || Frameskip == MaxFrameskip) {
    screen_redraw();
    Frameskip = 0;
    FrameCount = 0;
}

Something like that should work as for auto-frameskipping, but not too well. I'd suggest you also add common fixed frameskipping for very low ends that won't work very well with this approach. Finally, a method would be using something as follows:

Creation event

// Declarate frameskipping variables
FrameskipActivated = true;
AutoFrameskip        = true;
Frameskip              = 0;
MaxFrameskip         = 9;
PreviousTime          = current_time;
FrameCount            = 0;
FrameInterval         = 1000/room_speed;
set_automatic_draw(false);

Step event

// Check for frameskipping
if (FrameskipActivated == false) {
    screen_redraw();
    exit;
}

// Increase framecount
FrameCount += 1;

// Check if we should skip this frame
if ((AutoFrameskip == true && (current_time < (FrameCount*FrameInterval))) || (AutoFrameskip == false))
    Frameskip += 1;
PreviousTime = current_time;

// If we didn't skip the frame or reached the max amount of frameskip, redraw.
if (Frameskip == 0 || Frameskip == MaxFrameskip) {
    screen_redraw();
    Frameskip = 0;
    FrameCount = 0;
}

Anyway, remember I don't guarantee the auto-frameskipping to work properly, since I can't test it on my end xD.

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...
  • 5 months later...
  • 1 month later...

Just did. I've been using the time delta method for a while, and that DLL seems to not use the correct way it should be done. To get a stable delta, you need to previously store various delta and then do the arithmetic mean.

This is my code:

// On creation...
global.IdealFPS = 60;
global.IdealInterval = 1/(1000/IdealFPS);
global.DeltaList[19] = 0;
global.DeltaNode = 0;
global.Delta = 0;
global.PreviousFrame = current_time;
global.CurrentFrame = current_time;

// On step
global.PreviousFrame = global.CurrentFrame;
global.CurrentFrame = current_time;

global.DeltaList[global.DeltaNode] = (global.CurrentFrame-global.PreviousFrame)*global.IdealInterval;
global.DeltaNode = (global.DeltaNode+1) mod 20;

var i;
global.Delta = 0.0;
for (i=0; i<20; i+=1) global.Delta += global.DeltaList[i];
global.Delta = global.Delta*0.05;   // Or global.Delta / 20, but this way is faster.

After having the delta, once you want to move an object or increase a timer, you need to multiply it by the delta. This way you achieve frame independant movement :)

  • Like 1
Link to comment
Share on other sites

// On creation...

global.IdealFPS = 60;

global.IdealInterval = 1/(1000/IdealFPS);

global.DeltaList[19] = 0;

global.DeltaNode = 0;

global.Delta = 0;

global.PreviousFrame = current_time;

global.CurrentFrame = current_time;

// On step

global.PreviousFrame = global.CurrentFrame;

global.CurrentFrame = current_time;

global.DeltaList[global.DeltaNode] = (global.CurrentFrame-global.PreviousFrame)*global.IdealInterval;

global.DeltaNode = (global.DeltaNode+1) mod 20;

var i;

global.Delta = 0.0;

for (i=0; i<20; i+=1) global.Delta += global.DeltaList;

global.Delta = global.Delta*0.05; // Or global.Delta / 20, but this way is faster.

Hmmm... appending Delta to every speed variable looks a little tough, and... this delta can keep collisions stable? I ask this, because I mean the speed+delta issue, the collisions can lose their precision. Also, the number of active objects influences a lot on fps decreases...

Link to comment
Share on other sites

Hmmm... appending Delta to every speed variable looks a little tough, and... this delta can keep collisions stable? I ask this, because I mean the speed+delta issue, the collisions can lose their precision. Also, the number of active objects influences a lot on fps decreases...

Implementing delta is actually quite easy, doesn't take much time. I did it with the Dash engine in near no time. The collision problem you mention there, though; can be present, but there are ways to avoid it. For example, when the delta gets ridiculously high, the number of pixels to move will increase bastly. A way to prevent this is to divide the number of pixels to move by a safe value, and then perform the collision checks in various steps.

Works perfectly good!

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...