Minimize/unminize game gives lag...

Hi everyone.

I've been using shaders and surfaces now for a while to come up with all
sorts of cool effects. Weather, lighting, fog, day/night cycles,....
However I've run across something that I'm sure a lot of people have already encountered:
Lag, specifically lag after I minimize the game, then enlarge it again (to full screen).

I've tried everything I can think of. I increased the texture page sizes. I clear the display buffer of each room.
I clear the surfaces in the cleanup event, in the objects where the surfaces are made. I changed variables to local variables wherever i could. Made sure that objects outside of the camera's view aren't drawn at all, and so on...

I learned a lot about optimization by doing this. in fact, the game runs almost as smooth as butter now, even with large amounts of objects (upwards to 2000/3000 within the room), each with quite a lot of code in it (couple of hundred lines per object).

When the object counts goes completely overboard, which I will never need anyway in such large amounts, yes I still encounter lag.
But that's not the issue here. Object count was just a test to see how far I can push it.

What bothers me is that, somehow... minimizing and unminimizing always causes lag. 60 FPS drops to like 40 - 35, sometimes even lower. The lag isn't there if I never un-minimize.

In the debugger, after I minimize, I see an FPS drop, one that clearly curves down from 60 to 40 (although not instantaneous, more like in a few seconds) and memory says somewhere around 64mb, and what's used on average is around 60 (I don't understand that memory thing I will add).

Sooo question:
1) Is this a common mistake? something I'm overlooking?
2) Is there by any chance a way to increase the system memory the game uses? I have a hunch that if I could double it, my issues would be over quickly.
 

Simon Gust

Member
When you minimize your game, Video Memory is used by other Programms on your Computer, this "vram" is taken away from your game temporarily, what this means is that surfaces are being freed from this vram.
Maybe there is some code that mishandles this situation and is creating some unwanted effects. Can you show every code where a surface is created? There has to be a reason your game does not speed up again.
 
Your saying the game continues to lag indefinitely after minimizing? That isn't normal. It should lag when you minimize it or move the window around but once you reselected the window it should go back to normal. You said you were looking at the debugger, you should look and see what your surfaces are doing in the debugger as well as profiling to see what objects are causing the issue. You likely have some code creating a new surface every step or something.
 
Your saying the game continues to lag indefinitely after minimizing? That isn't normal. It should lag when you minimize it or move the window around but once you reselected the window it should go back to normal. You said you were looking at the debugger, you should look and see what your surfaces are doing in the debugger as well as profiling to see what objects are causing the issue. You likely have some code creating a new surface every step or something.
Yes indeed, only after I minimize the game window (game is fullscreen) does the lag occur. After I go back to fullscreen then, the lag remains.
Also, how can i see the individual surfaces in the debugger? That would help me a lot.
 
When you minimize your game, Video Memory is used by other Programms on your Computer, this "vram" is taken away from your game temporarily, what this means is that surfaces are being freed from this vram.
Maybe there is some code that mishandles this situation and is creating some unwanted effects. Can you show every code where a surface is created? There has to be a reason your game does not speed up again.
I expect exactly this.
I'm going to search today for what could cause it, if I think I found the issue I'll post it here so other people can try and help me out with it :p
 
When you minimize your game, Video Memory is used by other Programms on your Computer, this "vram" is taken away from your game temporarily, what this means is that surfaces are being freed from this vram.
Maybe there is some code that mishandles this situation and is creating some unwanted effects. Can you show every code where a surface is created? There has to be a reason your game does not speed up again.
Ok, so I have a couple of surfaces going on;
- I use a shader to give lighting effects, for example around torches. A circular texture reverts the game's color back to normal with an outward gradient around a torch. But only when
certain variables tell it to. Basically, either it's already "dark" inside a room (dungeon for example) or it's "dark" outside (in outside rooms that have a day and night cycle). Within the texture, the "darkness" is ignored, giving a light effect. it looks exactly how i want it to.
- When being "outside", a day and night cycle happens. Basically I have an ingame timer to determine ingame time. This means I update RGB variables which are then passed through
into a shader.

Basically, a top down game with your normal dungeons, torches, and a player that could light up his own surrounding areas if a lightsource is held.

So an OVERALL day/night color change, which then has textures in it where this color change won't happen to give the illusion of point lighting.

