Jump to content

[QUESTION] One table for both server and client side


Hale

Recommended Posts

Hello, I've been working on a bigger project for a while, and up until now, I haven't realized I have a major issue regarding my data tables (Lua yes, as I'm trying to achieve best overall performance for the server). To briefly explain, instead of having dozen SQL queries for every data change a player makes, I simply store the data into a table and save it periodically or on resource stop. This was all server side, the main tables and exported functions (updateAccountData, getAccountData, pretty much the same as elementData but better for performance). As I was scripting I came to a realization that all that data in the table was reachable in server side, not client side, which is big of a problem, however, I thought if I move the table and exported functions to a shared .lua (declared in meta.xml as "shared" instead of "server" or "client") it would work just fine, but turns out the table is filled server side if the exported function is called from a server side .lua, and same for client, meaning they don't mix but rather have their own sides.

My question is, is there a way to get data from a server side table to client side script/variable? What can or should I do if not, considering I have hundreds of calls to those exported functions from many different files.

If you haven't understood what I did regarding the table and exported functions, here are some explanations:
 

accounts = {} -- table containing player data

function insertAccountData(element, data)
	accounts[element] = data
end

function getAccountData(element, dataName)
	if dataName then
		return accounts[element][dataName] or false
	end
	return accounts[element]
end

function updateAccountData(element, dataName, newData)
	if type(dataName) == "table" then
		for k,v in ipairs(dataName) do
			accounts[element][v] = newData[k] or false
		end
	else
		accounts[element][dataName] = newData or false
	end
end

function removeAccountData(element)
	accounts[element] = nil
end

 

In expectations of any possible help, thank you!

Link to comment

If you're looking for a work-around or a trick, that let's you communicate between client/server without triggers.. unfortunately you just won't find such thing. You only have couple of options in MTA

  1. When the client logs in, send them all the data that will be used frequently, eg.: positions of interiors and whenever you create something new on the run, trigger to client the new data
  2. Use triggerServer / triggerClient event whenever you need something from the server
  3. Use setElementData and store all the data that will be used frequently on specific elements. eg.: Vehicles: id, owner, fuel; Players: id, character name, admin level (these are just examples) and whenever you need something that isn't often used eg.: getting some info about a player that will not be rendered in HUD etc
  4. Use something like you did there, but with an export to client as well, so you can access those data on the client side

I understand you are trying to build your server as efficient performance wise as possible, I have been there... but you are limited and at the end of the day, it's a server, you are supposed to run it on a decent machine when expecting lots of players and it's supposed to be able to get stuff done. In my opinion, I would rather fill up the server's RAM, even if it used 3-4-5GB, rather than overloading the client, most of the players still have outdated PC's..

I think you should try out the performance tester resource and try to overload the server with a bunch of calls, just to see yourself how much it can handle.

  • Like 1
Link to comment
  • Moderators

If you could test if elementdata does get send to the clients 100% successfully, even if it changes rapidly, then you might consider sending small updates using elementdata.

 

 

So for example the player joins the server.

Global: Every time you update something of your table, you update a counter which indicates which id this data contains.

  1. You wait for the resource to be load clientside.
  2. Then you send a triggerEvent from clientside to serverside. (saying: "I want cookies")
  3. The server sends with triggerEvent the whole table. (Included a ref id from the last update)
  4. From that moment you will be fetching elementdata from serverside and update the table. (the elementdata contains only the parts that are updated)
  5. This id you give to your elementdata can indicates if you are missing information. For example packets: 80, 81, 83 <-- Ey, I am missing update 82.

 

I would say this is a very experimental thing to do, since I do not know what happens when elementdata stacks up. But I can tell you that using a trigger for an large amount of updates isn't a solution.(unless you update the table only ones in a while)

 

  • Like 1
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...