Is using the Changed event expensive in terms of server resources? I am using IntValue Objects in ReplicatdStorage that get updated from more secure values in my Player Data. I have attached this Changed event to a function that updates the player GUI.
I hope to have at least 20+ players in the lobby of this game, maybe more if I can!
Does this sort of thing cause the server to be constantly using resources to see if the value changed? Is this a problematic way to do things?
Thanks in advance for taking the time to read and share your knowledge.
The server doesn’t need to check anything to see if the value changed, it just fires the event when it does change. Whenever something changes the value, it also causes the event to be fired.
RemoteEvents are an alternate approach, where instead of setting the value of an IntValue, you change some variable and call RemoteEvent:FireAllClients(newValue) with the new value. Effectively the same thing is taking place; the server changes a value and then signals every client to the change in the value. Using an IntValue, the server changes the value and then that change is replicated to every client, and the Changed event fires. Connecting to Changed would be just as intensive as connecting to OnClientEvent.
Thanks, I want sure how it was fired and was hopeful it wasnt some built-in loop where if you have dozens of these sitting around, you build up conditions that lead to server lag.
The server doesn’t need to check for changes in an IntValue or fire the new value to the client unless the client cannot see it. The contents of ReplicatedStorage replicate to both environments so both the client and the server can access it. The client can listen for IntValue.Changed and the server needs not do anything.
So do I need a Changed event to fire a function that updates a GUI textlabel? If I just set the GUI textlabel to equal the value of the object, will the GUI update automatically?
Here’s a neat class I wrote called ValueContainer that behaves similarly to how things like IntValue are implemented. You can see that no loops are necessary, all of the connections are given the new value only when the value is changed.
local ValueContainer = {new = function(value)
local connections = {}
return setmetatable({
Changed = {
Connect = function(self, f)
local connection = {Connected = true}
connections[connection] = f
function connection:Disconnect()
connections[connection] = nil
connection.Connected = false
end
return connection
end;
Wait = function(self)
local thread = coroutine.running()
local connection;
connection = self:Connect(function(newValue)
connection:Disconnect()
coroutine.resume(thread, newValue)
end)
return coroutine.yield()
end
}
}, {
__index = function(t, k)
assert(k == "Value", k.." is not a valid member of ValueContainer")
return value
end;
__newindex = function(t, k, v)
assert(k == "Value", k.." is not a valid member of ValueContainer")
if value ~= v then
value = v
for _, f in pairs(connections) do
f(value)
end
end
end
})
end}
example:
local container = ValueContainer.new(5)
container.Changed:Connect(function(newValue)
print("value changed to "..newValue)
end)
coroutine.wrap(function()
print("waiting")
print(container.Changed:Wait())
print("done")
end)()
container.Value = 10
Yes. The client will listen for ValueObject.Changed, then update whatever text with the new value passed. The server only needs to change the value of the ValueObject and the client will handle the rest.
-- Client
ValueObject.Changed:Connect(function (NewValue)
-- perform your stuff
end)
-- Server
ValueObject.Value = whatever
Why not use GetPropertyChangedSignal for listening to property-specific changes? No loops are necessary for any instance of Changed in the first place.
GetPropertyChangedSignal would be redundant in this case, IntValue and the like have a unique implementation of the Changed event that only fires when the Value propery is changed, and they also pass the new value to the connected function.