Hamurlik Posted December 16, 2022 Share Posted December 16, 2022 (edited) Hello. I'm making a mod that stores some data on worldstate. I made some variables, as you can see in the snippet below, but printing it on server and on client returns different values. Spoiler AddClassPostConstruct("components/worldstate", function(self, inst) local _watchershack = UpvalueHacker.GetUpvalue(self.AddWatcher, "_watchers") local function SetVariablehack(var, val, togglename) --copied from components/worldstate.lua, so _watchers is consistent and i dont have to override the entire component if self.data[var] ~= val and val ~= nil then self.data[var] = val local watchers = _watchershack[var] if watchers ~= nil then for k, v in pairs(watchers) do for i, fn in ipairs(v) do fn[1](fn[2], val) end end end if togglename then watchers = _watchershack[(val and "start" or "stop") .. togglename] if watchers ~= nil then for k, v in pairs(watchers) do for i, fn in ipairs(v) do fn[1](fn[2]) end end end end end end local function OnAdminOnly(src, tbl) print("OnAdminOnly event", _G.TheShard:GetShardId()) for k, v in pairs(tbl) do print("OnAdminOnly event tbl", tbl, k, v) end local name = tbl.name local but = tbl.preset local bool = tbl.boolean SetVariablehack("cr_" .. but, bool) if bool then adminonly_func(but) end --SendModRPCToShard(SHARD_MOD_RPC["cr"]["adminonly_shard"], nil, name, but, bool) end for _, k in ipairs(button_list) do self.data["cr_" .. k] = button_presets[k].admin_default --boolean end inst:ListenForEvent("cr_adminonly", OnAdminOnly) end) AddModRPCHandler("cr", "adminonly", function(_, name, but, bool) --bool is 1 for true or 0 for false, because sending a false as an argument for an rpc sends it as nil instead, for some reason. print("adminonly_rpc func", name, but, bool, _G.TheShard:GetShardId()) local str if bool == 1 then bool = true str = "disabled" elseif bool == 0 then bool = false str = "enabled" end _G.c_announce(name .. " has " .. str .. " the " .. button_presets[but].name .. " button.") _G.TheWorld:PushEvent("cr_adminonly", { name = name, preset = but, boolean = bool }) end) button_presets.god.admin_default is false, so that's the default value. Printing on server and client returns the same default value of false. Then, I do TheWorld:PushEvent("cr_adminonly", {name = ThePlayer.name, preset = "god", boolean = true}), and printing on server returns true, while client still returns false. I need to check if a button in a widget should be enabled or disabled, accessing it as TheWorld.state.cr_god or similar. Right now I made a workaround, assigning a netvar and updating it by watching world state with a component, which does read it properly. Spoiler local buttons = { "god", "craft", "speed", "suicidedespawn", "mime", "wonkey", "grogginess", "size", "wardrobe", "map", "beard" } local cr_player = Class(function(self, inst) for i,k in ipairs(buttons) do inst.cr_buttons[k].adminonly = net_bool(inst.GUID, "cr_" .. k .. "_adminonly") inst.cr_buttons[k].adminonly:set(false) inst:WatchWorldState("cr_" .. k, function() inst.cr_buttons[k].adminonly:set(TheWorld.state["cr_" .. k]) end) end end) return cr_player This means instead of accessing a button as TheWorld.state.cr_god, I access it as self.owner.cr_buttons.god.adminonly:value(). The problem with this workaround is that I'm storing the same data, on every player, while nor server nor other players ever access this value. It's really wasteful. I need these worldstate variables the same between all shards, too, but right now I just need this to work at least on overworld. In my testing, it works perfectly fine on servers without caves. However, I only have been able to test it while being the host, and I've not tested it on a dedicated server. So that's probably why. I should note that using upvaluehacker to get _watchers table in the first code snippet is not ideal, and I could have probably just gotten the entire SetVariable function instead, but I tried overriding the entire worldstate.lua file, and got the same results of different data on client and server, so I think it's irrelevant. Edited December 16, 2022 by Hamurlik typo as a reason is irrelevant Link to comment https://forums.kleientertainment.com/forums/topic/145238-custom-worldstate-variables-are-not-synced-between-server-and-clients/ Share on other sites More sharing options...
Hamurlik Posted December 29, 2022 Author Share Posted December 29, 2022 Sorry, I entirely misunderstood how world state works. I think world state just holds variables on client side, they are not synced. I had to make a component with netvars that are synced with their world state counterpart Link to comment https://forums.kleientertainment.com/forums/topic/145238-custom-worldstate-variables-are-not-synced-between-server-and-clients/#findComment-1616324 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now