How to detect changes in properties of parts in a table

I am making an in game recording system to record part movements over frames. I am doing this by getting all the parts in the workspace and checking what properties they have are unique (not default) from there class and recordinging them. I do this every second or so and reference the previous second to see if a part was static or dynamic. The issue is that when a part gets deleted between scans I don’t know how to check back. Basically my question is how to align the tables of properties and/or give each part an id that doesn’t mess with the client or server.

1 Like

Not 100% sure if I understand what you’re asking but I would recommend using two different events for this in combination with a loop. Here is what it will basically entail.

for _,a in pairs(workspace:GetChildren()) do
    if a:IsA("BasePart") then
        a.Changed:Connect(function(prop)
            if (prop == 'Position') then print("Position changed")
            elseif (prop == 'Parent') then print("Part deleted") -- Parent property is what will register when part gets deleted
            end
        end)
    end
end
2 Likes

Thats not what I am trying to do. Sorry but I am not good at explaining. I am trying to get all the parts in workspace and then basically record their not default properties in a table kinda like this.
{{classname = "Part", position = PartCFrameHere, size = Vector3.new(0,10,0)}, {classname = "Seat", position = PartCFrameHere, size = Vector3.new(0,10,2)}}
I do this every second and then tell the differences. If the first part didn’t move over the 1 sec wait until next time, no new properties would be recorded. But if it moved a block the next table would show the new position.
I need to sync the parts/identify them so if the part gets deleted between frames it will not cause or offset the other parts.

So like have a loop that runs forever like this?

local datatable = {}
while true do
    wait(1)
    datatable = {}
    for _,v in pairs(workspace:GetDescendants()) do
        if v:IsA("BasePart") then
            table.insert(datatable,{classname = v.ClassName,position = part.CFrame,size = v.Size--[[extra values here]]})
        end
    end
end

This would be quite expensive as you’re looping through all parts in workspace which can add up to a hefty amount.
Using .Changed would be better as you’re not searching through all parts in workspace every second and creating a new table. By using .Changed you can update the specific data when you need to and it doesn’t have to wait for the wait(1) to get resumed and update all part data again.
(also if you’re using only going to search through workspace once with :GetDescendants() or :GetChildren() then you might want to use a .ChildAdded or .DescendantAdded so objects could be added later)

Kinda what you are saying except that if the part in the previous table did not move, or have any properties change during the 1 second wait, it doesn’t record them again.
Kinda how video only records the pixels that change between frames and not individual pictures each time.

local datatable = {}
while true do
    wait(1)
    for _,v in pairs(workspace:GetDescendants()) do
        if v:IsA("BasePart") then
            if datatable[v] then
                local data = datatable[v]
                if not v:IsDescendantOf(workspace) then
                    datatable[v] = nil
                else
                    for property,value in pairs(data) do
                        data[property] = v[property]
                    end
                end
            else
                datatable[v] = {--[[properties here]]}
            end
        end
    end
end

Does this work?

Doesn’t seem to work. Also, not sure how I can tell if a part got deleted between frames or when the property was changed.

Can’t you check the .Parent property?

Like get a timestamp? You would definitely have to use a .Changed event then.

Can’t check parent property without live instance to check if parent is nil.

Don’t want to use changed event due to loops occurring each second.

Here is the system concept again. I am getting confused myself.

1st time loop runs it record all properties of all parts.
After 1st loop it only records changes. Like a part being deleted or position being changed.
Each loop is 1 second apart and “scans” the workspace.
Big issue is identifying if part is the same part in both scans or is completely new part or a previous part was deleted offsetting the table. I can’t store instances in the table, only properties.

Why can’t you store instances inside the table? In my script it will automatically remove instances that were moved out of workspace from the table, so there won’t be any memory leak issues.

Can’t store instances in the table because I want the system to be able to “record” for a certain amount of time in game A and then it be able to give you a giant table which you could simply paste in another completely different game and be able to watch the recording.