is it possible to run a python script list threaded?

But aren’t they “helping” the BGE? as far as I know the BGE is not multithreaded.

EDIT: by helping it, I mean, that with new threads the SO can sends them to new cores.

I can run about 18 duplicates of my mech, but the bottle neck there is animations (I am not sure why the bge can’t handle as many?)

however at 60 fps with 18 mechs, I am running 5 ms logic (with everything)

I am thinking that levels with swarms (no armature) can run about 1825 ‘drones’ with a head, a core and a gun or a bomb

this is a limitation I will face in the demo(maybe more once I push health management to weapons and actor cores),

however, I kinda wanted to thread the full version, as I want to add multiplayer,

*I kinda want to

But aren’t they “helping” the BGE? as far as I know the BGE is not multithreaded.

No. Imagine you’re writing a script, but you couldn’t control which order the lines were run in. It would fail completely, right? You’d have to schedule which order to do things, wait for those things to be done, then integrate the results back into the original work flow. If that sounds like a lot of work, well, it’s because it is. The time saved by running multiple calculations on different cores needs to be greater than the time taken to manage the threads.

however, I kinda wanted to thread the full version, as I want to add multiplayer,

I’d strongly suggest building in multiplayer from the beginning. It’s a very different way to code and manage objects. For example, in my network game the objects that represent other players don’t have any logic (or python) on them at all; it’s all controlled by a central script on an empty that is picking up position and other messages from the network then applying them to the appropriate target.

I’m not sure what else to suggest to improve the processing, other than trying to rethink how much you really need to do on each object every frame. I can see that you’ve got rays on these objects, do the rays need to keep working after the blocks are merged? I feel like maybe you could have a central point of control that has several limbs, as opposed to your current model of having data trickle to the points it ends up being used. Just a thought.

the order the list is proccessed in does not matter,

just that it is proccessed, in this case,

each thread will just be doing the same thing to a different part,
right?

Imagine this situation. I’m changing the order of a list by removing the middle element.
list = [0,1,2,3,4]
thing = list.pop(2)

There are two things that just happened in that “pop” command:

  1. You copied the element at position 2
  2. You removed the element at position 2

What stops another thread from doing something to the list between those two actions? The GIL. It holds control until the process is complete. That’s how Python threads can access the same variables and never corrupt them, because there is no actual concurrent processing going on.

What you’re thinking of designing is still within the GILs control. So no… you are still not even saving any processor time using threads. Think of it like a busy little worker that keeps jumping between threads to do the next task. It’s actually random which thread it goes to… go do some reasearch on the GIL.

This leaves us with separate processes that ether share information by accessing each others RAM, or by communicating with sockets. Sharing RAM is very dangerous, so lets ignore that for a moment. Sockets means preparing the task in a way you can send it, and having something recieve the result so it can apply it to the game engine.

have - set pop ( a list)

and then (marked run first) Pop elements before initiating the threaded task?

so (pop command)
run thread
pop command
run thread

?

any thing that changes the size of the list is done before the list is processed?

Imagine two guys in different rooms. They share a cake. This is multithreading.
The first guy eats the whole cake.
The second guy cuts the cake in to four pieces and eats one of them.
See how this would cause a paradox? There’s only one cake, you have to be careful what happens to it. Even if neither guy eats the cake, they still can’t be sure about it because there’s no communication between the rooms. You have to wait until one room is finished with its action before the other one can start.

Now imagine there’s a runner, a guy going back and forth between the two rooms with the cake. This is multiprocessing with socket communication, a little like how multiplayer is handled. One room sends the guy off to get the cake, while waiting for him to come back, that room can be busy making another cake, or filling in tax returns, or doing their nails or something.

So why use multithreading? isn’t it useless then? Well imagine the first guy is baking a cake, (or downloading a file) he has to wait until that’s finished before he can do anything else. He’s just waiting for the cake to bake. But we don’t have to wait, we can go on doing stuff in the other room, but we have to keep checking that the first guy isn’t doing anything paradoxical and that slows us down a bit.

Multithreading is useful because the computer won’t lock up while waiting for an outside process to finish (what people call I/O tasks, input/output). But the downside is that it slows down performance a bit.

In short, threading is for IO bound operations, and processing for single core applications that can be optimised using multiple processes. You can’t easily port a single core application to multiple cores, because there are design requirements when using multiple cores.

You should rarely need extra cpu cores in the BGE, unless you’re writing everything in python (frameworks, not simple scripts like you’ve poste).

Having more cores isn’t always useful. For parallel processing, a GPU will best the cpu hands down. Only certain tasks are suited to multiple cores.

So, Should Ai vision cone raycasts be in the framework ?

Aiming a gun?

raycasting from the gun to see if I should fire?

I thought my design was efficient, rather then each component containing code, this list runs 1 script to process all of them.

reducing the overhead right?

It’s not necessarily more efficient, but it does have advatantages. Like you can control the order which things happen in, or you can pause processing of some actions without affecting others.

The standard logic brick system of blender is probably a bit faster.

To improve speed you could try putting attached blocks in to a dormant state so they don’t get processed.

For animations you can only try to use less polys, no IK (if possible) and less bones to improve performance.

I do only proccess attached blocks,

if they are unparented they are popped off the list

they are added to the list on assembly

also, rayCast to a random position in a cone, seems to be the most efficient way to use a vision cone that I have found, trying to use logic and ray sensor
requires a bunch of bricks,

I’m still a beginner but from what I learned, Python isn’t good with running loops at every frame, I’d rather fork out the loop onto its own python controller and skip a few frames with Always sensor, this will help raise performance significantly

