Running separate python instance in background to handle extra logic?

I’ve been working on a game for a while now and certain parts of the game are fairly harsh on the logic processing.:mad:
So I was wondering if it is possible to have a separate background instance of python in the background (for use on a separate processor or core) and host a local server that can handle the more resource intensive tasks.(For example, I will be using BPY in my game to generate waves on a surface such as the water in a pool. In a scene with nothing else but a block and the water, the framerate goes from 60 to 30 instantly [meaning I haven’t even made any waves yet]).

You should look at the Python ‘multiprocessing’ module. That have an interface like the ‘threading’ module but it creates separate Python processes instead of threads so you really get parallel execution.

I did look into that but there are 2 problems with using the multiprocessing module.

1.) It isn’t supported in the latest windows python build (Trust me, i’d be using linux if I could).
2.) Native multi-threaded processing is still gimped by python’s GIL and would actually slow things down in this specific case. :frowning:

Yes, it’s possible using the multiprocessing module, though it can be fairly tricky to get it working with the BGE. A few things you should note though:

You shouldn’t use bpy in the game engine unless you’re fine with people only being able to play your game using the internal player and you actually intend to modify the blend file from within the game.

Also any external Python process won’t be able to import and use bpy or bge, so won’t be able to manipulate objects directly. You can give it data to process and have it return the results, but if editing the objects themselves is your bottleneck, it won’t help you much.

EDIT:
The threading module probably won’t help you because as other’s have noted, it is bound by the GIL and can’t use other CPU cores.

@Terra_Byte_Tech
What version isn’t it supported on? I’ve been using it fine on version 3.4.

Actually you can use bpy outside of blender if you manually compile it from the blender source (see: http://stackoverflow.com/questions/10972637/how-can-i-access-bpy-in-standard-python-console-bpy-is-the-blender-python-thin and http://wiki.blender.org/index.php/User%3AIdeasman42/BlenderAsPyModule)

I have already done this and got it running in the standalone runtime.

Ever since I updated to python 3 it has always thrown: ImportError: No module named ‘multiprocessing.spawn’

Can you compile your own C function or wrap it so it can handle threading data entry and return cleanly?

“Uncapped” by Gil?

While it is possible there are a few reasons why you wouldn’t want to do it:
1.) A lot of python’s functions are not “thread safe” and could result in bad calls or corrupted data (which could indirectly result in crashes or even BSODs).

2.) Python’s GIL isn’t just one part of the system, it is integrated throughout the the entire compiler and the bytecode processor.

There was a video posted a while back about why the GIL is here and why it won’t be leaving anytime soon, but it appears that it was deleted. But I at least found the pdf he used in the conference. :slight_smile: http://www.dabeaz.com/python/GIL.pdf

Excerpt from Python3 documentation:

multiprocessing is a package that … It runs on both Unix and Windows.

Have a read of this.

As noted, bge isn’t thread-safe, so you’ll have to use queues to pass data around. In the resources forum you can find a simple threading example I made.

The question I have is: ‘What do you want multithreading for?’
Quite often, it’s not the best solution.

EDIT:
The threading module probably won’t help you because as other’s have noted, it is bound by the GIL and can’t use other CPU cores.

This means that:

runs on 1 core only?

(“Attente” = wait for the thread is finished; “boucle” = loop; “fin de la boucle” = end of the loop (the thread))

If you are still talking about a game, such time intensive processing should not be necessary. Games are focused on entertainment rather than accuracy (if you get free accuracy it is fine ;)).

If you still want your intensive processing, I strongly suggest to keep it away from the BGE. There should be no need for a direct access to the BGE or Blender.

You can to establish a safe interface between BGE and your process. You feed the interface with BGE/Blender data (attention: critical section) and pass back the results from your processing. The BGE can take the results and update the game’s status. So it is more like network communication. (The other process does not even need to be an the same hardware).

just an idea.

Pretty much… however it can sort of “hop” from one processor to the next in between tasks.

This is the sort of thing I was hoping to accomplish.
I also want to make it easy to be reused in more than one way. The game me and my friends are working on is meant to be an advancement of multiple existing concepts (I won’t say what those are yet though as it’s still very much a W.I.P.) and will be made open source for educational and private use. :slight_smile:

Thanks for your answers! I’ll try to study your idea Monster. Do you think using socket module with tcp protocol is a good idea?

I do not have much experience on implementing such architecture. Sockets were the first that crosses my mind. But you need to consider the amount of data to be transferred. So, yes I think that should work.