This is handled by my camera object, as it's the one object that is for absolute sure, always present and therefore can be used to set up a general lighting system that also has to be always present.

Now to come back to my problem: The weird thing is that I didn't notice the lag at first. Sometimes it did get laggy when I had too many objects, but i optimized the code within those objects to reduce the lag, and it works a looot better now.
When I minimize the game, when in a room with a lot of objects, suddenly the lag comes back full-force.
When I don't minimize, the lag is also at minimal or not present at all (with a lot of objects).

This leads me to believe, as you said, there has to be something that creates an unwanted effect.

First of all, these objects need to be drawn. This doesn't cause lag if the game opens up, then stays maximized.
However, when minimized, it seems there are v-ram problems.

It is not a memory leak. The lag drop happens one time and doesn't build up. Minimizing and maximizing again, 10 times even, does not further drop the framerate significantly.

The more I started to look in my code, the more I'm starting to assume it's the APPLICATION SURFACE at fault here.

yes, I am manipulating the application surface quite a bit. And since many objects have to be drawn on it, if by any chance
something goes wrong when the v-ram is cleared upon minimizing, and then maximizing,
maybe the combination of amount of objects + wrong surface memory allocation could be the cause of my lag.

So, I'll only show the code in my camera object related to the APPLICATION SURFACE here:

Camera Object:

CREATE EVENT
----------------------
//Camera object that handles views and lighting effects
///////////////////////////////////////////////////////
//Initial parameters
Scale = 4; //also looks amazing when making it 3 => have it as an option?
Display_Height = display_get_height()/Scale;
Display_Width = display_get_width()/Scale;
//Pixel perfect (even for rotation) surface resize:
surface_resize(application_surface, display_get_width(), display_get_height());

//GUI and full screen:
display_set_gui_size(Display_Width, Display_Height);
//window_set_fullscreen(true);

//Camera:
Camera = camera_create();
camera_set_view_size(Camera, Display_Width, Display_Height);
camera_set_view_pos(Camera, x - (Display_Width / 2), y - (Display_Height / 2));


STEP EVENT:
---------------------
this just updates the x and y for the camera to either
a) track the player during game time
b) be detached from the player and given a path by code, for example during cutscenes
//It also updates certain rgb variables that need to be passed into a shader. There is no surface
//handling here, just very simple prepwork for the shader stuff down below in the post draw event


ROOM START EVENT:
----------------------------------
view_enabled = true;
view_visible[0] = true;
view_set_camera(0, Camera);
x = OBJ_Player.x;
y = OBJ_Player.y;


POST DRAW EVENT:
-----------------------------

if (!surface_exists(srf_lights))
{
srf_lights = surface_create(surface_get_width(application_surface), surface_get_height(application_surface));
tex_lights = surface_get_texture(srf_lights);
}

surface_set_target(srf_lights);
draw_clear(c_black);
gpu_set_blendmode(bm_add);
gpu_set_tex_filter(true);
var lightsstrength = lightsalpha;
var vx = camera_get_view_x(Camera);
var vy = camera_get_view_y(Camera);
//testing purposes: these need to be combined into a parent, already works but code can be minimized i think
with(OBJ_PlayerLight) //if the player has a lamp item held, this object will be spawned in the same place as the player and follow him (causing an area to be illuminated around player)
{
draw_sprite_ext(sprite_index, image_index, OBJ_Camera.Scale*(x-vx), OBJ_Camera.Scale*(y-vy),
OBJ_Camera.Scale, OBJ_Camera.Scale,
image_angle,
image_blend,
image_alpha*lightsstrength*0.9);
}
if (TimeHours >= 14)
{
with(OBJ_LanternLight) //just static objects that need to illuminate the area when needed
{
draw_sprite_ext(sprite_index, image_index, OBJ_Camera.Scale*(x-vx), OBJ_Camera.Scale*(y-vy),
image_xscale, image_yscale,
image_angle,
image_blend,
image_alpha);
}
}
gpu_set_blendmode(bm_normal);
gpu_set_tex_filter(false);
surface_reset_target();

