Jump to content

Speed up createObject


Gallardo9944

Recommended Posts

Hello.

I've created a map loader, which transfers map data (in a table) to the client side and creates all the stuff there. But a huge table of resources causes a freeze of the game (basically full MTA freeze) depending on the map size (1 sec for a little map, 12 secs fo a big one). How can I speed this up or make it run in some kind of separated thread? Here goes the code:

  
local objnum = #objs 
for i=1,objnum do 
--for i,v in ipairs(objs) do -- This one is slower than a simple "for" from 1 to the objects amount 
    local v = objs[i] 
    local object = createObject(v.model,v.posX,v.posY,v.posZ,v.rotX,v.rotY,v.rotZ) 
    if object then 
      table.insert(objects,object) 
      if v.doublesided == true then 
    setElementDoubleSided(object,v.doublesided) 
      end 
      if v.scale and (v.scale > 1 or v.scale < 1) then 
    setObjectScale(object,v.scale) 
      end 
      if v.interior and tonumber(v.interior) and tonumber(v.interior) > 0 then 
    setElementInterior(object,v.interior) 
      end 
      if v.dimension and tonumber(v.dimension) and tonumber(v.dimension) > 0 then 
    setElementDimension(object,v.dimension) 
      end 
      if v.alpha and not (v.alpha == 255) then 
    setElementAlpha(object,v.alpha) 
      end 
      if v.collisions == false then 
    setElementCollisionsEnabled(object,v.collisions) 
      end 
    end 
  end 
  

Also tried this technique, not a huge help though:

local objnum = #objs 
  --for i,v in ipairs(objs) do -- This one is slower than a simple "for" from 1 to the objects amount 
  for i=1,objnum do 
    local v = objs[i] 
    local object = createObject(v.model,v.posX,v.posY,v.posZ,v.rotX,v.rotY,v.rotZ) 
    if object then 
      table.insert(objects,object) 
      if v.collisions == false then 
    setElementCollisionsEnabled(object,v.collisions) 
      end 
      if v.alpha and not (v.alpha == 255) then 
    setElementAlpha(object,v.alpha) 
      end 
      if not (v.alpha == 0) then 
    if v.scale and (v.scale > 1 or v.scale < 1) then 
      setObjectScale(object,v.scale) 
    end 
    if not (v.scale == 0) then 
      if v.dimension and tonumber(v.dimension) and tonumber(v.dimension) > 0 then 
        setElementDimension(object,v.dimension) 
      end 
      if not tonumber(v.dimension) or tonumber(v.dimension) == 0 then 
        if v.interior and tonumber(v.interior) and tonumber(v.interior) > 0 then 
          setElementInterior(object,v.interior) 
        end 
        if not tonumber(v.interior) or tonumber(v.interior) == 0 then 
          if v.doublesided == true then 
        setElementDoubleSided(object,v.doublesided) 
          end 
        end 
      end 
    end 
      end 
    end 
  end 
  

Of course, those checks were done to avoid some unneccessary things like setting alpha to 0 and scale to 0 at the same time (totally unneeded here cause they both do the same in the result). Basically, the only thing I want to get rid of is that lag varying from 1 to 10-15 seconds. If that's possible, please, give me a note. There could be about 8000-9000 objects to create when the lag appears.

Thanks in advance.

Link to comment

Some additional information:

I added a tick counter before the objects building, made client trigger server after it finishes building all the objects, made server send back to client (to validate that MTA is actually responding and can receive data) and output the timing between first tick counter and last one. It shows about 0.1-0.2 seconds, however, MTA gets stuck at that point, but at the same time manages to validate all the information. What could cause the issue and how to solve it?

Link to comment

Are you using triggerClientEvent to send the table with the map data? if so, that is most likely the reason and you dont have to put a "sleep" timer in the creation loop if you instead use triggerLatentClientEvent (dont forget to add (can be lower version, but whatever) in the meta).

TriggerClientEvent freezes the main thread while triggerLatentClient works on a different thread.

Also another recommendation, instead of saving values in table as

table.insert(objects, 
{ 
    ["posX"] = posX, 
    ["posY"] = posY, 
    ["posZ"] = posZ 
} 
-- etc 

you should instead do

table.insert(objects, 
{ 
    posX, 
    posY, 
    posZ 
} 
-- etc 

and then client sided

createObject(v[1], v[2], v[3]) 
-- etc 

Then the map size you are sending will be much smaller (much smaller than loading a map with startResource (http download). If done right, around 24% of original map size).

Lua uses more memory in tables if you dont use numeric index values, and if the index you use are not in order, like

table.insert(objects, 
{ 
    posX, 
    posY, 
    posZ 
} 
objects[#objects][10] = id 
-- etc 

instead of

table.insert(objects, 
{ 
    posX, 
    posY, 
    posZ 
} 
objects[#objects][4] = id 
-- etc 

Link to comment
  • Moderators

what if you load them more slowly?

  
local objnum = #objs 
local amountOfLoops = math.ceil(objnum/100) 
local index = 1 
setTimer(function () 
    for i=1,100 do 
        local v = objs[index] 
        if v then 
            -- do your thing.... 
             
            --------------------- 
            index = index+1 
        else 
            break 
        end 
    end 
end,50,amountOfLoops) 

Edited by Guest
Link to comment
IIYAMA, tried this too, goes really slow, even more. About 40 secs to build all the stuff if not 1-2 minutes. I solved the problem by moving the building to the server side with setElementVisibleTo.

From wiki for setElementVisibileTo:

This function can change an element's visibility. This does not work with all entities - vehicles, players and objects are exempt. This is because these objects are required for accurate sync (they're physical objects). This function is particularly useful for changing the visibility of markers, radar blips and radar areas.

If it takes that long to create the objects, then you are doing something wrong. It works with no problem in our server without any delaying or anything like that.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...