• Toolgun stutter in multiplayer
    5 replies, posted
I have a STOOL that links two entities (in this particular case, air tanks) together. It works fine in singleplayer, but for some reason it seems to almost stutter and run some of the code more than it should, causing console errors. The toolgun seems to do its job, at least in the first cycle, as the objects appear to be linked together and are sharing resources. In subsequent cycles it encounters errors and the toolgun no longer functions. The following is the toolgun's source, and following that the errors thrown in the console. Maybe a second set of eyes are all I really need... [lua] TOOL.Category = "Horizon" TOOL.Name = "Link Tool" TOOL.Command = nil TOOL.ConfigName = "" local timesFired = 0 local cycleComplete = false local startPos local endPos function TOOL:LeftClick( tr ) if (!tr.Entity:IsValid(tr.Entity.linkable)) or (tr.Entity:IsPlayer()) then return end startPos = tr.HitPos if (timesFired == 0) then entA = tr.Entity print ("entA = " .. entA:GetClass()) timesFired = 1 if (CLIENT) then return true end end if (tr.Entity != entA) then if cycleComplete == false then entB = tr.Entity print ("entB = " .. entB:GetClass()) if entA.networkID == nil and entB.networkID == nil then print( "neither entities are networked" ) entA.networkID = GAMEMODE.nextNet print(entA.connections) table.insert(entA.connections, entB) entB.networkID = GAMEMODE.nextNet table.insert(entB.connections, entA) newNetwork = {} newNetwork[1] = {} newNetwork[2] = entA newNetwork[3] = entB GAMEMODE.networks[GAMEMODE.nextNet] = newNetwork --Now, let's add any new resources to the network's resource list for _, ent in pairs( newNetwork ) do if ent.deviceType == "storage" then GAMEMODE:addToResourceList( ent ) end end --Next, we need to get a count of all resources on the network GAMEMODE:updateResourceCount(GAMEMODE.nextNet) -- Increment to next available network ID GAMEMODE.nextNet = GAMEMODE.nextNet + 1 cycleComplete = true; end end if entA.networkID != nil and entB.networkID == nil then if cycleComplete == false then print( "one entity (entA) is networked" ) --add each other to connections table table.insert(entA.connections, entB) table.insert(entB.connections, entA) entB.networkID = entA.networkID table.insert(GAMEMODE.networks[entA.networkID], entB) if entB.deviceType == "storage" then GAMEMODE:addToResourceList( entB ) end GAMEMODE:updateResourceCount( entA.networkID ) cycleComplete = true end end if entB.networkID != nil and entA.networkID == nil then if cycleComplete == false then print( "one entity (entB) is networked" ) --add each other to connections table table.insert(entA.connections, entB) table.insert(entB.connections, entA) entA.networkID = entB.networkID table.insert(GAMEMODE.networks[entB.networkID], entA) if entA.deviceType == "storage" then GAMEMODE:addToResourceList( entA ) end GAMEMODE:updateResourceCount( entB.networkID ) cycleComplete = true end end if entA.networkID !=nil and entB.networkID != nil then if entA.networkID == entB.networkID and cycleComplete == false then print("Entities are in the same network!") table.insert(entA.connections, entB) table.insert(entB.connections, entA) cycleComplete = true end if cycleComplete == false then print( "both entities are networked" ) table.insert(entA.connections, entB) table.insert(entB.connections, entA) local oldNetA = GAMEMODE.networks[entA.networkID] local oldNetB = GAMEMODE.networks[entB.networkID] local NetworkA = GAMEMODE.networks[entA.networkID] local NetworkB = GAMEMODE.networks[entB.networkID] local newNetwork = {} newNetwork[1] = {} for _, ent in pairs( NetworkA ) do if ent.linkable == true then ent.networkID = GAMEMODE.nextNet table.insert(newNetwork, ent) end end for _, ent in pairs( NetworkB ) do if ent.linkable == true then ent.networkID = GAMEMODE.nextNet table.insert(newNetwork, ent) end end GAMEMODE.networks[oldNetA] = nil GAMEMODE.networks[oldNetB] = nil GAMEMODE.networks[GAMEMODE.nextNet] = newNetwork for _, ent in pairs( GAMEMODE.networks[GAMEMODE.nextNet]) do if ent.deviceType == "storage" then GAMEMODE:addToResourceList( ent ) end end GAMEMODE:updateResourceCount( GAMEMODE.nextNet ) GAMEMODE.nextNet = GAMEMODE.nextNet + 1 cycleComplete = true end end endPos = tr.HitPos // Get information we're about to use local constraint, rope = constraint.Elastic( entA, entB, 0, 0, startPos, endPos, 0, 0, 0, "cable/cable2", 2, 0 ) timesFired = 0 cycleComplete = false end if (CLIENT) then return true end return true end function TOOL:Reload( tr ) if tr.Entity.linkable == true then if tr.Entity.networkID != nil then GAMEMODE:unlinkDevice(tr.Entity) end if (CLIENT) then return true end end return true end [/lua] Console output: [code] ] ent_create test_tank ] ent_create test_tank entA = test_tank entA = test_tank entB = test_tank neither entities are networked table: 2BDC3FC8 entB = test_tank neither entities are networked nil [@weapons\gmod_tool\stools\link_tool.lua:40] bad argument #1 to 'insert' (table expected, got nil) nilentB = test_tank neither entities are networked [@weapons\gmod_tool\stools\link_tool.lua:40] bad argument #1 to 'insert' (table expected, got nil) entB = test_tank neither entities are networked nil [@weapons\gmod_tool\stools\link_tool.lua:40] bad argument #1 to 'insert' (table expected, got nil) entB = test_tank neither entities are networked nil [@weapons\gmod_tool\stools\link_tool.lua:40] bad argument #1 to 'insert' (table expected, got nil) [/code]
One small suggestion to reduce the clutter, make a link function on the entity itself as it seems quite complicated. This way you don't have to copy-paste it everywhere you need it. As for the error: entA.connections is nil, make it equal to {} if its nil to fix it.
[QUOTE=CmdrMatthew;30774743]One small suggestion to reduce the clutter, make a link function on the entity itself as it seems quite complicated. This way you don't have to copy-paste it everywhere you need it. As for the error: entA.connections is nil, make it equal to {} if its nil to fix it.[/QUOTE] I'm not sure that would fix the problem- on the first run entA.connections isn't nil. It should only run through this sequence once, which it does in singleplayer. As you can see in the console output, it's running part of the sequence four additional times.
Anyone want to take a crack at it? Anyone at all...?
Is entA.connections a table or is entA a table :p It's trying to add it to a table but that table doesn't exist so Theory wise [lua] local entAT = {} local entBT = {} table.insert(entAT, entB.connections) table.insert(entBT, entA.connections) [/lua]
[QUOTE=RetTurtl3;30783673]Is entA.connections a table or is entA a table :p It's trying to add it to a table but that table doesn't exist so Theory wise [lua] local entAT = {} local entBT = {} table.insert(entAT, entB.connections) table.insert(entBT, entA.connections) [/lua][/QUOTE] entA.connections is a table that exists on the entity. When the entity is selected by the toolgun, entA(or entB for that matter) becomes valid and their connections table is accessible to the tool. The problem I'm having is not the 'Bad Argument' error in the console. That's only a symptom. The problem is the code running multiple times when it shouldn't be. The only analogy I can think of is a gun. In singleplayer, it behaves like a semi-automatic. the script executes once, does its job and readies itself to fire again. In multiplayer, the same script tries to go full auto, executing the first time as it should, but then fires again without a valid entity selected, effectively jamming up. That's the point where it throws the console error. I just want to know why this behavior would occur only in multiplayer?
Sorry, you need to Log In to post a reply to this thread.