BGE Scene redraw(refresh)

Hi guys,
I’m using LibLoad(inside a for loop) to load terrain tiles into a scene, but tiles are being drawn only when the last tile is loaded. Is there a function to redraw the scene-> draw a terrain tile right after it’s loaded?

thanks in advance

Avoid any long lasting loops. You have less then 1s/60 time to process the logic.

You can perform the loading asynchronously. This way the logic does not wait until it is finished and smoothly continues.

Or you could load just a single tile per frame, that’s still 60 tiles per second.

Do you mean that by async=True the logic will be loaded independently, so when there’s a lot of logic, it will be loaded over more than one logic tic?

In clarification I believe it is a non asynchronous libload (blocking libload) inside a single frame. You should stagger this or perform it asynchronously to solve your request

Thanks guys, but I actually use asynchronous loading, here’s the code:

import bge

def finished_cb(status):
    print("Library (%s) loaded in %.2fms." % (status.libraryName, status.timeTaken,))
for i in range(0,16):
    for j in range(0,1):
          bge.logic.LibLoad('g:\\Blender\\ArmaProject\\BlendTerra\\Data\\Tiles\\Terrain_'  + str(i) + '_' + str(j) + '.blend', 'Scene',async=True).onFinish =  finished_cb

and here’s the output of the finished_cb function:

In this case I just load first row of terrain tiles. Firstly, loop prints tile name(x y) and run LibLoad(note that ‘0 0’ is printed out twice,what causes the following error message ‘blend file already open’, have no idea why it tries to open ‘0 0’ twice) and finally the ‘finished_cb’ prints loading progress and here comes my problem… all terrain tiles are drawn in the scene at once after terrain tile ‘7 0’(the last in the list) is loaded. What I want to achieve is to force BGE to redraw the scene everytime a single tile is loaded. To be even more precise this is what does happen:
-after pressing ‘P’ I have empty scene and fps 60, after pressing ‘M’ to load tiles fps drops down to about 20 and I get deadlock(BGE is not reacting) till the last tile is loaded, then all terrain tiles are drawn at once and fps back to 60.

Thnx Monster, long loop was exactly the problem. Now I feed ‘Always’ sensor with only one terrain tile per logic run and it draws tiles once they are loaded.

A style suggestion, use format instead of string concatentation (str + str):

          filePath = 'g:\\Blender\\ArmaProject\\BlendTerra\\Data\\Tiles\\Terrain_{}_{}.blend'.format(i,j)
          bge.logic.LibLoad(filePath, 'Scene',async=True).onFinish =  finished_cb

It’s more efficient and readable.

To force a redraw upon load, you could try adding bge.logic.NextFrame() to the callback function. I’m not complete sure how it works but it’s supposed to render the next frame (sjoerd knows more about this).

I think async creates an actual thread for the operation. The framerate drops because you’re creating n=16 threads in a single logic tick, including whatever else LibLoad does like allocating memory, etc. Notice how each successive LibLoad takes longer to load than the previous one; obviously, there is a bottleneck somewhere, possibly IO and/or multithreading issues. So the async option is really there to prevent LibLoad from blocking the game logic from running, however, it doesn’t mean the logic tick rate will not be unaffected.

One way to prevent lagging is to load anywhere from 1-15 tile(s) per logic tick; experiment with this. This will distribute the loading over multiple logic tics. So create a list object that contains all the filepaths and on every logic tick, iterate through the list. Furthermore, you could begin loading the next one in the callback function so they load back to back asap. The safest bet would be loading 1 tile per logic tick. If it’s still lagging, then possibly break it up into further blend files or see if you can simplify the blend files.

bge.logic.NextFrame will only work inside a script that grabs the main loop. It will not work inside a Python controller.

Thnx for really valuable info, I read one tile(blend file) per logic tick now, but I also like the idea of splitting loading among more ‘Always’ sensors.

In what order are logic bricks executed, one by one or all at once(per object)?

Please read the BGE Guides in my signature. It explains how the logic works :smiley:

Thank you Monster, it looks useful.