As a developer, Changed is not reliable enough because it can break my code by firing for properties that are not Lua-scriptable. For instance: ReplicatingAbsoluteSize.
Example of Broken Code:
local propertyValues = {}
screenGui.Changed:connect(function(property)
propertyValues[property] = screenGui[property] --Errors because ReplicatingAbsoluteSize is not Lua-scriptable and cannot be read
end)
Improvements to Development Experience:
Should this issue be resolved, my development experience would be improved by not needing to manually blacklist certain events from Changed, and not needing to worry about my code breaking whenever a non Lua-scriptable property is added in the future.
AbsoluteValue is readable and a useful property to read.
Example usage: Expecting .Changed for AbsoluteSize to fire is needed when we want to know when someone resizes their screen.
AbsoluteValue isnât settable, that is true, but you never said that. You said itâs not queryable (that is, readable). I guess itâs just a typo.
The example use, (replicating any property on .Changed), is a bad practice.
Using FilteringEnabled and then replicating changes on the .Changed by passing to a RemoteEvent is both inefficient and defeats the purpose of using FilteringEnabled.
This results in blindly replicate changes, but RemoteEvents are more expensive than using ROBLOXâs native replication
Yes, you can start filtering properties and things with your suggested replicated system, but then youâre defeating your original purpose of having .Changed fire for only queryable properties.
Using pcall to solve this is also incrediably inefficient
The property argument in the .Changed is there to help you filter out changes that you donât want. Use it!
My suggestion is to start using FilteringEnabled correctly, or not at all.
Until I actually see proof of a property that cannot be read or written (i.e. errors on read), that fires .Changed, I vote against this feature.
Itâs being used in a plugin â FE does not apply.
The plugin itâs being used in is a CoreGui two-way mirror since ROBLOX broke showing the contents of the actual CoreGui in the explorer when it was force-enabled through the reflectionmetadata.xml. If you change one thing in the dummy CoreGui or a CoreScript changes something in the real CoreGui, the property changes need to replicate to the same object on the other side of the mirror â thereâs no way around that.
Itâs not a typo. ReplicatingAbsoluteSize is an actual property thatâs not the same as AbsoluteSize. It canât be read (if you do print(screengui.ReplicatingAbsoluteSize) you get an error).
This is not a feature request to stop firing for read-only properties. Itâs a request to stop firing for properties that canât even be read.
There isnât a convenient list of non-queryable properties to blacklist â theyâre not on the wiki page nor in the API dump. You happen upon them by chance, and thatâs not a good thing to have to work with. Even if there was a list of them, why are we having to deal with non-usable properties?
omg noob itâs not an argument. Jumping into stuff in the mindset that itâs a win/lose battle is a no no â canât we just have a productive and friendly conversation?
Letâs start with this. I said I disagree with your argument because I wanted to avoid the ad-hominem attacks that seem to get thrown around in forums. Itâs not about winning an argument, itâs about respectfully discussing this sort of thing.
I agree we should do that, and thatâs why I opened with that. Let me reword: I disagree with your argument for â.Changed should not fire for non-queryable propertiesâ which is what we were discussing.
Iâm sorry if I somehow came off as attacking you. I merely intended to attack your argument (which is why that was first specified).
Yep. You get an error saying it doesnât exist.
> print(game.StarterGui.Frame.ReplicatingAbsoluteSize)
21:06:06.153 - ReplicatingAbsoluteSize is not a valid member of Frame
21:06:06.156 - Script 'print(game.StarterGui.Frame.ReplicatingAbsoluteSize)', Line 1
21:06:06.157 - Stack End
> game.StarterGui.ScreenGui.Frame.Changed:connect(function(Property) print(Property) end)
Size
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
AbsoluteSize
I stand by initial argument, even with the new information, as I canât reproduce the error. Of course, I havenât put a lot of effort into this, but a copy of your plugin that repros it will work fine.
syncConnections[object] = object.Changed:connect(function(property)
modifyProperty(clone, property, object[property])--trying to index object[property]
end)
Repro video:
Edit: ReplicatingAbsoluteSize is a member of ScreenGui â not Frame. Thatâs why you werenât getting the correct error.
âNon-scriptableâ or âunstableâ is the generally accepted term when referring to these kinds of properties. I assume thatâs what you mean.
I brought up this exact issue years ago when they were making changes involving these properties. I thought I remembered someone saying that it was going to be fixed, but it never happened.
First of all, neither one of those are settable, so using .Changed to modify wonât work out anyway. In any event, it looks like it fires double because the replicating part fires.
Iâd still not recommend syncing the way youâre doing, but arguable that single property shouldnât trigger a .Changed event.
Being settable has nothing to do with it. ReplicatingAbsoluteSize cannot be queried. Unlike AbsoluteSize which can be read, print(screengui.ReplicatingAbsoluteSize) will error with âUnable to query property ReplicatingAbsoluteSize. It is not scriptable.â ReplicatingAbsoluteSize cannot be used at all.
There are more (i.e. DraggingV1 of BasePart) â itâs not just ReplicatingAbsoluteSize. Regardless of the number though, these properties should not trigger .Changed. They are of no relevance to and canât be used by us â the only thing they accomplish is causing errors. Of course they shouldnât fire .Changed.
There is no other way. No matter how you go about it, syncing two partsâ properties is setting the opposite oneâs property to the value of the changed one.
That feels like the wrong word to use⌠maybe âreadâ works better
That aside, I totally agree that a property shouldnât fire changed if it canât even be read. Maybe making it readable is a solution or the other solution is removing the changed signal.
If you use the API dump, you wonât even know of those properties. (Actually, arenât there a few listed on the AD that arenât scriptable? I forgot)
Why not just listen to the specific properties youâd like to change?
Itâs a bad idea to simply query a property if you donât know what property youâre accessing.
Regardless of what we think best practices are, unless Changed is deprecated, ROBLOX is encouraging developers to use it. Since itâs intended to be used, it shouldnât cause unexpected errors. There are also use cases for listening to every property (e.g. mirroring an instance, only subscribing to a single event instead of 20 if a large number of properties need to be subscribed to, etc)
This is a bug Iâd like to fix, but itâs a dangerous change internally. Iâll try to see if I can do it. Thereâs no reason for us to expose unscriptable properties in our API. It should be as though they donât exist.