Tables and Efficiency

So I have a few questions about tables, and the efficiency of timers with net messages in a gamemode.

edit: The below question about tables was answered and solved. If you want me to explain how incase it wasn’t already explained well enough below pm me. The only question I have left is what is the most efficient way of handling or using net messages and sending them to players.

Is a timer a good way so it doesn’t check every second to update the player on an integer like the below or should I just keep everything the way it is?

The first question is about tables; I have a table like below:


mytable = {}
mytable.firstmodel = "modelstring"

Where modelstring is the string of a player model or “models/player/combine_soldier.mdl”

Now what I’m asking about is am I able to set player’s models by doing something like below.


function GM:Initialze

       ply:SetModel(mytable.firstmodel)

end

If not could you please explain why this does not work, and how I can fix it and why it is the way it should be so
I can have a better understanding.

Next I was told that I should be using a timer to update the player on how much energy they have. The energy system basically was a net message
that sends the player a number and add/subtracts integers from that integer.

Is this correct? Should I be setting up timers to update the integer for the client.

Below is the full code, including clientside, the energy system. Sorry if these questions were not clear enough I couldn’t really figure out a way
to explain this better.



--server side
/*
Energy system starts here:
*/
function meta:GetMana(num)
	return self.Mana or 0
end

function meta:SetMana(num)
	net.Start("PlayerSetmana")
		net.WriteInt(num, 32)
	net.Send(self)
	self.Mana = num
end

function meta:AddMana(num)
	self:SetMana(self:GetMana()+num)
end

function meta:TakeMana(num)
	if (self.Mana) <= 0 then return end
	self:SetMana(self:GetMana()-num)
end
/*
Energy system ends here.
*/

--clientside

net.Receive("PlayerSetmana", function(len)
	mana = net.ReadInt(32)
	LocalPlayer().Mana = mana
end)

firstly,
[lua]
local mytable = {
model_name = “path/to/model”,
}
local function custom_PlyInitialSpawn( ply )
ply:SetModel( mytable.model_name )
end
hook.Add( “PlayerInitialSpawn”, “custom_PlyInitialSpawn”, custom_PlyInitialSpawn )
[/lua]

secondly;
Adding and subtracting may result in desync issues depending on how you’re using it.
Best to send the full number then calculate the difference on the client.

and finally;
yes that looks about right.

however i believe it’s more efficient to use SetNWInt() on variables expected to change frequently.

Ignore Pyro-Fire, he’s not understanding whatsoever and just made the code extremely ugly.

What I suggest is trying it yourself, but yes, that will work. As for the second part…

Refer to above, try it first then post errors.

I’ve actually tried setting the player’s model that way several times now. At first I got some errors referring to adding { or } to close the table.

After fixing that I used the below code:


function meta:Initialize()
	if (self:Team() == 1) then
		self:SetModel(soldierModels.apex)
	elseif (self:Team() == 2) then
		self:SetModel("models/player/Group03/Female_01.mdl")
	end
end

soldierModels = {}
soldierModels.apex = "models/player/combine_soldier.mdl"

The code above supplies no errors in the console on the server whatsoever. But when the player spawns on team 1 then they

are given the standard player.mdl debug model.

A little more information that might be useful; I’m currently using meta = FindMetatable(‘Player’) hence why it’s meta:Initialize and
maybe this could be causing problems when setting the model?

Also, which reguards to what Pyro had said about using Get/SetNWI() I’ve heard that is not a good(or efficient) way
to do what I’m trying to do, but again I don’t have any kind of data to compare to the two ways.

It’s a lazy way of doing it.

Have you made sure all your files are included correctly? Is this your own custom gamemode? If not, then use hook.Add instead of overwriting gamemode functions.

Otherwise use this.

Yes all of my files are included correctly. Normally when I was using my meta:Initialze I just had
the self:SetModel to a string or path of the model I wanted. Once I tried using a table to pull
that string from for some reason it’s as if I didn’t even set my playermode, hence the debug model.

I also used that function, GM:PlayerSetModel and even that is not working.

[lua]function meta:Initialize()
if (self:Team() == 1) then
self:SetModel(soldierModels.apex)
elseif (self:Team() == 2) then
self:SetModel(“models/player/Group03/Female_01.mdl”)
end
end

soldierModels = {}
soldierModels.apex = “models/player/combine_soldier.mdl”[/lua]

First off, set the table above the function.

Second, why use that? Why not PlayerInitialSpawn?

This may not be related to your problem with using GM:PlayerSetModel, but you should be aware of the following note listed in the hook’s page on the wiki:

"NOTE: This function may not work in your custom gamemode if you have overridden your GM:PlayerSpawn and you do not use self.BaseClass.PlayerSpawn or hook.Call."

GM:PlayerSpawn is defined like so in the base gamemode:



function GM:PlayerSpawn( pl )

    --
    -- If the player doesn't have a team in a TeamBased game
    -- then spawn him as a spectator
    --
    if ( GAMEMODE.TeamBased && ( pl:Team() == TEAM_SPECTATOR || pl:Team() == TEAM_UNASSIGNED ) ) then

        GAMEMODE:PlayerSpawnAsSpectator( pl )
        return
    
    end

    -- Stop observer mode
    pl:UnSpectate()

    pl:SetupHands()

    player_manager.OnPlayerSpawn( pl )
    player_manager.RunClass( pl, "Spawn" )

    -- Call item loadout function
    hook.Call( "PlayerLoadout", GAMEMODE, pl )
    
    -- Set player model
    hook.Call( "PlayerSetModel", GAMEMODE, pl )
    
end

Meaning if you have overwritten it but aren’t manually calling those hooks yourself, the player’s model won’t be set. Take this all with a grain of salt since we don’t know much of what you have done with your gamemode.

I’ll go a little more in-depth with what has been done so far.

First:


function GM:PlayerInitialSpawn(ply)
    ply:Initialze()
end

--in other server file

local meta = FindMetaTable('Player')

function meta:Initialze()
       self:SetModel('model/path')
--in here I can do things for players like set hp, speed and model
--and with this function I can also put it elsewhere and not JUST in
--GM:PlayerInitialSpawn
end

Below the meta:Initialize() I have my other meta functions like


function meta:SetMana()
--code
end

I could use my Initialize if I had a spectator team that the player spawned on first, which I was
thinking of doing once I had done a few other things in the gamemode.

I changed things back so now I have the below in meta:Initialize()



function meta:Initialize()
      self:SetModel("models/player/combine_soldier.mdl")
end

And oddly enough this works just perfectly and sets my model like it should. Maybe I was doing something weird by using


if (self:Team() == 1) then
     --do code
end

edit: I may have figured it out, I have to go out, will be back with the solution if I find it.

Funny how you talk about desync issues then recommend SetNWInt. [G/S]etNW* should be avoided as they can have desync issues.

I’ve seen numerous times people mentioning that using the Get/SetNWInt is a bad idea since it can

lag the server if used too many times. I didn’t realize they also can cause desync issues…

They don’t necessarily cause desync, but they are affected by it when it happens. DTVars are definitely the best alternative if you can use them. They are not affected by desync, and also have less overhead.

Wait, aren’t DTVars depreciated?

**"This function is deprecated. You should avoid using it as it may be removed in a future version.

Use Entity:NetworkVar instead. It offers the same functionality with more features."**

The function DTVar* is, it has been simplified into the NetworkVar function. It’s still the DTVar system though.