The connect syntax is a special thing that ROBLOX made for its own objects. Developing that syntax for your objects is not preferable.
You can use a loop as someone else mentioned, but it requires knowledge of the table (what to watch), and potentially could miss some changes.
Instead, we can use creative metatable solutions to do this.
local inventory = {};
local fake = {};
function onChange(key)
print("CHANGED",key,"TO",inventory[key]);
end
local recursive = false;
local meta = {
__index = function(key)
return fake[key];
end,
__newindex = function(_,key,value)
print("SETTING!");
fake[key] = value;
recursive = true;
if not recursive then
onChange(key);
end
recursive = false;
end
};
setmetatable(inventory,meta);
This method has a number of drawbacks, unfortunately. A number of built in functions do not work with this for technical reasons:
pairs ipairs table.insert table.remove. These all can technically be remedied by redefining them, however, that would be an annoying project.
Robust loop approach:
While a loop cannot manage to capture instantaneous changes, it can at least track changes from time to time. A robust solution would automatically capture all visible changes, and not just those on a select number of variables. We can do that like this:
local old = {};
function watch(tab)
if not old[tab] then
old[tab] = {};
end
local exist = {};
for index,value in pairs(tab) do
if old[tab][index] ~= value then
Changed(index,tab);
end
old[tab][index] = value;
exist[index] = true;
end
for index in pairs(old[tab]) do
if not exist[index] then
Changed(index,tab);
old[tab][index] = nil;
end
end
end
In some external loop (or using the Stepped event or similar) we continually call watch on the table we want to watch. This function in turn will call Changed for any values which are different from the last call to watch.
This is robust because it requires no knowledge of which values you need to watch, and will work for all. However, if you ever redefine a list completely, e.g., inventory = {}; then the change of deleting them will not be found. In this case, I designed watch to have a second, optional, "name" parameter. This is used to identify tables instead (when provided), so if you want to be able to clear out a table, you can pass "inventory" as the second parameter to watch.
(This is of course all just an example and your implementation could vary)
Good luck!