shader_set(SHD_DayNightWeather);
///////////////////////////////////////////////////////////////
shader_set_uniform_f(udaycolorred, colormixred); //these are just shader variables, which are set elsewhere depending on ingame time
shader_set_uniform_f(udaycolorgreen, colormixgreen);
shader_set_uniform_f(udaycolorblue, colormixblue);
shader_set_uniform_f(ucontrast, conmix);
shader_set_uniform_f(usaturation, satmix);
shader_set_uniform_f(ubrightness, brightmix);
shader_set_uniform_f(upop, popmix);
shader_set_uniform_f(utres, tresmix);
texture_set_stage(s_lights, tex_lights);
application_surface_draw_enable(false);

if (surface_exists(application_surface))
{
draw_surface(application_surface, 0, 0);
}
////////////////////////////////////////////////////////////
shader_reset();



CLEANUP EVENT:
--------------------------
if surface_exists(srf_lights)
{
surface_free(srf_lights);
}
 
Extra update:
I loaded up a room with a large amount of pre-made objects.
Then I tested it without minimizing: barely any lag or none at all.
Then I minimized and the lag came back.

Then, just to be sure, i disabled ALL the draw code in those objects.
And... same story...
if no draw code is run by a large amount of objects, and the lag comes back,
I think i can safely conclude that yes, the minimizing and maximizing the game window is definitely at fault here.
 
I don't have an answer, but I've noticed this behaviour sometimes when min/maxing my game, the fps drops inexplicably the same way you describe. Sometimes can fix it by switching between true full screen and windowed mode. I'm not sure if it's still doing this on the latest build of GMS 2, will go check it later.
 
I don't have an answer, but I've noticed this behaviour sometimes when min/maxing my game, the fps drops inexplicably the same way you describe. Sometimes can fix it by switching between true full screen and windowed mode. I'm not sure if it's still doing this on the latest build of GMS 2, will go check it later.
I've made quite a lot of progress. Learning about the debugger and the profiler, I was able to reduce any causes of lag in my objects themselves. Game runs smooooth as butter now even with object counts in the thousands (all with their own code in step and draw event).
Still, minimizing and maximizing seems to give the same drop in framerate. This time, after optimizing everything in the objects themselves, the game no longer drops below 60. But I do see a hit in the FPS. From FPS like 150 down to like 70 - 85. Still just above the required 60, and I no longer notice it. But once I add more things to the game this problem can come back, as the drop in FPS from minimizing clearly remains.
 
To see what surfaces and texture groups are currently in use you have to pause the game in the debugger. Once you click pause look at the tabs where the output console is and there should be one called graphics or something. There you will find an option for texture pages and surfaces. So basically whenever you want to check the current status of surfaces pause! Once paused you can see other stuff like active objects, variables etc.

Also make sure the debug overlay is on, show_debug_overlay(true) this will show a bar at the top with important information about your game, fps, how many texture swaps and most importantly a graph condensing all the object events. If you look at the docs it explains what the colors mean, but this would let you see what event is causing the issue, step or draw.

Also, depending on your game this may or may not be incredibly difficult. But if possible you might want to remove everything and then start putting things back one by one and testing each time until you find the issue.

Also also, how are you handling full screen? Have you tested in a windowed mode to see if it makes a difference?
 
Oh and are you playing with vsync on? If not then that i would turn it on. My game runs around 300fps on my good computer and on that of I can play without vsync. But on my office PC I only get about 150 fps and it can drop to 100 when everything is active but even though it's well over 60 it still has lag unless vsync is enabled, then it's smooth. So my point is if your getting just over 60 fps it might not be enough to play without vsync.
 
Oh and are you playing with vsync on? If not then that i would turn it on. My game runs around 300fps on my good computer and on that of I can play without vsync. But on my office PC I only get about 150 fps and it can drop to 100 when everything is active but even though it's well over 60 it still has lag unless vsync is enabled, then it's smooth. So my point is if your getting just over 60 fps it might not be enough to play without vsync.
I have never tried checking that! Will definitely look into that :)
 

Ido-f

Member
Are you regularly playing other games?
It might be a flaw in your computer/operating system/drivers/hardware
In my machine for example some games lag when there is no audio device connected or sometimes when speakers are conected instead of headphones - in which case I exit those games and restart them until it's rather fixed. My point is computers can be quite buggy.
It's not really something you can check with small GM projects, so I suggest you try to check if it happens with other, published, preferrably GM-made games.

It wouldn't hurt to make sure your video card driver is updated.
 
Top