I can already do that, by changing the tic rate of the processor,

it works , I can also randomly discard proccessing, which works well to run large
groups of enemies, but not to make hover cars fly,

The whole point is, the problems you discover will not be resolved by using multiple cores. It will just push the limits just a little bit.

Thinking “I have two cores now i can process twice as much as with a single one” is simply an illusion. This can happen when your application has a effort of O(n). Even then it will not be doubled, as you need to consider the additional management overhead which can eat any benefits quite easily.

In your situation I think it is more worth to think about how you can save processing time.

This is one of the big challenges of game development … satisfying the “nearly-realtime”-requirement.

Seeing some of your published work, I’m pretty sure you use the number one (logic) performance killer of a typical bge beginner:


It is like pressing the gas pedal all the time even when the car is standing.

The idea of an event system is to
[INDENT][INDENT][INDENT]act when your need it. [/INDENT][/INDENT][/INDENT]

This also means do not act if you do not need it.

  • Looking for an event (polling) is acting too. It simply eats processing time.
  • Triggering a controller - eats processing time
  • Triggering a Python controller - eats processing time
  • Triggering a Python controller that does nothing - eats processing time
  • Triggering a Python controller that checks conditions - eats processing time
  • Triggering a Python controller that sets variables -eats processing time

    each single line of your code eats processing time.

To avoid that -> act when your need it -> avoid to act as much as you can.

An event system reacts on events. The BGE does this via sensors. The sensor is your event (regardless if the framework might poll the sensor). The sensor is native code = much faster than everything you can do via Python.

Number two performance killer:
[INDENT][INDENT][INDENT]bad design[/INDENT][/INDENT][/INDENT]

Bad design kills several performance aspects:

  • the game logic execution time
  • the development time
  • the maintenance time

This can be mutually contradictory. Often it is not. So you need to find a balance between these aspects. The main focus … nearly-realtime execution! [this is no excuse for dirty code]

Sometimes you can save tons of processing time, just by little changes on the design of your game.

Example: your enemy has a near sensor to detect the player avatar?
That is fine.

You have 100 enemies. How many nears sensors are detecting now?
-> 100

I hope you know near sensors are heavy sensors (= long processing time).

Now do a design change:
Have one object checking the surrounding of the player avatar for enemies. This object notifies each detected enemy that it is near the player. How many near sensors do you need?

I hope you see, a different design can increase performance significantly. But it can result in the opposite effect too!

(imagine you have 100 players and one enemy :wink: )

Yeah, the thing is the system is used to attack enemies, and to attack the player

everything is very flexible,

I can hack a enemy robot and order him to attack another unit, or to navigate to a point
if he is navigating, and he sees another unit, if it is hostile, he will try and kill it,

I am adding some code soon as well, that if a friendly unit is spotted, and it has a enemy targeted, the
friendly will target the same unit,

everything works really really well the way I have it, and I have not hit a wall at all as far as logic per enemy

it’s more like anything more then 180 active components,

I can cull the component list as well somehow, (is it in 80 units of active player?)

and maybe even have ‘Do not cull’ as a Boolean in each component (for some scenes where actors are persistent)

Have you seen wrectified in the last few days Monster?

it has grown by leaps and bounds, as everything uses flexible soft coded systems :smiley:

You did not complaint about flexibility. Flexibility is nice. I try to do that as much as I can.

You complaint about performance. That can easily be the price for flexibility. I know that from my own experience. Therefore you sometimes need to reduce flexibility and focus on the things you really need.

So you have 180 components per enemy?

no, each enemy is a core(not in this script) , and each core has x jacks.

each jack can hold a lifter, head, gun arm or seat,

I wish you could debug how long 1 specific script was taking,

this way I could optimize.

most enemies are
1 head, 2 arms 1 core

1 head, 1 arm, 3 or 4 lifters 1 core

1 head, 1 core, 1 arm

at the most a single enemy will have 7 jacks.

(until they add the ability to libNew a new physics mesh)
then I can make assembles using more then 1 core.

You can measure the time your uses with the time module.

It is a bit hacky as this integrates with your code. basically you measure the time when entering the code and the time before leaving, then you can calculate and output the duration.

I did that in the past. There might be some profiling modules out there that provide better support. Unfortunately this eats more processing time.

This information can help you to improve a single instance of your enemies. You should also look if you can improve a group of enemies e.g. by using a sort of LOD to skip enemies out-of-sight. Maybe you can replace them by a “virtual enemy”.

Sometimes you get to a point where you can’t optimize any more. Don’t worry about it. If the game is crashing or jittering down to 5 frames per second, then you need to fix it somehow.

Otherwise just see how many agents you can comfortably run with a good framerate and design your game so there’s never more agents in the playing area than that.

Monster is right about scheduling tasks too. Although you need to move once a frame to keep the appearance of fluid movement you only have to check once ever 12 frames to avoid obstacles, and once every 30 for the nearest enemy. An AI could go for a whole second (60 tics) before it needs to make a behaviour check.

Or you could make those checks dependent on some event, so only change strategy again when you take x amount of damage or when you run out of ammo.

one thing I need to do, is some how dyschronize the steering actuators
(they fire every 15 frames) but if all units start on the same frame,
it makes one heavy frame every 15, rather then spreading it out over time.

can I use a object to get a list of its sensors?

I guess I could just add in the objects on different frames?

another thing I could do is randomly dump some of the calculations, that worked for large mobs when I was testing, but I need to ensure this does not happen with lifters, as the fly and maintain zenith by thrust vectoring.