You can write your topic however you want, but you need to answer these questions:
Hey I want to check if a table has changed (got added an instance or not) in every 3 seconds
I have no idea how to do it with my own knowledge
I have tried scripting this thing but It doesnt seem to be working
Any help would be appreciated. How can I exactly detect whenever the table has changed
local plr = game:GetService("Players").LocalPlayer
local enemies = game.Workspace.Enemies
local CombatEnemies = {}
--- SERVICES
local RunService = game:GetService("RunService")
local function enemyCheck()
for i , Enemy in pairs(enemies:GetChildren()) do
local distance = (plr.Character:WaitForChild("HumanoidRootPart").Position - Enemy:WaitForChild("HumanoidRootPart").Position).Magnitude
if distance < 100 then
if not CombatEnemies[Enemy] then
CombatEnemies[Enemy] = true
end
end
if distance > 100 and CombatEnemies[Enemy] == true then
CombatEnemies[Enemy] = nil
end
end
end
local function TableChange()
while true do
task.wait(3)
local CurrentSet = {}
enemyCheck()
if #CurrentSet ~= #CombatEnemies then
CurrentSet = CombatEnemies
end
end
end
you can either use Variable for that or BoolValue(whatever you want)
No problem, dev in here always help
you can improve
i’ve been answered all your questions, the Script look fine to me but, you could change CombatEnemies[Enemy] = nil to CombatEnemies[Enemy] = false (Optional) also change local function to function (Optional), overall the Script is fine!, just dont mess it up
You can also use setmetatable to intercept the changes to the table without using any kind of loop.
For example:
local data = {}
local CombatEnemies = {}
function updated()
print("there was a change to the table")
end
setmetatable(CombatEnemies, {
__index = function(_, key)
return data[key]
end,
__newindex = function(_, key, value)
local oldValue = data[key]
if value == nil then
if oldValue ~= nil then
data[key] = nil
updated() -- something was removed
end
elseif oldValue == nil then
data[key] = value
updated() -- something was added
else
data[key] = value
updated() -- something was updated
end
end,
__pairs = function()
return next, data, nil
end,
__len = function()
return #data
end
})
also you might asking why
change CombatEnemies[Enemy] = nil to CombatEnemies[Enemy] = false
i see that your Script have CombatEnemies[Enemy] = nil So it just hurt my eyes, that you didnt use boolean for it
also you asking about why change local function to function lemme explain clearly in basic term function is basically a function that defined on top of code, to visual this imagine a gun, when you shoot a gun yeah you see it function outside, but it also has local function inside which is the mechanics of a gun
I used chatgpt for adding instances into table and he said If I do false I dont remove it from the table I just make it’s value false and I didnt want that
thats why I used nil
The metatable (__index, __newindex, __pairs, __len) are just metamethods which are methods that let you change how table’s behave when certain operations happen within them - almost like they are hooks.
So the code I gave you sets the metatable to overhook __newindex to fire the updated function on changes.
Only __newindex is relevant in the example I gave but I just kept the others there to preserve the functionality of the table (e.g. __pairs is for looping, __index is for fetching data and __len for getting the table length).
If it’s well maintained then yeah it can be okay.
I prefer breaking everything up into different scripts though, mainly ModuleScripts and then just make the functions and data exported from them - makes maintenance and debugging much easier anyway.
(You never stop learning programming, there is no end)
My most recent game probably has around 40-50 different scripts with 80% of them just being module scripts that return different data and functions to be used.
Just try using this with your current code and see if it works as you wish but yea I would advise you do learn them.
Just remove your declaration of CombatEnemies and simply paste this at the top of your script.
local data = {}
local CombatEnemies = {}
function updated()
print("there was a change to the table")
end
setmetatable(CombatEnemies, {
__index = function(_, key)
return data[key]
end,
__newindex = function(_, key, value)
local oldValue = data[key]
if value == nil then
if oldValue ~= nil then
data[key] = nil
updated() -- something was removed
end
elseif oldValue == nil then
data[key] = value
updated() -- something was added
else
data[key] = value
updated() -- something was updated
end
end,
__pairs = function()
return next, data, nil
end,
__len = function()
return #data
end
})
And I’ll just again briefly explain why it works and what’s happening.
Essentially CombatEnemies just becomes a proxy for data - you can see I am setting the metamethods to update the values inside of the “data” table instead of the CombatEnemies and also I am returning the values from “data”.
That way when you do CombatEnemies[key] for example it’s actually doing data[key] - the difference is in the __newindex (a value change) so if a value is changed then it will trigger updated AND also update the data - I broke it up into 3 things (removal, added, updated) incase you wanted to use that in future.
Meanwhile
me : lowkey painfully writing whole backend-frontend, 100-1000 lines of codes, 100-200+ configs system im really tired, even the codes are working, no error at all, good codes, im just tired so that why ppl have devs team, and im just solo