Multi-Threading Lua

This lua plugin appears to have multithreading support:

My question is thusly;

How do?

What do you need threads for?

Because my 3 servers run at max cpu at about 30 players, and i have 3 more cores doing absolutely nothing.

Coroutines aren’t good enough.

The max CPU is being caused by physics calculations, not Lua scripts.

If it is being caused by Lua scripts then threads aren’t the solution :v:

You can try lowering the tickrate on your server in order to reduce the number of physics calculations per second.

You should be looking into the cause of what makes your servers use so much CPU and not trying to remedy the side effects.

The module you linked probably doesn’t work with gLua and it’s apparently also lacking vital synchronization features like mutexes which makes it pretty useless anyways.
What kind of server are you running?
It’s probably some hook like PlayerCanHearPlayersVoice that is causing a lot of lag.

Actually it can be. There are so many different things that could be done in a seperate thread. Unfortunately Garry’s Mod (and source in general) just doesn’t do that…,

The solution would be first to find out what on earth you’re doing to cause the CPU to max out from Lua before you just start throwing threads around

Of course, multithreading doesn’t solve the issue if your algorithms are bad.
The PlayerCanHearPlayersVoice hook is quadratic by itself and can easily become quartic if you aren’t cautious.
The fact still remains that Garry’s Mod performance in general would increase significantly if it was properly using multiple threads.

local function comms_PlayerInitSpawn( ply )
ply.lastHearCalc = 0
ply.canHear = {}
hook.Add( “PlayerInitialSpawn”, “comm_PlyInitSpawn”, comms_PlayerInitSpawn )

– Voice Chat Settings
local voice_offset = Vector( 0,0,40 )
local maxdistSqr = 2000^2
local pos1

– Voice chat calculator so it isnt so damn expensive
local function SortPlayerCanHear()
while( true ) do
for k,ply in pairs( player.GetAll() ) do
if( !IsValidPlayer( ply ) ) then continue end
pos1 = ply:GetPos()+voice_offset

        for i,talker in pairs( player.GetAll() ) do
            if( talker == ply ) then continue end
            ply.canHear[ talker:UniqueID() ] = ( ply:IsAllied( talker ) || !util.TraceLine( { start=pos1, endpos=talker:GetPos()+voice_offset, filter={ply,talker} } ).Hit )

local co_CanHear = coroutine.create( SortPlayerCanHear )
timer.Create( “GMPlayerCanHear”, 0.2, 0, function() coroutine.resume( co_CanHear ) end )

function GM:PlayerCanHearPlayersVoice(ply, talker, other)
return ply.canHear[ talker:UniqueID() ], false


I’ve been using DBugR to help optimize the code.
I’ve optimized, re-written and/or otherwise slowed down timers to the point of near-breaking point just to squeeze every last cpu cycle out.

As i have said;

Also, extremely efficient GM:PlayerCanHearPlayersVoice hook on the house.

Are you calling ents.FindInCone or other ents.FindIn* functions every frame? FindInCone can reduce FPS by half if called every frame to detect things to render / not render ( I used to use it for my vehicle lighting system… It is much cheaper to just process the Distance / location of each spawned vehicle than using ents.FindInCone )…

What game-mode are you running? How many addons? What addons? Etc…

What’s your tickrate and how many fps does your server get with 30 players online? (use stats in server console)

I’ve re-written most every aspect of the gamemode (and addons) to either avoid using ents.Find* entirely, or run using slowed timers and/or coroutines when applicable.

A complete re-write of Basewars in my own vision, from scratch where only using the original as a reference (for hook names etc)
The drain from addons is pretty miniscule based on the data from DBugR.

+fps_max 128 -tickrate 33

Not sure what the “fps” is at 30 players, but it starts to cap out a 3.1Ghz cpu to 110% after about the 29th player has spawned in.

Is it basewars by chance?

Unless there’s lots of entity collisions you’re missing there’s something wrong somewhere and it may not show up on DBugR.
You can probably get away with a 16 tick as a temporary solution to keep your servers stable.