On a greater extend, you can see the game as UI to feed the simulation and give feedback to the user. This architecture allows to have any number of “clients”. The clients do not even need to be the same e.g. 3D client, textual client, test client. It also helps testing a lot.

Thanks very much for answers! I was thinking about threading for AI (my WIP on jump point search)… I’m wondering if I select more than 10 units, I can delegate pathfinding process for the next ten units in a new “thread” or something to avoid framerate decreases. The only parameters that I give to the pathfinding function are: startPoint on the grid, endPoint on the grid, and the grid itself and the function returns path (list of points with 2 coordinates XY) for each selected player. I don’t know if this is a good idea and I have to think about that…

Nice vertex shader VegetableJuiceF! Can I try to use it for my river:

https://drive.google.com/file/d/0B3GouQIyoCmrLTRPV0RZWjBVbEU/view?usp=sharing

I need to understand how you made that. I abandonned to try to understand Martinsh shader water/underwater, but your code is a little shorter. Thanks for sharing.

Sending the whole grid through socket every time would not be great…
Anyway,
http://puu.sh/d3Io3/e18ffb1e55.gifhttp://puu.sh/d3IDY/a832451d2b.png

I can’t code well for shaders yet, so no normal maps or “real” lights.
Also I didn’t get why you had semi-transparent ground, so that also was also abused by me.

Basically i get the material of the parent object and change its shader into mine.
The shader just moves the vertices by sine and cosine functions.

I can ignore vertices (edge of the river) by painting it black in vertex paint.
Then i only check in my code if vertex is black then ignore.

Made the code better, as the other one was the first one i found in my computer :D.





def main():
    """
    Takes the cont owner's mesh and applies wave 
    function on the vertices through vertex program
    """
    
    cont = bge.logic.getCurrentController()
    own =  cont.owner
    
    # timer for the sine and cosine function 
    own['timer'] = own['timer']+own['speed']
    time = own['timer']    
    
    #get owner mesh
    mesh = own.meshes[0]
    
    #what material ( the mat with index 1 is eau)
    mat  =  mesh.materials[1]
    
    if not "shader" in own:
        # mat.getshader() is a quite heavy on non integrated gpus?
        # just save it in memory
        own["shader"]  = mat.getShader()     
    shader =  own["shader"]    


    if shader != None:
        if not shader.isValid():
            
            # use the shader
            shader.setSource(  VertexShader  , FragmentShader  ,6)               
            
    shader.setUniform1f('timer',time)  
            
                                
            


VertexShader = """
uniform float timer;
//uniform float objTimer; 


void main( void )
{
    float x = gl_Vertex.x;    
    float y = gl_Vertex.y;
 
    float freq = 30;
    
    
    // calculate a scale factor.
    float s = sin( (timer+freq*y) );
    float c = cos( (timer+freq*x));
    float z = 0.0215 * s * c;
    
    // if marked black (not green) ==  no wave 
    if (gl_Color.g < 0.2 ) z = 0;
    
    vec3 offset = vec3(0, 0, z);
   


    // offset the position along the normal.
    vec3 v = gl_Vertex.xyz + offset;


    // transform the attributes.
    gl_Position = gl_ModelViewProjectionMatrix * vec4( v, 1.0 );


       
    float bright = 1+s * c / 2;
    gl_FrontColor = vec4(bright,bright,bright,0);
    gl_TexCoord[0] = gl_MultiTexCoord0;
    
 
}




"""


FragmentShader = """


// does nothing special


uniform float timer;
uniform sampler2D difuse;
void main()
{    
    vec4 dif = texture2D(difuse,gl_TexCoord[0].st);   
    float globalLight = 0.2; 
    gl_FragColor = dif * gl_Color + vec4(0,0,0, 1.0);
}
"""
main()

http://en.wikibooks.org/wiki/GLSL_Programming/Blender
http://www.pasteall.org/blend/33041

Thats awesome VJF! thank you!
This actually solves the majority of my problem. :smiley:
Would it be possible to set up something like a height based texture. (for example, it could also be used to draw contour lines on a mountain using a texture image)

Thanks a lot VegetableJuiceF! I’ll try that and check if this increase performances (previously, I used animated textures). Thanks for the code. I’ll TRY to subdivide river faces, change scale factor and “float z” factor in your initial shader. For lights and specular, I’ll take a look at http://en.wikibooks.org/wiki/GLSL_Programming/Blender/Specular_Highlights… Or I’ll do a spec texture… Thank you!

I would love to see this, as well as a force field (high dampen waves and a repulsive force?) woob woob woob