Userdata, when stored in a variable, still updates in real time...?!?

Hey guys.

When I have one of my entities spawn, I’m getting the owner of the entity (I have falco’s prop protect) by using:

[lua]mrobot.OGOwner = mrobot:CPPIGetOwner()[/lua]

So, what I’m doing here is, I’m creating a variable called “OGOwner” that is stored in each entity I create, and that variabl****e stores the ORIGINAL owner that spawned the entity.

Now over to my init.lua file of my entity. I coded so that when the entity takes damage, it prints what it’s OGOwner variable is.

I shoot the entity. This appears in console:

[lua][1][Dreken][/lua]

Now here’s the perplexing part.

When I LEAVE the server (this is a dedicated server), and come back, and then shoot the entity, this appears:

[lua][NULL][/lua]

How the hell is this possible? The variable self.OGOwner is a variable! Variables don’t update!

This leads me to one conclusion, that userdata updates in real time, even if you make a variable store it.

So here’s the question: **How the hell do I make a variable that stores the userdata statically, that does not change when I quit and then come back?
**
I’m doing this because I’m trying to get it so that a person can only spawn 1 of this entity, and in my entities ENT:Remove() function (when the entity gets removed by FPP or otherwise) the server subtracts one from the players Pdata.However, when the player leaves and then comes back, the server apparently thinks OGOwner is null, even though variables don’t change, but I guess userdata does, even in a variable.

That’s because when you leave the server, your physical player entity gets removed, thus the userdata becoming NULL. This is perfectly normal. If you want to store player data over reconnects, you should store it using their steamid as an index.

OGOwner is a reference to a player entity. When the player leaves the server, that entity becomes NULL.

I would store their :SteamID() or :UniqueID(), then when removing it just loop through the players that are online and check if their steamid matches.

There are two types of data:

Reference and primitive.

Primitives are things like strings and numbers. When you do x = “hi” you are assigning a copy of “hi” to x.

Reference are things like tables and userdata. You aren’t actually assigned a copy of the object ( and in some cases, like when dealing with entities, it isn’t possible ), but rather a pointer to that object.

The variable never changes unless you explicitly interact with it - but the object it is pointing to can and does often change.

In this case, the player disconnects and his player object is destroyed. All variables that reference said player are now pointing to NULL. This is expected behavior.

Solution:

Index by a field that doesn’t rely on the player object remaining valid. Be it uniqueid, steamid, or what have you, they survive the player disconnecting.

You can even have a two-step solution


function ENT:Initialize( )
  hook.Add( "PlayerInitialSpawn", self, self.PlayerInitialSpawn)
end

function ENT:PlayerInitialSpawn( pl )
  if not IsValid( self.OGOwner ) and self.StoredSteamID == pl:SteamID( ) then
    self.OGOwner = pl
  end
end

function ENT:AssignOGOwner( pl )
  self.OGOwner = pl
  self.StoredSteamID = pl:SteamID( )
end

This way, if the player disconnects and comes back, the entity restores its ownership to that player.

Okay, Could you give me an example of how to store how many entities the person has using the steam ID? I follow this code, but I don’t really know how to implement it.

I’m pretty much looking for how to tell the server whose robot count should go down, if they aren’t there. So I’ve indexed something (the steam ID) to do this.

I just can’t figure out how to write it.