Creating a part wiring system?

Hello everyone! This is my first post on this forum and I am currently working on a logic gates simulation/circuitry system, and i cannot for the life of me figure out how to code it.

I attempted to create a system where if you click on a part named “Output”, and then click on a part named “Input1” or “Input2”, a black wire would appear between those 2 parts, and the color of the output determines the color of the input.

Here is a script for an AND gate (the game is down at the end if you want to try it):

local andGate = script.Parent
local input1 = andGate.Input1
local input2 = andGate.Input2
local output = andGate.AndOutput

local clickDetector1 = input1:FindFirstChildOfClass("ClickDetector") or error("ClickDetector not found on Input1")
local clickDetector2 = input2:FindFirstChildOfClass("ClickDetector") or error("ClickDetector not found on Input2")

--state of inputs
local isInput1On = false
local isInput2On = false

-- function to set the color of input1 based on its state
local function setInput1Color()
	isInput1On = not isInput1On
	input1.BrickColor = isInput1On and BrickColor.new("Shamrock") or BrickColor.new("Persimmon")
	updateOutput()
end

-- function to set the color of input2 based on its state
local function setInput2Color()
	isInput2On = not isInput2On
	input2.BrickColor = isInput2On and BrickColor.new("Shamrock") or BrickColor.new("Persimmon")
	updateOutput()
end

function updateOutput()
	-- updates output based on AND logic
	output.BrickColor = (isInput1On and isInput2On) and BrickColor.new("Shamrock") or BrickColor.new("Persimmon")
end

clickDetector1.MouseClick:Connect(setInput1Color)
clickDetector2.MouseClick:Connect(setInput2Color)

updateOutput()

The gate works just fine, its the wiring system that is annoying me. I have the actual wire part creation working, but i need to output some sort of “Signal” so that the color of the output is the same as the color of the input it is wired to. This is currently what im working with (this is just an example script for now between 2 parts in the workspace when i click on them)

local outputPart = nil
local wire = nil
local wiringEnabled = true

local function createWire(part)
    if outputPart and (part.Name == "Input1" or part.Name == "Input2") then
        wire = Instance.new("Part")
        wire.Name = "Wire"
        wire.Material = Enum.Material.Slate
        wire.Color = Color3.new(0, 0, 0)
        wire.Anchored = true
        wire.CanCollide = false
        wire.Size = Vector3.new(0.2, 0.2, (part.Position - outputPart.Position).Magnitude)
        wire.CFrame = CFrame.new(outputPart.Position, part.Position) * CFrame.new(0, 0, -wire.Size.Z / 2)
        wire.Parent = workspace

        local clickDetector = Instance.new("ClickDetector")
        clickDetector.Parent = wire

        if not part:FindFirstChildOfClass("ClickDetector") then
            local clickDetector = Instance.new("ClickDetector")
            clickDetector.Parent = part
        end

        if not workspace[part.Name]:FindFirstChildOfClass("ClickDetector") then
            local clickDetector = Instance.new("ClickDetector")
            clickDetector.Parent = workspace[part.Name]
        end

        print("Wire created between " .. outputPart.Name .. " and " .. part.Name)
        wiringEnabled = false
    elseif not outputPart then
        warn("Please click on a part named Output first.")
    else
        warn("The part you clicked on is not named Input1 or Input2.")
    end
end

script.Parent.MouseButton1Click:Connect(function()
    if wiringEnabled then
        local function onPartClicked(part)
            if part.Name == "Output" then
                if wire then
                    wire:Destroy()
                    wire = nil
                end
                outputPart = nil
                wiringEnabled = true
            elseif part.Name == "Wire" then
                part:Destroy()
            elseif outputPart and (part.Name == "Input1" or part.Name == "Input2") then
                createWire(part)
            end
        end
        for _, part in pairs(workspace:GetChildren()) do
            if part:IsA("BasePart") then
                local clickDetector = part:FindFirstChildOfClass("ClickDetector")
                if not clickDetector then
                    clickDetector = Instance.new("ClickDetector")
                    clickDetector.Parent = part
                end
                clickDetector.MouseClick:Connect(function()
                    onPartClicked(part)
                end)
            end
        end
    end
end)

(Extra info: The Input parts and outputs are inside of their respective model, so Input1 and Input2 and AndOutput (all outputs have their own output name) are in a model called AND, and this model is stored inside of object folder with all the other gates)

i have looked all over youtube and the dev forum and even tried to find models and even used ai to help me, im a pretty new dev so i need help on this stuff. Thank you!

game if you want to check it out: Logic Gates System! [Demo] - Roblox
(the wiring tool doesnt work right now, and if you use the delete tool, BE CAREFUL, it can delete the baseplate.)

2 Likes

How about you store an actual BoolValue in each wire that’s either true or false (off or on based on the connected output to the wire.) Then when you connect the wire to the gate you want, you refer back to the value in the wire and change the input to either off or on. You’d have to change a bit of your script to make sure the gates are referring to a value but that shouldn’t take too much testing. Idk if this is a multiplayer kind of game but if it is, you’d have to use a server script with events for others to see whats going on.
p.s I’m sure there’s a better way to do this but I’m no wizard, good luck with the game and I can’t wait for the integrated circuit update in 5 years

2 Likes

I cannot believe I didn’t think of using what u told me, thank you for the suggestions, and ill make to try something like this tomorrow. By the way, it’s just a sandbox game, so yeah its multiplayer so other people can see what you’re doing. if it works, ill make this the solution unless someone has some better idea

1 Like

That’s really cool, I studied digital circuits a lot last year and they’re really interesting once you get into them, the things you can make are infinite. Good luck with the project and let me know once It’s finished so I can play it.

1 Like

The world of the bit32 luau library is yours.

1 Like

I will let you know when i finish the wiring system and also when i implement stuff you can output to (led and stuff)

1 Like

update on my work, i just completely rewrote my gate systems (except SR and JK for now) to use boolvalues instead of JUST brick colors. Here is the brand new AND gate code and example:

local input1 = script.Parent.Input1
local input2 = script.Parent.Input2
local output = script.Parent.Output

local function toggleInput(input)
	input.Value = not input.Value
end

local input1Value = Instance.new("BoolValue")
input1Value.Name = "BoolValue"
input1Value.Value = false
input1Value.Parent = input1

local input2Value = Instance.new("BoolValue")
input2Value.Name = "BoolValue"
input2Value.Value = false
input2Value.Parent = input2

local outputValue = Instance.new("BoolValue")
outputValue.Name = "BoolValue"
outputValue.Value = false
outputValue.Parent = output

local function updateOutput()
	outputValue.Value = input1Value.Value and input2Value.Value
	if outputValue.Value then
		output.BrickColor = BrickColor.new("Shamrock")
	else
		output.BrickColor = BrickColor.new("Persimmon")
	end
end

local function updateColor(part, boolValue)
	if boolValue.Value then
		part.BrickColor = BrickColor.new("Shamrock")
	else
		part.BrickColor = BrickColor.new("Persimmon")
	end
end

input1.ClickDetector.MouseClick:Connect(function()
	toggleInput(input1Value)
	updateColor(input1, input1Value)
	updateOutput()
end)

input2.ClickDetector.MouseClick:Connect(function()
	toggleInput(input2Value)
	updateColor(input2, input2Value)
	updateOutput()
end)

input1Value.Changed:Connect(updateOutput)
input2Value.Changed:Connect(updateOutput)

updateColor(input1, input1Value)
updateColor(input2, input2Value)
updateOutput()
1 Like