Making tasks run on separate threads

Hello, I have a program where it uses perlin noise to generate heightfield maps and then uses Panda’s GeoMipTerrain to make terrain out of them. This is done on the fly when the player walks towards the edge of the current “chunk”. However I’m having a bit of a problem enabling this to run at a good speed. I’ve tried lowering the chunksize but there is still a noticeable spike which sometimes causes the player to fall through terrain. I’ve attached the image from PStats.

I think I’ve narrowed it down to the part where the heightfield map is used by GeoMipTerrain to generate the map. The main point of this topic though is that I was playing around with the idea of running this function on a separate thread hoping that maybe this would stop the lag spikes and allow the player to move smoothly while it loads (I’m not sure if this is how it works). So I created a task manager (and added the terrain load function to it) like this:

taskMgr.setupTaskChain('custom task chain', numThreads = 1, tickClock = None,     #Task chain for separate thread
                       threadPriority = TP_normal, frameBudget = -1,
                       frameSync = False, timeslicePriority = None) 

taskMgr.add(self.checkForChunks, 'Check chunks to be loaded', taskChain = 'custom task chain')

However whenever I set numThreads to more than 0, the game freezes on startup with a grey background (sometimes the skybox is loaded). Is there something I’m missing? Is this the right way of going about it? I’ve got the code for the chunk loading function at pastebin with the area I believe to be the time consuming part:


I’m probably wrong, but you might be coming across the same kind of issue as per here:

“In fact, it’s almost certain that GeoMipTerrain isn’t thread-safe, because of a current known problem with Panda’s geom structures which appear to be non-thread-safe when regenerating.”

If i understand correctly, the code you have on pastebin is not in the thread right? (If it is you are creating a new geomip terrain instance every frame. These build up which might be your problem).

So which code do you specifically have in the thread (in the self.checkForChunks method)?
If this is indeed the geomip.update method then you are running into the same problem as in the post Maikeru mentioned.

Ah yes that might be the problem, I did see that post when I was reading into threads, but I didn’t think it was the same thing.

The code on pastebin is for creating the geomipterrain instance, but it isn’t run every frame. The task in the thread is self.checkForChunk and it checks to see if a new chunk is needed. (if they are, it creates a chunk and runs chunk.makeChunk)

My geomip.update method is part of the main task chain.

Do you think GeoMipTerrain will be thread-safe in future updates or will I need to look at other ways? Thanks for all the help so far :slight_smile:

GeoMipTerrain in itself not being thread-safe isn’t a huge problem; the problem is that geometry generation in general is causing this issue. It’s a known bug.

Ah I see, so would it be better to leave the generation function in the main task chain in the meantime and look at other ways to make it run smoothly?

It seems so, yes.
Would it be possible to generate the whole terrain at the beginning, or at specific ‘loading’ borders? Perhaps save them as bam files on the drive, or keep them open if they aren’t huge.
I’m currently just patiently waiting till the geometry bug is fixed :slight_smile:

Hmmm, well the aim was to make the terrain randomly generating near endlessly like minecraft, but perhaps I could generate bigger terrain chunks and have a loading screen when the new area loads or something. Hopefully in future updates this will be sorted out :slight_smile: