How to optimize your game?

I was wondering what techniques/code you use to make your game run better and load faster?

After exporting a game as a runtime (and playing it) the game can sometimes take up to 20 seconds to load (startup) leaving just a blank white screen. This can often be frustrating and give the impression that your game is buggy and not in a playable state.

I can think of a few obvious things such as:
-Texture size
-Poly count
-Number of lights in the scene at once.
-LOD
-Putting everything in one .blend?

I mainly want to make this thread a sort of checklist which you can refer to before exporting out a game.

Any contributions/links/demo’s are greatly appreciated!

Initiation time is a big problem.
You can get around the white screen of death by having a simple menu scene as your first scene. Then have a “press space to start” message. When they press space, change the text to “loading…” THEN load the main scene.

The loading screen will be displayed while your main scene is initiating. It doesn’t look that much better but it’s better than thinking the game has crashed, especially on a first impression.

I think the newest version of blender has even longer initiation time than ever! some of the improvements have made it much faster when playing, but that first start up stage is a killer.

If you want to cut down on loading time perhaps reducing the complexity of your armatures can help. I think the threaded armatures feature is causing a lot of the wait time when first loading. I’ve tried loading scenes with and without armatures and it makes a difference. Less bones, fewer constraints and IK… these can help a little.

Another way to improve loading time is to save info about your scene (enemy positions, level design or whatever) to a TXT file and then load them up in to the main scene when you first start the game. However the trick is to load objects sequentially over several frames of logic instead of all in one logic tic. I don’t know what the technical term for this is but I’d call it chunk loading. We only want to load a chunk of our data at a time, not all in one go.

Here’s a basic outline of chunk loading:

if own['y_chunk'] <= 4: ### the maximum horizontal size
            
            ### declare the regions for this chunk                                        
            x_min = own['x_chunk'] * 10
            x_max = ((own['x_chunk'] +1) * 10)
                                    
            y_min = own['y_chunk'] * 10
            y_max = ((own['y_chunk'] +1) * 10)
            
            ### draw terrain in this chunk square by square            
            for x in range(x_min,x_max):
                for y in range(y_min,y_max):
                
                    draw_terrain(x,y,own) ### another function for drawing terrain
            
            ### increase chunk count                   
            if own['x_chunk'] < 9:
                own['x_chunk'] +=1
            else:
                own['x_chunk'] =0
                own['y_chunk'] +=1           
                
        else:
            ### finish drawing 
            own.state = 2   

You could also arrange your chunks in a list and then calculate the distance from the start point (where the player will be spawned) and load the chunks nearest to the player. Their immediate environment will be loaded instantly and only distant areas will still be loading as they start to move around, so they won’t notice it.

Here’s a basic version of that:

start =  [2,3] 
loading_list = []

### calculate the distance to each chunk from the starting chunk
for x in range(8):
    for y in range(8):
        tile = [x,y]        
        distance = (abs(start[0] - tile[0]) + abs(start[1] - tile[1]))
        
        loading_list.append([distance,tile])

### now sort the loading list so that nearest tiles are at the start of the list        
nearest_chunks = sorted(loading_list,key=lambda sorted_list:sorted_list[0])  

print (nearest_chunks)

You’ll get a list which you can increment through loading one chunk at a time. The result is that you can load thousands of objects with no significant loading delay, its near enough instant even when I loaded over 12000 objects. If you don’t want to let the player roam through the world as it’s still loading, or you want to make sure AI doesn’t become confused by missing world features you can put everything on hold (load everything in an empty state) and show a loading progress bar as your chunks are being loaded. That way although there’s a waiting time, you don’t get the “not responding” message if it takes too long to load.

  • make simplified collision mesh for complex shaped meshes because generating collision meshes take a long time. Also remember to make all objects “No collision” that don’t need collision.

  • most of the python/logic itself is not too heavy but pay attention to how often you run the logic. People overuse “always” sensor with huge pulse rate when they should be really using property or input actuator for example to initiate their script/bricks.

also any object dependent on another, that does not change it’s best to do something like


if 'Target' not in own:
    own['Target']=scene.objects['Object']
else:
    T=own['Target']