Help looping through parts and returning table of colors found

Warning: very rookie dev; ugly code ahead:

I’m working on a puzzle game with a large group of colored blocks that are either red, orange, yellow, green, blue, magenta, gray or black.

I periodically generate a player block that is one of these colors. The large group of blocks is constantly changing and may be any combination of these colors and may not include certain colors at any given time. The player block must be one of the remaining colors.

I need to check the large group of blocks on the server, then have a table returned to the client that looks like this, but only includes the colors that were found remaining in the group.

local Color = {BrickColor.new("Really red"), BrickColor.new("Neon orange"),BrickColor.new("New Yeller"), BrickColor.new("Lime green"), BrickColor.new("Really blue"), BrickColor.new("Magenta"), BrickColor.new("Cloudy grey"), BrickColor.new("Really black")}

I have this code that, when pinged by the client, loops through all game blocks and returns which colors are still present back to the server. (I know how poor this looks, again rookie here…)

ReplicatedStorage.RemEvRemColorCheck.OnServerEvent:Connect(function(player,Set)
local R = false
local O = false
local Y = false
local G = false
local B = false
local M = false
local Gr = false
local Bl = false
for i, part in pairs(Set.Parts:GetChildren()) do
  if part.BrickColor == BrickColor.new("Really red") then R = true end
  if part.BrickColor == BrickColor.new("Neon orange") then O = true end
  if part.BrickColor == BrickColor.new("New Yeller") then Y = true end
  if part.BrickColor == BrickColor.new("Lime green") then G = true end
  if part.BrickColor == BrickColor.new("Really blue") then B = true end
  if part.BrickColor == BrickColor.new("Magenta") then M = true end
  if part.BrickColor == BrickColor.new("Cloudy grey") then Gr = true end
  if part.BrickColor == BrickColor.new("Really black") then Bl = true end
end
game.ReplicatedStorage.RemEvRemColorCheck:FireClient(player,R,O,Y,G,B,M,Gr,Bl) -- TO SERVER - fires after loop
end)

Question: How can I translate my returned data (true / false for each color), into a table like this?

local Color = {BrickColor.new("Really red"), BrickColor.new("Neon orange"),BrickColor.new("New Yeller"), BrickColor.new("Lime green"), BrickColor.new("Really blue"), BrickColor.new("Magenta"), BrickColor.new("Cloudy grey"), BrickColor.new("Really black")}

local function SpawnNextPart() -- Function to bring a Part into the Next-Part waiting spot
  if PartQueued == false then
    PartQueued = true
    local NextPart = Part:Clone()
    NextPart.Position = Set.PNextPart.Position
    NextPart.BrickColor = Colors[math.random(#Colors)]
  end
end

Appreciate any help.

1 Like

what kind of table? do you want a table of bool (true/false) values for each color or a table of all the found colors, denoted as {BrickColor} it would help to know why you are checking the colors and what you plan on doing with the found and not found colors.

Thanks for the quick response. The very last section of code in my post shows the example of the table, and my next piece of code, which generates a “player part” that is one of the returned remaining colors randomly.

Honestly, my question is probably simple, how to translate the “true” returned values into their corresponding BrickColor designations, and the “false” not included in the Colors table at all.

Ah the last part explained it perfectly, you probably don’t want to track boolean values instead make an array of found brick colors.

local foundColors = {}
for i, part in pairs(Set.Parts:GetChildren()) do
  if part.BrickColor == BrickColor.new("Really red") or
  part.BrickColor == BrickColor.new("Neon orange") or
  part.BrickColor == BrickColor.new("New Yeller") or
  part.BrickColor == BrickColor.new("Lime green") or
  part.BrickColor == BrickColor.new("Really blue") or
  part.BrickColor == BrickColor.new("Magenta") or
  part.BrickColor == BrickColor.new("Cloudy grey") or
  part.BrickColor == BrickColor.new("Really black") then 
    table.insert(foundColors, part.BrickColor)
  end
end

theevent:FireClient(player, foundColors)
1 Like

Thank you! “table.insert” was a large piece of what I was missing.

Two more questions please:

  1. The table this creates “foundColors” now includes the color of every single part in my set. the set may include many red parts, many blue, but no green. In that case, I am trying for a table that only includes red one time, blue one time, and does not include green. What I received includes red listed one time for each time it is found: Server fired client and returned: ▼ {
    [1] = Really red,
    [2] = Really red,
    [3] = New Yeller,
    [4] = New Yeller,
    [5] = Really blue,
    [6] = Really blue,
    [7] = Really blue,
    [8] = Lime green,
    [9] = Really red,
    [10] = Really red,
    …and so on
    } - Client - GamePlayScript:51

  2. The table returned includes the colors only (Really red), but not the full BrickColor designation I need: "BrickColor.new(“Really red”).

  1. You’re right my mistake, we need to check if it’s in the table and if it isn’t we add it.
  part.BrickColor == BrickColor.new("Cloudy grey") or
  part.BrickColor == BrickColor.new("Really black") then
    if table.find(foundColors, part.BrickColor) == nil then -- find is nil if it isn't in the table!
      table.insert(foundColors, part.BrickColor)
    end
  end
  1. Is more complicated there are some things that can and cannot be sent over a remote event. I believe BrickColor is a enumerated type and in fact can only be sent over as a string, hence it automatically is converted. The automatic conversion is actually quite lucky too, normally it will replace any values it cannot send with nil.
    You can read more about the limitations on the Roblox Articles “Remote Functions and Events” though it can be a tough read. I would say largely stick to sending numbers and strings through remote events. Since you can convert the brick color back easily it’s not so much of a problem now
BrickColor.new(clientColors[1])
-- or
for _, colorString in ipairs(clientColors) do
  local brickColor = BrickColor.new(colorString)
end
2 Likes

Can’t thank you enough for the coaching here. I’m always amazed at the willingness to share and craft these detailed responses. THANK YOU.

(edit) And yes, your update to the table methodology worked perfectly to add the color only one time if found.

I’m going to research the specifics of passing values through remote events as you suggest.

My mind keeps going back to passing true or false values depending on whether the color is found, then perhaps I build the table client-side like with something like If R = true, table.insert(Colors, BrickColor(“Really red”) – I think the challenge is the use of quotes (") in the color designation.

Edit: After reading further I may try to pass color3.

1 Like