Can i update overlay scene in for loop while using libload?


I have dived into making a loading screen… Succes.

But i want to show some kind of progress, so i use a text object to show what blend is loading, but this does not work due to the loading screen(overlay) won’t update.

My question: can i update an overlay scene in a for loop while using libload to show the blend that get’s loaded?

Here is my whole test setup:

(It’s a .zip file around 21.68 MB. (6 test blend files to get atleast a few seconds load time)
Unpack and run the ‘my game’.blend, read the whole script first and then after reading HIT P TO START LOADING).

what about a for loop, that sends a message packet?


each time another files libload is finished, by marching through a list, and counting how many parts were loaded?

or even spam the message each frame

1/10, 1/10, 2/10 etc, but this will probably use more resources then something setup to update is a value changes*

or even spam the message each frame

well this is kinda my problem, it looks like everything loads in 1 frame, so the only thing that is working at that frame is the for loop.
this means i need to find a way to update the overlay scene trough the for loop, in order to refresh it, but i have no idea if this is even possible to do.

the blend file has an animation, it stands still while loading. so i know that the overlay is not updating

what about a for loop, that sends a message packet?

i am in a for loop that tells the overlay to change the text, it doesnt work, so messages wont work either.

Yes, when you request LibLoad to run in asynch mode.

A loop makes no sense as it blocks the consecutive processing of the BGE (including render). When not running LibLoad asynchronously it already does that … blocking the game until the load completed. This is pretty much what happens when you switch a scene.

Doesn’t work. Async mode actually only makes async the loading of the file, loading the scene (wich is what takes more time) is still atached to the main loop.

Wich means, no you won’t be able to make anything smoothly on a loading screen no matter what you do (unless you load chuncks of a level small enough that they don’t effect the framerate)

no you won’t be able to make anything smoothly on a loading screen

it does not have to be smooth. i only want to update text object.

Also i tried to use async, it looks like async loads the blends after the whole for loop is done.
my overlay get almost instant removed, then you see it loading the blends 1 by 1.

why is it that it loads ouside the for loop with async?
is there anyway to keep it loading in the loop so that the overlay stays until loading is done?

because now the whole mainloop is done before it starts loading.

here is the script i use and works as a static loading screen

from bge import logic

def blend_file():
    blend_files = ['test', 'test2', 'test3', 'test4', 'test5', 'test6']   
    return blend_files

def load_blend(blend_name):
    #path where you are holding the blends to libload    
    path    = logic.expandPath('//libload/' + blend_name)
    load    = logic.LibLoad(path,'Scene')
def lib_load(cont):
    own = cont.owner
    if not 'lib_loaded' in own:        
        print('start loading blend files!')
        blend_files = blend_file()    
        for blend in blend_files:
            blend_name = blend + '.Blend'


        own['lib_loaded']       = True 
        own['loading_ready']    = True
        print('loading blend files done!')

as soon as i use async = True, the loading screen wont work and blender will crash 6 out of 10 times.

ok i now got some sort of dynamic loading screen. i used the onFinish command to ad +1 to a property
when it hits the total number of blends loaded it ends the overlay scene. downside loading takes almost twice as long.

We can kinda update the overlay but as said above it wont run smoothly. but i can now make a progress indicator like Loading: assets, loading: world, etc. or even make a progressbar that fills 1/6th each time a blend is loaded.

but to be sure if this is working well i would like to have some people who can test it for me.
the console will output the loading time for each blend.

Download the package from first post and replace ‘my game.blend’ with the one below (or create directory libload, and put 6 test blends in it (test, test2,test3,etc)):
my game.blend (501 KB)

while the static loading screen acts faster, is this setup a good option?
or is there a better way to do it?

To be honest, I forget about async libload and just go with non-async:

load one blend
update text
load the next
update text

I used to play around with libload a lot, and, well, these days I go for the simple option.

Async removes the frame dependency, that is all. So it makes you able to keep the game updating while things are loaded - except for the scene merge, which if you have a lot of lights and materials, will take a while.

To be honest, I forget about async

i am thinking the same due to async is kinda something else to handle, but without async how do you load 1 blend skip a frame(update hud) and load the next one, due to i am loading it trough a for loop and that will load all in 1 frame so no time to update any text.

the .onFinish does not work without async.

with async, this will update a property but the loadingscreen can’t grab the property and use it.

from bge import logic

def blend_files():

    blend_files = ['test', 'test2', 'test3', 'test4', 'test5', 'test6'] 
    return blend_files

def get_scene(scene_name):
    scenes = logic.getSceneList()   
    scene = None
    for sce in scenes:
        if == scene_name:
            scene = sce
    return scene

def test(status):

    obj = get_scene('Scene').objects['libloader']
    obj['loaded_blends'] +=1
    blends_to_load = blend_files()
    if obj['loaded_blends'] == len(blends_to_load):
        print('loading done')
        obj['loading_ready'] = True
def lib_load(cont):
    blends_to_load = blend_files()
    for blend in blends_to_load:
        blend_name = blend + '.Blend' 
        path    = logic.expandPath('//libload/' + blend_name)
        load    = logic.LibLoad(path,'Scene', async=True)
        load.onFinish = test

For example you make a queue and pop the last element each frame (until the queue is empty). You update the poo :spin:

You write a script that

  • determines what scene to load next
  • loads exactly that one scene.

You just need to remember (e.g. via property) what scene was loaded last, so you can calculate the next one.

I needed to find a way around the for loop, and found a way.
Now i have a working loading screen with progress text and a working loadingbar

Only thing i want to know is this the smoothest it can get…animation wise?
i guess its due to loading the blends but if there is a way to smooth that out, then we can have really nice loading screens.

Here is the working blend:
loading screen.blend (474 KB) (don’t forget to adjust the blends and path to it)

Only way to get smoother I think would be to make your own level editor. You store each model on a diferent blend so they are small enough to almost no effect framerate when being libloaded and then you read a file where you’ve stored the transforms of every object on the scene.

Actually that’s similar to the tesselated terrain technique for open worlds that has been discused here in the past.

As loading a single blend is the smallest time scale you get, there is nothing that can smooth it any further.

You could create either small scenes to load, or load parts of a scene step by step (e.g. by loading just a few meshes into the current scene).

You could create a Blender script that analyzes your source scenes and creates code/data that allows loading from within BGE (As there are no such operations available within the BGE).

ok thanks for all the info, it really helped, time to put this topic on solved :slight_smile:

i am happy enough with how the loading screen is now.