How can I find the difference between two parts?

I want to save some properties for each parts

Server script

local part1 = Instance.new("Part")
local part2 = part1:Clone()
local part3 = part1:Clone()

local parts = {}

local function createProperty(part, colorType, state)
    parts[part] = {
        colorType = colorType,
        state = state
        -- and other
    }
end

createProperty(part1, "red", 1)
createProperty(part2, "blue", 2)
createProperty(part3, "green", 3)

for part, props in pairs(parts) do -- error - Cannot convert mixed or non-array tables: keys must be strings
end

I have read that I can’t save server properties for parts in part’s values because some client can change it.

Maybe, Can I get some unique ID of part?

I send event from client with part
Local script

event:FireServer(part)

Server script

event.OnServerEvent:Connect(function(player, part)
    -- I can get property about the part
    local prop = parts[part]
    -- but I think it wrong way, because I get an error in 'for' loop
end)

How can I recognize the part and get properties from table about the part?

First off, I’m on mobile and it’s 2 AM, so I might not be as clear or as accurate as I usually am, but I will take a go at it.

The first problem I see with your scripts is that you’re inserting a table into another table without a key. Everything needs a key in order to retrieve that table. In order to fix this, you will need to create a key and then store the table inside of it. This is how you would do so.

local function createProperty(part, colorType, state)
    table.insert(parts, (part.Name)) --You can change this to something more precise, but has to be a string or number.
    parts[part.Name] = {
                              ["colorType"] = colorType; --Adding string keys
                              ["state"] = state; --Adding string keys
                       }
end

Another thing I saw was how you stored you values in the table. You must use a key to store these values. I already went ahead and created the keys, but keep in mind that you have to use these ā€œ[ā€ brackets to start and enclose a STRING key.

I hope this helped! :smile:

1 Like

Thank you
Ok, I changed it, but the part.Name is not unique

local function createProperty(part, colorType, state)
    parts[part.Name] = {
        ["colorType"] = colorType; --Adding string keys
        ["state"] = state; --Adding string keys
    }
end

How can I get properties about the part from my table? I have many parts

event.OnServerEvent:Connect(function(player, part)
    local prop = parts[part]
end)

or

event.OnServerEvent:Connect(function(player, partName)
    local prop = parts[partName]
end)

If I set unique names for my parts, will it be safely?

Run a for loop through the table and check the matching property whether they match with the input. Since it’s a dictionary in a dictionary, you can check by the key of each part inside.

Furthermore, why is there OnClientEvent on server? It should be OnServerEvent if the client fired RemoteEvent:FireServer().

Thank you

Furthermore, why is there OnClientEvent on server? It should be OnServerEvent if the client fired RemoteEvent:FireServer() .

Sorry, It was just copy paste

Run a for loop through the table and check the matching property whether they match with the input. Since it’s a dictionary in a dictionary, you can check by the key of each part inside.

Can you describe more please?

Before we step into it, are you trying to compare two parts as it says in the title? How exactly are you going to compare the part?

You can actually use the part instance as a key, if I reckon correctly.

Thank you

You can actually use the part instance as a key, if I reckon correctly.

Yes, I thought the same way and this is a simple way to get properties from a table.

event.OnServerEvent:Connect(function(player, part)
    local prop = parts[part]
end)

But l have an error when I use a ā€œforā€ loop.

for part, props in pairs(parts) do -- error - Cannot convert mixed or non-array tables: keys must be strings
end

And I thought that it is wrong way, isn’t it

If I do not use table(part) as a key, can I get some unique key from ā€œPartā€ to use it as a key?

If parts have some unique ID I will have string keys

If parts have some unique ID I will have string keys

Or
How can I do that?

Yes, parts can be indices for tables.

 mytable[game.Workspace.Baseplate] = 5 

Also, keys in a dictionary don’t need to be in brackets.

 mytable = { hello = 4, goodbye = 3} 

However, I would put the keys inside brackets. They may otherwise be messed up by your function arguments of part, colorType, and state.

Now it’s time for

 -- error - Cannot convert mixed or non-array tables: keys must be strings

Are you sending the parts table to the client/server using a remove event? If so, all the keys of your table must be strings, or if using numbered keys, there cannot be any ā€˜gaps’ in the table. You may also have issues if the keys are parts. I’ve never tried that.

okay: {2, 4, 5, 9}
okay: {hello = 5, bob = 3}
not okay: {2, 4, 5, nil, 9}
not okay: {2, 4, 5, bob = 4}

1 Like

EDIT: Directed at @Teltair

So wait, I might have missed something, but why can’t you just change the name to like, ā€œPartā€ā€¦Colour?

I’ll let you know what I think after that.

Nope, sorry, its for the original poster. I’ll edit that post.

Thank you

Are you sending the parts table to the client/server using a remove event? If so, all the keys of your table must be strings, or if using numbered keys, there cannot be any ā€˜gaps’ in the table. You may also have issues if the keys are parts. I’ve never tried that.

Ok

Server script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local event = ReplicatedStorage.RemoteEvent
local HttpService = game:GetService("HttpService")
local props = {}

local function createPart()
    local part = Instance.new("Part")
    local id = Instance.new("StringValue", part)
    id.Name = "ID"
    id.Value = HttpService:GenerateGUID(false)
    return part
end

local function createProperty(partID, colorType, state)
    props[partID] = {
        ["colorType"] = colorType;
        ["state"] = state;
        -- etc
    }
end

local part = createPart()
createProperty(part.ID.Value, "red", 1)
part = createPart()
createProperty(part.ID.Value, "blue", 2)
part = createPart()
createProperty(part.ID.Value, "green", 3)

event.OnServerEvent:Connect(function(player, part)
    local prop = props[part.ID.Value]
end)

Client local script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local event = ReplicatedStorage:WaitForChild("RemoteEvent")
...
event:FireServer(part.ID.Value)

I have string unique keys and I am happy
But I read that the client can change part.ID.Value by exploit
or Am I mistaken?

Is there other way to have a similar structure?

Thank you

Yes of course

I can change part.Name

But I think that client can change it and I won’t have right values

If I’m wrong, please correct me

Clients can change the value on their computer, it won’t replicate.

You can read more about Server and Client Relationship, there are many great articles.

1 Like

Thank you

Yes, you are right
I checked it

Server script

local event = game.ReplicatedStorage.TestEvent
local part = Instance.new("Part")
local id = Instance.new("StringValue", part)
id.Name = "ID"
id.Value = "Test"
part.Parent = workspace
print(part.Name) -- Part
print(part.ID.Value) -- Test
event.OnServerEvent:Connect(function(player)
    print(part.Name) -- Part
    print(part.ID.Value) -- Test
end)

Client local script (tool)

local tool = script.Parent
local event = game.ReplicatedStorage.TestEvent;
tool.Equipped:Connect(function()
    local p = workspace.Part
    print(p.Name) -- Part
    print(p.ID.Value) -- Test
    p.Name = "NewName"
    p.ID.Value = "NewValue"
    print(p.Name) -- NewName
    print(p.ID.Value) -- NewValue
    event:FireServer()
end)

Console

Part
Test
Part
Test
NewName
NewValue
Part
Test

1 Like