Loading files gradually causes program to stutter/lag

I’ve made a game with Processing (in fact, it’s been released on Steam! Search “Enter The Backrooms” if you’re interested!) and some of my players have run into an error: if you reload the game over and over, the game will slowly start to lag more and more. I would assume this is a memory issue with loading files since it gets worse after each load. The only solution is to exit the program/executable entirely and restart. Is there some sort of cache that I should be clearing after each load? Why does this effect compound on itself?

It’s very hard to help you without knowing how (and why!) you are loading files while the game is going on.

Ideally, you would only load each thing once, no matter how many times the game has to reload a level/zone/area or restart.

But depending on how much you have to load, dynamically loading some things might actually make sense.

Please post the relevant sections of code that does your loading. Seeing setup() might help, as well and any calls to load*(), or thread(), or any code that does resetting.

2 Likes

the thread() function would probably work in this situation. For asynchrounous tasks like loading files, they take a long time so they make the animation thread stop. You should use the thread() function to run it outside of draw() in order to keep the animation thread running smoothly. Daniel Shiffman on the coding train youtube channel has a great tutorial on it.

Turns out there was a lot of the same stuff loading with each call to my thread(loadSurfaces) and thread(loadSounds) functions, so I moved those to setup() and the problem was significantly diminished, but it still happens after too many reloads. Here’s what loadSurfaces() looks like:

void loadSurfaces() {
surfaceReady=false;
  switch(level) {
  case 0: 
  backrooms=loadImage("surfaces/backrooms.png");
  floor=loadImage("surfaces/carpet1.png");
  ceiling=loadImage("surfaces/ceiling0.png");
  lightTexture=loadImage("lights/light2.png");
  glow=loadImage("effects/glow0.png");
  door=loadImage("decor/door1.png");
  break;
  case 1:
  backrooms=loadImage("surfaces/wall1.png");
  floor=loadImage("surfaces/floor1.jpg");
  ceiling=loadImage("surfaces/ceiling1.jpg");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow1.png");
  door=loadImage("decor/door2.png");
  break;
  case 2:
  backrooms=loadImage("surfaces/wall2.jpg");
  floor=loadImage("surfaces/floor2.jpg");
  ceiling=loadImage("surfaces/ceiling2.jpg");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow1.png");
  door=loadImage("decor/door2.png");
  break;
  case 3:
  backrooms=loadImage("surfaces/wall3.jpg");
  floor=loadImage("surfaces/floor3.jpg");
  ceiling=loadImage("surfaces/ceiling3.png");
  lightTexture=loadImage("lights/light1.png");
  glow=loadImage("effects/glow1.png");
  door=loadImage("decor/door3.png");
  break;
  case 4:
  backrooms=loadImage("surfaces/wall4.png");
  floor=loadImage("surfaces/floor4.jpg");
  ceiling=loadImage("surfaces/ceiling0.png");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow0.png");
  door=loadImage("decor/door3.png");
  break;
  case 5:
  backrooms=loadImage("surfaces/wall5.jpg");
  floor=loadImage("surfaces/floor5.png");
  ceiling=loadImage("surfaces/wall4.png");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow0.png");
  door=loadImage("decor/door2.png");
  door2=loadImage("decor/door1.png");
  break;
  case 6:
  backrooms=loadImage("surfaces/wall6.png");
  floor=loadImage("surfaces/floor6.png");
  ceiling=loadImage("surfaces/ceiling6.png");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow0.png");
  break;
  case 7:
  backrooms=loadImage("surfaces/wall7.png");
  floor=loadImage("surfaces/floor7.png");
  ceiling=loadImage("surfaces/ceiling6.png");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow0.png");
  door=loadImage("decor/door2.png");
  door2=loadImage("decor/door4.png");
  break;
  case 8:
  backrooms=loadImage("surfaces/wall8.jpg");
  floor=loadImage("surfaces/floor8.jpg");
  ceiling=loadImage("surfaces/wall8.jpg");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow0.png");
  break;
  case 9:
  backrooms=loadImage("surfaces/wood.jpg");
  floor=loadImage("surfaces/floor9.png");
  ceiling=loadImage("surfaces/wood.jpg");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow0.png");
  break;
  default:
  backrooms=loadImage("surfaces/wall1.jpg");
  floor=loadImage("surfaces/floor1.jpg");
  ceiling=loadImage("surfaces/ceiling2.jpg");
  lightTexture=loadImage("lights/light3.png");
  glow=loadImage("effects/glow1.png");
  door=loadImage("decor/door1.png");
  break;
  }
  tempWall=backrooms;
  tempFloor=floor;
  tempCeil=ceiling;
  surfaceReady=true;
}

A brief explanation: depending on the level, PImage variables that act as textures for walls are set to a loaded image since each level uses different textures for the walls (backrooms), floor, and ceiling. The loadSounds() function is very similar since different sounds are used on each level as well. Both of these functions are used as threads in a separate loadLevel() function:

void loadLevel() {
  stopSound();
  death="";
  pause=false;
  surfaceReady=false;
  soundReady=false;
  thread("loadSurfaces");
  thread("loadSounds");
}

And then, of course, you have plenty of loading done in setup(), but nothing there is loaded again. Let me know if you’d like to see setup() as well! :slight_smile:

Considering you don’t have an excessive amount of total images in your program, might be worth just loading everything in regardless of the option the user has chosen. At least this way you can set a bool for filesLoaded, and on each reload you would simply check the bool is active.

I’m sure it might not be good practise, but if the images aren’t too big and you have a number that wont cause the ram too much trouble ie 1gb or under then it might be a solution.

Of course if it exceeds 1gb ram and you still want to make use of this method and the program doesn’t crash at startup then you could just stipulate game requirements before download.

2 Likes