Reduce lag with perlin noise/random map generator

Hi,

I started working on a new project, in which I’m using procedural generation for the first time. So far, it has been great! I followed this tutorial Implementing Procedural Generation [GDevelop wiki] and it worked perfectly.

The problem is, I noticed that the map size (sizeX; sizeY) can’t be very big, otherwise it both takes 2+ minutes to load, and the game also drops the fps noticeably. The “limit” that I found is 64x64 sizeX and sizeY (I’m using 8x8 sprites as tiles/colours), which is a 516 x 516 pixels map. It loads in less than 15 seconds, and the FPS remains ok.

However, I’d like to generate a map way bigger than this (maybe 4x ou 8x this size - 2048x2048 or 4096x4096). Is it possible? I mean, would it be possible for GDevelop to only load the map in which your camera is? And, if you move/avance in the map, it keeps generating procedurally? I though this was actual procedural generation, and the tutorial that I’ve linked is a “random map generator”, but pardon me if I’m wrong.

Anyway, any help is very much appreciated. I’m going to leave this picture with my events and the preview. (I’m using 255x240 resolution and 8x8 sprites/tiles btw, so this preview only takes a quarter of the map).

Thank you very much!

Ideally, could GDevelop actually handle this size of map I mentioned? If it’s 512x512 (the grid, meaning 4096x4096 in total “resolution”), for exemple, that would be 262.144 objects (of 8x8 each) needed to load…As I mentioned, 64x64 (4.096 objects, or 512x512 resolution), was the largest map my gdevelop could handle.

I’m not a programmer, so I really don’t have a clue about it. I’ve been thinking now: how can Minecraft or No Man’s Sky load those almost infinite maps? Just out of curiosity…I understand that not everything is rendered, only what’s near you, but still is hard for me to figure it out. Can someone give me some insights about the limitations of GDevelop on that matter?

EDIT:

These are the things I tested:

  1. Not creating also the “colour” sprite. That obviously reduces by half the amount of objects created, so it loads way faster. I could load a 128x128 map (1024x1024 pixels) with the grayscale map and I also colored them - this is not ideal, since some parts of the map are more visible than others.

  2. Deleting the tile/color sprite when the opacity is near 150 (which is, I would say, 70% of the map, which in my new project is the sea) and just changed the background color of the scene to blue. This reduced as well the number of objects created, but I didn’t noticed a major improvement.

The generation that you use is to create the game world on the engine. You create a lot of objects in loops that in fact you do not need now, you load the entire game world into memory.

The Minecraft world generation algorithm includes biome and terrain generation. In terms of terrain creation, early versions used a 2D Perlin noise heightmap.
Minecraft - I believe there are sources on the Internet that describe how everything works there.

If we consider your example, then one of the options for generating a map is to create it not in memory from objects, but in a file. That is, you create a file (for example, json), which in the form of a two-dimensional array will represent your map: each element of the array is an index (type) of the area. The size of such an array can be anything, but you will display the map in the engine depending on the position of the player and his “visibility range”. Thus, only the necessary part of the map will be drawn and displayed, which will be clearly faster. The very process of generating a map, you can “hide” at the time of creating (loading) a new game.

1 Like

Thanks for your answer. I’m going to try working on that.

What I did, so far, was two things:

  1. Used only the “tile” object, so this is the only object that is created massively. After that, I changed the animation of the tile object based on its opacity (from the extendedmath/perlin noise function). I can now load maps of 800x800 pixels (100x100 blocks of 8x8 pixels; or 10.000 8x8 sprite objects) and the fps drop is very minimum.

  2. Since I wanted a bigger map, I decided to create 4 scenes. This is not ideal, but here how it went: on the menu of the game, I already decided the seeds of the 4 scenes and storaged them in global variables (yes, each scene has one seed, that is what I think it’s a problem, because it kinda kills the idea a bit). So when traveling through a certain point, you’re moved to the new scene (with the other seed that has been already generated on the menu). I can now storage these 4 seeds to create some sort of save function.

Also, this allows me to create dungeons with the same method. All I need to do is, on the very first scene of the game (which, in my case, is the menu), to generate the seed from the new scene I want, and then just paste it when entering the specific scene.

I’m not sure if this is helpful, or a good solution, but if anyone is reading this, I hope you find it useful.

1 Like