Help with client getting variable from server

Hello all,
I’ve been trying to learn all the ins and outs of making a game mode for gmod 13. I have read all the lua tutorial from gmod wiki and I’ve scoured that website and haven’t found an answer. What I am trying to do is make a variable server side that is for the whole server and not for individual player and then be able to fetch it client side whenever I want. I do know about net libraries and user messages but it seems extremely tedious to use considering I would have to send info to the server side that would initiate a hook which would send the information I wanted back to the client side. I’m just wondering if there’s a much easier way that I’m overlooking or a way I don’t know about. Thanks in advanced.

Just make the data shared.

Although I appreciate the reply, you should know how unhelpful it is when you just tell me to do something I’ve never heard of. A example or a link to a tutorial would be a lot more helpful.

In GLua there is a side that is serverside and a side that is clientside. When I say shared I mean you make the variable on both sides, which could be in a shared file that’s included on the server and on the client.

A file in lua/autorun/
Ex:
[lua]
local SHARED_VAR = 1
if SERVER then
AddCSLuaFile()
print(SHARED_VAR)
else
print(SHARED_VAR)
end
[/lua]

Oh, I misunderstood, now I understand, thank you for clarifying. You saved me another couple hours spent trying to figure out a more sloppy way of solving this problem. Many thanks.

Unfortunately it’s not that easy and the above solution is probably not what you’re looking for. What you are basically doing is declare a variable named SHARED_VAR on the server, and another variable with the same name on the client. Since the server and the client are two separate machines, you have two variables which are completely independent from each other.

Basically that means that if you change one, the other is going to stay the same. And I don’t think that’s what you want.

There are several ways to send a variable from the server to the client. The quick but dirty way is to use global networked variables, accessible through functions such as SetGlobalFloat and GetGlobalFloat.

For instance, doing this on the server:

[lua]SetGlobalFloat(“myGlobalVar”, 1.23)[/lua]

would assign the value 1.23 to a global networked variable named “myGlobalVar”.
To read it on the client, you would do this:

[lua]local var= GetGlobalFloat(“myGlobalVar”)[/lua]

Here, GetGlobalFloat would return the current value of myGlobalVar.
There are variations of the two above functions for every type of variable. SetGlobalInt is for integer variables, SetGlobalFloat is for floating point variables, SetGlobalString is for strings, and so on…

Now keep in mind that although the above solution is relatively simple, it is quite unreliable. Meaning that it might occasionally not work, especially if you are updating a variable very frequently or if you are under heavy lag.
It is acceptable if you want to perform quick tests, but for a polished gamemode, you should use the clean way.

The clean way is a bit more complicated. Basically, it involves creating an invisible entity which contains the data that needs to be sent to clients.

I will assume that you know how scripted entities work. Something you might not know is the fact that scripted entities have a special data table which holds serverside data that should be known to the client. This data is very reliable, and it will almost never fail to update on the client, actually that’s how the position and angles of entities are stored.
This is how you handle data tables: http://wiki.garrysmod.com/page/Networking_Entities

So if you want to network a global variable named MyGlobalVar, your entity’s SetupDataTables function would look like this:

[lua]function ENT:SetupDataTables()
self:NetworkVar(“MyGlobalVar”, 0, “Float”)
end[/lua]

It should be declared both clientside and serverside (so in your entity’s shared.lua file).

You will also need to make your entity “visible” to clients at all times. Entities are normally optimized so they don’t transmit their data to clients who cannot see them. You don’t want that here.
You can disable this optimization by declaring this in your entity’s init.lua.

[lua]function ENT:UpdateTransmitState()
return TRANSMIT_ALWAYS
end[/lua]

And of course, since you don’t want your entity to be visible or to be interacted with, its Initialize function may look like this:

[lua]function ENT:Initialize()
self:SetMoveType(MOVETYPE_NONE)
self:SetNotSolid(true)
self:SetNoDraw(true)
self:DrawShadow(false)
end[/lua]

Now to actually be able to access this variable, you will need to create it serverside. Assuming that you are working on a gamemode from scratch, and that you named your entity “my_gamemode_logic” (since it’s an entity will most likely hold data related to gamemode logic), this is what the gamemode’s (serverside) Initialize function would look like:

[lua]function GM:Initialize()
local logic = ents.Create(“my_gamemode_logic”)
logic:Spawn()
end[/lua]

Finally, to access your variable, you can declare the following functions in your gamemode’s shared.lua.

[lua]local MyGamemodeLogic

function GetMyGlobalVar()
if not IsValid(MyGamemodeLogic) then
MyGamemodeLogic = ents.FindByClass(“my_gamemode_logic”)[1]
end

if IsValid(MyGamemodeLogic) then
	return MyGamemodeLogic:GetMyGlobalVar()
else
	return 0
end

end

function SetMyGlobalVar(x)
if not IsValid(MyGamemodeLogic) then
MyGamemodeLogic = ents.FindByClass(“my_gamemode_logic”)[1]
end

if IsValid(MyGamemodeLogic) then
	MyGamemodeLogic:SetMyGlobalVar(x)
end

end[/lua]

First those functions attempt to find your entity if it hasn’t been found yet. That’s because the client doesn’t know where this entity is, or if it even exists yet. ents.FindByClass(“my_gamemode_logic”) returns a table containing all instances of my_gamemode_logic. The [1] after that gets the first element of that table. Since there’s only one my_gamemode_logic at a time, that’s all you need.

The GetMyGlobalVar/SetMyGlobalVar from that entity come from the entity’s SetupDataTables from earlier:

[lua]function ENT:SetupDataTables()
self:NetworkVar(“MyGlobalVar”, 0, “Float”)
end[/lua]

NetworkVar automatically creates a Set/Get function for any variable you declare with it.

And that’s it. Keep in mind that data tables can only hold a limited number of variables (4 slots per type), so you might need several different entities if you need to store more networked data.
It might seem tedious but it’s generally worth it in the long run and it’s really not as hard as it seems.