• How to sync client side timers
    13 replies, posted
I have 2 timers that are hooked to the Initialize function client side. Obviously as you would assume when 1 player connects, and then another player connects 5 or so minutes later, the timers will be out of alignment. What is the best possible way to align these timers and assure that all players on the server have the same exact time remaining on their timers. I would provide code but I'm assuming there's no need for it since this is more of just a general question.
Wait, so why not create and use a serverside timer in the Initialize function instead? I guess there's a obvious reason why you don't want to do this, but some extra info would help about what you're trying to do since I don't see a reason not to
[QUOTE=MPan1;50793939]Wait, so why not create and use a serverside timer in the Initialize function instead? I guess there's a obvious reason why you don't want to do this, but some extra info would help about what you're trying to do since I don't see a reason not to[/QUOTE] That's most definitely an option. I was more just trying to challenge myself and find a way to do this all client side though, if for some reason it came a time where it was needed.
[QUOTE=dannyf127;50793962]That's most definitely an option. I was more just trying to challenge myself and find a way to do this all client side though, if for some reason it came a time where it was needed.[/QUOTE] Just send a net message out from the server every second syncing it. That's how most round timers work.
-snip-
That makes no sense; you're going to have to post some code.
I'm sorry for explaining this in such a shitty way, I'm not the best at doing so if you can't tell. So basically with this code, Schedule.Classes[Schedule.CurrentClassActive].Active = true , this index "Schedule.CurrentClassActive" needs to be aligned with all clients, however it's not if another player joins at a later time. Also I've rewritten this code about 3 times to get the same product so if this doesn't make sense I can write it in another way that it will. At this point it's no longer a matter of unsynced timers, it's just a matter of unsynced values. [editline]29th July 2016[/editline] [CODE]//Shared Schedule.Classes = { [1] = {Name= "Name1", Location = "Location1", Active = true}, // Do not change the Active = false [2] = {Name= "Name2", Location = "Location2", Active = false}, [3] = {Name= "Name3", Location = "Mum's Bum", Active = false}, [4] = {Name= "Name4", Location = "Location4", Active = false}, [5] = {Name= "Name5", Location = "Location5", Active = false}, [6] = {Name= "Name6", Location = "Location6", Active = false}, [7] = {Name= "Name7", Location = "Location7", Active = false}, [8] = {Name= "Name8", Location = "Location8", Active = false}, [9] = {Name = "Name9", Location = "Location9", Active = false}, } Schedule.CurrentClassActive = 1 Schedule.NumberOfClasses = 9 //Server util.AddNetworkString("StartT1") util.AddNetworkString("StartT2") hook.Add("Initialize", "StartClassTimer", function() timer.Create( "StartT1", 600, 0, function() net.Start("StartT1") net.Broadcast() end) timer.Create("StartT2", 620, 0, function() net.Start("StartT2") net.Broadcast() end) end) //Client net.Receive("StartT1", function(len,ply) Schedule.Classes[Schedule.CurrentClassActive].Active = false timer.Stop("StartT1") end) net.Receive("StartT2", function(len,ply) Schedule.CurrentClassActive = Schedule.CurrentClassActive + 1 Schedule.Classes[Schedule.CurrentClassActive].Active = true timer.Start("StartT1") end) [/CODE] Essentially without all the extra BS it's just this
[QUOTE=dannyf127;50793909]I have a 2 timers that are hooked to the Initialize function client side. Obviously as you would assume when 1 player connects, and then another player connects 5 or so minutes later, the timers will be out of alignment. What is the best possible way to align these timers and assure that all players on the server have the same exact time remaining on their timers. I would provide code but I'm assuming there's no need for it since this is more of just a general question.[/QUOTE] If you only want a time to be synchronized with clients and the server, use [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Global/CurTime]CurTime[/url] It's a function that return the "uptime" of the server in second, and it's synced between every computer on the server. Simply define a variable on the server (for example 120 seconds) and network it to every clients. Then on the client: [lua] local timeout = 120 // Networked from the server hook.Add("Tick", "TimerCheckerBlah", function() if (timeout < CurTime()) then // Do your shit hook.Remove("Tick", "TimerCheckerBlah") end end) [/lua]
[QUOTE=guigui;50794407]If you only want a time to be synchronized with clients and the server, use [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Global/CurTime]CurTime[/url] It's a function that return the "uptime" of the server in second, and it's synced between every computer on the server. Simply define a variable on the server (for example 120 seconds) and network it to every clients. Then on the client: [lua] local timeout = 120 // Networked from the server hook.Add("Tick", "TimerCheckerBlah", function() if (timeout < CurTime()) then // Do your shit hook.Remove("Tick", "TimerCheckerBlah") end end) [/lua][/QUOTE] Right however that's no longer the issue since the timers are now synced. The indexes that the timers change are not in sync. Check out what I posted above this response.
If I need to explain this in a better way, I will do so.
[QUOTE=dannyf127;50801910]If I need to explain this in a better way, I will do so.[/QUOTE] What is wrong with using CurTime? I don't understand what you mean by "The indexes that the timers change are not in sync."
When a player initially spawns, network all indexes' current states (including those that are false) and have the client set this as its starting values.
I had to deal with the same kind of thing before and ended up doing something like this: [lua]if SERVER then AddCSLuaFile() end CURRENT_TIMESTAMP = CURRENT_TIMESTAMP or 0 local UpdateTimestamp if SERVER then util.AddNetworkString("HL2CoopTimeSync") util.AddNetworkString("HL2CoopTimeClientSync") local lastUpdate = SysTime() hook.Add("Tick", "HL2CoopTimeSync", function() UpdateTimestamp() end) UpdateTimestamp = function() CURRENT_TIMESTAMP = SysTime() if CURRENT_TIMESTAMP - lastUpdate >= 1 then net.Start("HL2CoopTimeSync") net.WriteDouble(CURRENT_TIMESTAMP) net.Broadcast() lastUpdate = CURRENT_TIMESTAMP end local world = game.GetWorld() world:SetNWFloat("CoopTimeSync", CURRENT_TIMESTAMP) end else TIMESTAMP_UPDATE_TIME = TIMESTAMP_UPDATE_TIME or 0 net.Receive("HL2CoopTimeSync", function(len) local ply = LocalPlayer() TIMESTAMP_UPDATE_TIME = SysTime() CURRENT_TIMESTAMP = net.ReadDouble() if IsValid(ply) then CURRENT_TIMESTAMP = CURRENT_TIMESTAMP + (ply:Ping() / 1000) end --DbgPrint("Update") end) end function GetSyncedTimestamp() if CURRENT_TIMESTAMP == 0 then if SERVER then UpdateTimestamp() else local world = game.GetWorld() CURRENT_TIMESTAMP = world:GetNWFloat("CoopTimeSync", 0) end end local res = CURRENT_TIMESTAMP if CLIENT then local delta = (SysTime() - TIMESTAMP_UPDATE_TIME) res = res + delta end return res end[/lua] Its not exactly highly precise but it should cover most of the cases.
[QUOTE=Zet0r;50806492]When a player initially spawns, network all indexes' current states (including those that are false) and have the client set this as its starting values.[/QUOTE] You are exactly right this is what I thought of last night, I just wasn't networking the server values to the client.
Sorry, you need to Log In to post a reply to this thread.