Jump to content

Element data, ipairs, getElementsByType, colshapes and lags


AMARANT

Recommended Posts

Hi there. I've been making my own server for a long time and the time has come for beta testing. Now I came across a problem called optimization. I have a lot resources with huge amount of stuff which may cause some lags and which eat CPU. These are elements, like vehicles, house and business pickups, many colshapes, etc. I also use element data and some render stuff of course. The things I mentioned in the subject of this topic never leave me in peace. My question is what of them are most CPU-greed and what is an alternative? Where do I need to dig first for optimizing? Because I found that the server starts to lag when its online hits 15+ people. Thank you for advance.

Link to comment

First of all, if you're using mysql. don't overuse the connection. Only use it for login systems, to get and save data. Only at resource start to keep it really nice. ipairs are no big deal, as long as you use 'return' or 'break' once you've got the data you need. Something else for this can be; if you're looking for a specific vehicle, give the vehicle an ID with setElementID and parse the ID to the function and use getElementByID to speed up the progress of getting the vehicle.

getElementsByType, if you're doing it with objects etc, include the resource's name after the type. This'll make sure the function only takes the objects created by that resource and not the map files etc.

Colshapes are fine, so is element data. Just make sure you don't share everything with the client. setElementData sets data on the element and uses a trigger towards the client to share this data. Quite hard if you're doing it with fuel systems or health status things every 50ms.

Link to comment

Try to use renderTargets for large drawings which doesnt change (like HUD background).

Try to use setElementData fewer.

If you want to sync something for only one player (or some) (like your own statistics, which are not in playerlist), just use triggerClientEvent.

Save your informations in a table instead of elementdata.

Only use setElementData when you wanna sync an information with every player and every resource.

triggerClientEvent is muuch better than setElementData (+ safer, can't get changed by client).

Replace every ipairs with i=1, ...

Try to localize everything possible.

Even the functions, localize them if you don't use them from other datas.

Try to use the db functions as few as possible.

Save the informations in an array instead of letting the player use db functions whole time.

If you use onClientGUIClick, dont use root, use the GUI.

If you use onMarkerHit, use the marker, not root.

If you have to use onClientClick for something special, add the event only when its needed and remove it when not needed.

etc.

When you have to use the same funcion multiple times in the same function with the same arguments, just save it to a variable and use that instead.

Try to create timers as few as possible.

Many times you can just use getTickCount instead, thats better.

You got your own nametag?

Try to get the players for nametag with streamed players (onClientElementStreamIn and out).

Its much better than using getElementsByType.

You got your own playerlist in dx?

Put the players in a table and use the table, much better than getElementsByType.

Use break in a loop.

Don't loop long tables too many times.

Try to use onClientRender as performant as possible.

Its triggered in every framerate!

Link to comment

First, I'd like to thank you guys for your very useful tips and advices!

Now I want to ask some additional questions. Let's begin.

First of all, if you're using mysql. don't overuse the connection. Only use it for login systems, to get and save data. Only at resource start to keep it really nice.

I'm an owner of Roleplay server, so I use MySQL for saving data. You know that there is a lot of information about players, vehicles and so on. I've been using "UPDATE" statements very often before I read what you wrote. "SELECT" queries I use only on login and on a resource start events. Then I set the returned data to the tables. I also have one db-connection and shared it with other resources. So, my questions are:

1. How often do I need to use UPDATE statements, e.g. for backup saving player data while he's online every 15 mins (I used this every 1 min!)?

2. Do I need to use callback function in my SELECT query to disable freezeing the whole server or use timeout parameter -1 in dbPoll anyway?

ipairs are no big deal, as long as you use 'return' or 'break' once you've got the data you need. Something else for this can be.

Yes, I use return fot that.

if you're looking for a specific vehicle, give the vehicle an ID with setElementID and parse the ID to the function and use getElementByID to speed up the progress of getting the vehicle.

Never used this useful function before, thank you again! Will try!

getElementsByType, if you're doing it with objects etc, include the resource's name after the type. This'll make sure the function only takes the objects created by that resource and not the map files etc./

Did that too, but it's hard to do with players, especially on render.

Colshapes are fine, so is element data. Just make sure you don't share everything with the client. setElementData sets data on the element and uses a trigger towards the client to share this data. Quite hard if you're doing it with fuel systems or health status things every 50ms.

I use many colshapes with key binds. E.g., if a player press some button being within the colshape something happens. What is the best way to do that taking into account that there might be a lot of places where you need to activate something with button?

As to fuel systems I even need to synchronize fuel state of a vehicle not only with a driver, so I have to use element data for that. Any other solution?

Thanks in advance for replies!

Link to comment

1. How often do I need to use UPDATE statements, e.g. for backup saving player data while he's online every 15 mins (I used this every 1 min!)?

2. Do I need to use callback function in my SELECT query to disable freezeing the whole server or use timeout parameter -1 in dbPoll anyway?

You only have to save the player his settings when he disconnects, make sure to see if he was actually logged in. If you're using paydays, save all the characters each hour. I would not recommend this though, it'll fire quite some queries so don't use a timeout for this. If you want to avoid the server from freezing, yes. Use callbacks, create a nice function that executes the query and takes a parameter as a callback function back to the actual resource, will keep things clear.

I use many colshapes with key binds. E.g., if a player press some button being within the colshape something happens. What is the best way to do that taking into account that there might be a lot of places where you need to activate something with button?

As to fuel systems I even need to synchronize fuel state of a vehicle not only with a driver, so I have to use element data for that. Any other solution?

Well, take a look at the setElementID again. If you save the ID on the player with setElementData when the event onClientColshapeHit has been triggered, you can always easily get the actual colshape back with;

local colshape = getElementByID ( getElementData ( thePlayer, "tmpColShapeId" ) ) 

this way you don't have to loop over all the colshapes and you'll be able to retrieve them right away.

Link to comment
Thank you, tosfera. But what about fuel system? Which way is more efficient if you need to sync the fuel state with server? What do you suggest?

As a fuel system.. I would not sync the fuel to every single client. Think about it.. 300 people, 1500 cars. All driving around like massive drag racers. Bigger distances, more calculations, every second, that goes to around 450K of triggers towards all the clients in total ( each client gets 1500 new triggers ). that'll sure as hell bring some trouble.

I would keep them server sided, once a player enters a vehicle, request the fuel from the server's side, set it client sided just for the driver and keep updating it on the server's side but also the client's side. Ping a verification every minute to see if they both match. Server is always right on this one.

Do note that you can't have 1500 cars driving with 300 players, that would be 5 cars a person. But don't forget that not everyone turns off their engine and it still uses the fuel.

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...