• String datatable?
    19 replies, posted
[code] ] lua_run Entity( 43 ):DTVar( "Str", 0, "blah" ) > Entity( 43 ):DTVar( "Str", 0, "blah" )... Couldn't addvar blah - type Str is invalid! ] lua_run Entity( 43 ):DTVar( "String", 0, "blah" ) > Entity( 43 ):DTVar( "String", 0, "blah" )... Couldn't addvar blah - type String is invalid! ] lua_run Entity( 43 ):DTVar( "Txt", 0, "blah" ) > Entity( 43 ):DTVar( "Txt", 0, "blah" )... Couldn't addvar blah - type Txt is invalid! ] lua_run Entity( 43 ):DTVar( "Text", 0, "blah" ) > Entity( 43 ):DTVar( "Text", 0, "blah" )... Couldn't addvar blah - type Text is invalid! ] lua_run Entity( 43 ):DTVar( "S", 0, "blah" ) > Entity( 43 ):DTVar( "S", 0, "blah" )... Couldn't addvar blah - type S is invalid! ] lua_run Entity( 43 ):DTVar( "St", 0, "blah" ) > Entity( 43 ):DTVar( "St", 0, "blah" )... Couldn't addvar blah - type St is invalid! ] lua_run Entity( 43 ):DTVar( "Int", 1, "blah" ) > Entity( 43 ):DTVar( "Int", 1, "blah" )... ] lua_run Entity( 43 ):DTVar( "Stri", 0, "blah" ) > Entity( 43 ):DTVar( "Stri", 0, "blah" )... Couldn't addvar blah - type Stri is invalid! [/code] Might be blindingly obvious, but what datatype represents a string for DTVars?
After doing some searching: apparently there isn't one. Just use a networked string instead.
Which is annoying since the one variable that it is essential the client gets in order for the entity to function happens to be a string. Ah well, I'll manage somehow. Thanks.
I hoped there would be a sting DT, i hope this could be added.
From garry's blog: [quote]I’m recommending that if you can fit all your SENT/SWEP’s data in this variables, then use them. They’re the best option for networked variables. [b]String data, or other variables should use the old method.[/b][/quote] [url]http://www.garry.tv/?p=1198[/url]
String data is not feasible since it would have a too variable size.
The strings represent the class of the entity, the client will lookup the string against a table of class objects and read appropriate data out. But yes, I'll set it so each class has a numerical ID too.
[QUOTE=iRzilla;19278834]Can you not just encode the string as a integer?[/QUOTE] Sure but even then it would be easier to use usermessages.
[QUOTE=iRzilla;19278834]Can you not just encode the string as a integer?[/QUOTE] No, I think you need to predict the maximum size the variable could be. Allowing for up to 256 characters for all these variables would be a waste of memory. Number and Vectors have a much smaller size so less memory is potentially wasted.
[QUOTE=conman420;19286374]No, I think you need to predict the maximum size the variable could be. Allowing for up to 256 characters for all these variables would be a waste of memory. Number and Vectors have a much smaller size so less memory is potentially wasted.[/QUOTE] Valve's data table variables only allow for statically sized char arrays, hence why Garry didn't implement them. Numbers, Vectors etc on the other hand have a predefined size.
ent resources integrate to have no tin thing allied industry institute for research, make studying further thorough. as a cooperator, weighed to celebrate post and tele university equally to have special advantage in the related research realm online games "the thing is allied net".That vice-president online games school's pronline gamesessor Li Yin Guo online games the school says:"We all lead in the domestic in the aspects online games spreading feeling mach Yesterday, the this report consociation police developed a transportation vulgar practice survey and got citizen to actively respond to.Up to when the reporter cuts a draft have already had 100 citizen to pass logging to originally report a website and wire this report hot-line 63820315 and send out an E-mail to hand over tube section, announce own opinion and viewpoint. care to see platform up, pedestrian and driver to the standpoint give tit for tat online games transportation vulgar practice, the critique opinion nowise shows conside[url=http://freeplayonlinegames.net/]online games[/url][url=http://freeplayonlinegames.net/]free online games[/url][url=http://freeplayonlinegames.net/]games[/url]
If the strings are constants (e.g. like a list of possible models) then you could define the same list separately on the server and client and then network the index instead. Not only is it leagues more efficient but it actually works with datatables (in the case that your strings are constants of course).
an efficient way to make your own dtvars/nwvars: init.lua: [lua]function ENT:Initialize() self.rp = RecipientFilter() self.yourstring = "" -- or whatever default value you want end --concmd handler for "whatever": self.rp:AddPlayer(ply) umsg.Start("whatever", self.rp) umsg.Short(self:EntIndex()) umsg.String(self.yourstring) -- might need multiple umsgs for long strings umsg.End() [/lua] cl_init.lua: [lua]function ENT:Initialize() RunConsoleCommand("whatever", self:EntIndex()) self.yourstring = "" -- or whatever default value you want, match up with server end usermessage.Hook("whatever", function(um) local self = Entity(um:ReadShort()) if self:IsValid() and self.Receive then self:Receive(um) end end) function ENT:Receive(um) self.yourstring = um:ReadString() end [/lua] the key to its efficiency and what makes this work so well is the recipientfilter and the fact that the client side requests data only when ready to receive it. if you have multiple items to transfer, you can prepend a umsg.Char with an id to the actual data and evaluate that on the client side.
I have had few occasions where the Entity was not initialized clientside when the usermessage arrived. This was, of course, fixable with a simple timer.Simple but it was hacky. And why are you adding players to self.rp, that would send it to all added players every time, and to non-existant players too( if they have left the server ) ?
You might have to add an EntityRemoved hook with an IsPlayer to get rid of disconnected and crashed players... sending a console command to the server when the entity is initialized clientside avoids timer hackery on the client.
You don't even need an RP for the usermessage, you can just pass the player object straight in.
you didn't read properly. the rp contains all players that have registered for receiving that user message from that entity instance. that means all players for whom the entity was already initialized on the client side. in the meantime I have turned this into a generic system and have used it in two wiremod components (control panel and text screen) it's a nice, efficient alternative to networked vars: it only takes one string table entry for as many entities and fields as you want and function calls are only involved when something changes. [editline]07:10AM[/editline] [lua]--[[ wire_umsg: self:umsg() system Shared requirements: WireLib.umsgRegister(self) in ENT:Initialize() Server requirements: ENT:Retransmit(ply) Client requirements: ENT:Receive(um) To send: self:umsg() -- you can pass a Player or a RecipientFilter here to only send to some clients. umsg.Whatever(whatever) umsg.End() ]] if SERVER then local registered_ents = {} hook.Add("EntityRemoved", "wire_umsg", function(ent) if not ent:IsValid() then return end if ent:IsPlayer() then for e,_ in pairs(registered_ents) do if e.wire_umsg_rp then e.wire_umsg_rp:RemovePlayer(ent) end end else registered_ents[ent] = nil end end) local function wire_umsg(self, receiver) umsg.Start("wire_umsg", receiver or self.rp) umsg.Short(self:EntIndex()) end function WireLib.umsgRegister(self) registered_ents[self] = true self.umsg = wire_umsg self.wire_umsg_rp = RecipientFilter() end concommand.Add("wire_umsg", function(ply, cmd, args) local self = Entity(tonumber(args[1])) self.wire_umsg_rp:AddPlayer(ply) if self:IsValid() then self:Retransmit(ply) end end) elseif CLIENT then function WireLib.umsgRegister(self) RunConsoleCommand("wire_umsg", self:EntIndex()) end usermessage.Hook("wire_umsg", function(um) local self = Entity(um:ReadShort()) if self:IsValid() and self.Receive then self:Receive(um) end end) end[/lua] it comes with wiremod, so if your addon relies on that anyway, you can just use it from there :) if you don't want to depend on wiremod, please change the umsg/concmd names to something else to avoid conflicts.
[QUOTE=TomyLobo;19500178]you didn't read properly. the rp contains all players that have registered for receiving that user message from that entity instance. that means all players for whom the entity was already initialized on the client side.[/quote] Then should not the code that sends the usermessage be put inside the SetMyString method (or whatever updates the string), rather than the concommand handler? [editline]08:45PM[/editline] But yes, I get the general idea of what you're saying. It would probably be better for the server to calculate whether a client knows about an entity's existence or not without the client sending a concommand though, maybe some stuff with PVS. You probably can't do that in GMod Lua though. Garry, we need more networking hooks.
[QUOTE=thomasfn;19510795]Then should not the code that sends the usermessage be put inside the SetMyString method (or whatever updates the string), rather than the concommand handler?[/QUOTE] It's in both, though the "SetMyString" method is not part of the code I posted. [QUOTE=thomasfn;19510795] But yes, I get the general idea of what you're saying. It would probably be better for the server to calculate whether a client knows about an entity's existence or not without the client sending a concommand though, maybe some stuff with PVS. You probably can't do that in GMod Lua though. Garry, we need more networking hooks.[/QUOTE] even if the entity is in the PVS according to the server's data, you still can't make sure the client side already generated a table by the time the umsg arrives. plus it would, again, require constant checking
Sorry, you need to Log In to post a reply to this thread.