Someone please help me debug my Rubik's cube script

What do you want to achieve? Keep it simple and clear!
I want to make a working Rubik’s cube.

What is the issue? Include screenshots / videos if possible!
Rotating only 1 side works fine, but as soon as you try to rotate another side that isn’t the opposite side it doesn’t work correctly.

Rotating only 1 side works fine:
image

Rotating another side that isn’t the opposite side:
image

What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I haven’t tried any solution yet so far, because I don’t even know where it went wrong. I did search a bit on the devforum but I only found Cube Puzzle - a 3x3 combination puzzle, which isn’t really resourceful.

It might also help to have the code and baseplate of this issue ofc :stuck_out_tongue: so here it is:

Baseplate.rbxl (716.9 KB)

local parts = {}

local partsCoordsOriginal = {}

function getNewPartName(part)
	local name = partsCoordsOriginal[part.Position]
	
	if name ~= nil then
		return name
	end
	
	local lastDist = 1000000
	local correctData
	for i, _ in pairs(partsCoordsOriginal) do
		local dist = (i - part.Position).Magnitude
		if dist < lastDist then
			lastDist = dist
			correctData = {i, partsCoordsOriginal[i]}
		end
	end
	
	if correctData ~= nil then
		part.Position = correctData[1]
		return correctData[2]
	end
	
	warn("Couldn't find name of part, original name: " .. part.Name)
	return nil
end

function filter(id, value, skip)
	if id < 1 or id > 3 then
		error("Invalid filter ID in Rubik's cube's script.")
	end
	
	if skip == nil then
		skip = {Name = ""}
	end
	
	local result = {}
	for _, part in pairs(parts) do
		if part[id + 1] == value then
			if part[1].Name ~= skip.Name then
				table.insert(result, part[1])
			end
		end
	end
	return result
end

for _, part in pairs(script.Parent.Parts:GetChildren()) do
	partsCoordsOriginal[part.Position] = part.Name
	local coords = string.split(part.Name, ",")
	table.insert(parts, {
		part,
		tonumber(coords[1]),
		tonumber(coords[2]),
		tonumber(coords[3])
	})
end

function renameCubeParts(affectedParts)
	for _, part in pairs(affectedParts) do
		part.Name = getNewPartName(part)
	end
end

function executeTrigger_CORE(selectedParts, skip, move)
	local model = Instance.new("Model", script.Parent)

	for _, obj in pairs(selectedParts) do
		obj.Parent = model
	end

	model.PrimaryPart = model[skip]

	for i = 1, 12 do
		model:SetPrimaryPartCFrame(model:GetPrimaryPartCFrame() * move)
		wait(.01)
	end
	
	renameCubeParts(selectedParts)
	
	for _, obj in pairs(model:GetChildren()) do
		obj.Parent = script.Parent.Parts
	end
end

local debounce = false

function executeTrigger(t)
	if debounce == false then
		debounce = true
		if t == "L" then
			executeTrigger_CORE(filter(3, 0), "1,1,0", CFrame.Angles(0, 0, math.rad(7.5)))
		elseif t == "R" then
			executeTrigger_CORE(filter(3, 2), "1,1,2", CFrame.Angles(0, 0, math.rad(-7.5)))
		elseif t == "B" then
			executeTrigger_CORE(filter(1, 2), "2,1,1", CFrame.Angles(math.rad(-7.5), 0, 0))
		elseif t == "F" then
			executeTrigger_CORE(filter(1, 0), "0,1,1", CFrame.Angles(math.rad(7.5), 0, 0))
		elseif t == "U" then
			executeTrigger_CORE(filter(2, 2), "1,2,1", CFrame.Angles(0, 0, math.rad(7.5)))
		elseif t == "D" then
			executeTrigger_CORE(filter(2, 0), "1,0,1", CFrame.Angles(0, 0, math.rad(7.5)))
		end
		debounce = false
	end
end

for _, trigger in pairs(script.Parent.Triggers:GetChildren()) do
	trigger.ClickDetector.MouseClick:Connect(function()
		executeTrigger(trigger.Name)
	end)
end

looks like you went wrong where u insert the positions into a table and that possibly carries over to the retrieval of those values as well

yeah, can you help me fix the code tho?

1 Like

Nevermind, already figured it out, the bug was that in function executeTrigger_CORE(selectedParts, skip, move) in tried renaming the parts before putting them back where they belong. New and working script:

parts = {}

local partsCoordsOriginal = {}

function getNewPartName(part)
	local name = partsCoordsOriginal[part.Position]
	
	if name ~= nil then
		return name
	end
	
	local lastDist = 1000000
	local correctData
	for i, _ in pairs(partsCoordsOriginal) do
		local dist = (i - part.Position).Magnitude
		if dist < lastDist then
			lastDist = dist
			correctData = {i, partsCoordsOriginal[i]}
		end
	end
	
	if correctData ~= nil then
		part.Position = correctData[1]
		return correctData[2]
	end
	
	warn("Couldn't find name of part, original name: " .. part.Name)
	return nil
end

function filter(id, value, skip)
	if id < 1 or id > 3 then
		error("Invalid filter ID in Rubik's cube's script.")
	end
	
	if skip == nil then
		skip = {Name = ""}
	end
	
	local result = {}
	for _, part in pairs(parts) do
		if part[id + 1] == value then
			if part[1].Name ~= skip.Name then
				table.insert(result, part[1])
			end
		end
	end
	return result
end

function finalizeResetting()
	for _, part in pairs(script.Parent.Parts:GetChildren()) do
		partsCoordsOriginal[part.Position] = part.Name
		local coords = string.split(part.Name, ",")
		table.insert(parts, {
			part,
			tonumber(coords[1]),
			tonumber(coords[2]),
			tonumber(coords[3])
		})
	end
end

function renameCubeParts(affectedParts)
	for _, part in pairs(affectedParts) do
		part.Name = getNewPartName(part)
	end
	
	parts = {}
	finalizeResetting()
end

function executeTrigger_CORE(selectedParts, skip, move)
	local model = Instance.new("Model", script.Parent)

	for _, obj in pairs(selectedParts) do
		obj.Parent = model
	end

	model.PrimaryPart = model[skip]

	for i = 1, 12 do
		model:SetPrimaryPartCFrame(model:GetPrimaryPartCFrame() * move)
		wait(.01)
	end
	
	for _, obj in pairs(model:GetChildren()) do
		obj.Parent = script.Parent.Parts
	end
	
	renameCubeParts(selectedParts)
end

local debounce = false

function executeTrigger(t)
	if debounce == false then
		debounce = true
		if t == "L" then
			executeTrigger_CORE(filter(3, 0), "1,1,0", CFrame.Angles(0, 0, math.rad(7.5)))
		elseif t == "R" then
			executeTrigger_CORE(filter(3, 2), "1,1,2", CFrame.Angles(0, 0, math.rad(-7.5)))
		elseif t == "B" then
			executeTrigger_CORE(filter(1, 2), "2,1,1", CFrame.Angles(math.rad(-7.5), 0, 0))
		elseif t == "F" then
			executeTrigger_CORE(filter(1, 0), "0,1,1", CFrame.Angles(math.rad(7.5), 0, 0))
		elseif t == "U" then
			executeTrigger_CORE(filter(2, 2), "1,2,1", CFrame.Angles(0, 0, math.rad(7.5)))
		elseif t == "D" then
			executeTrigger_CORE(filter(2, 0), "1,0,1", CFrame.Angles(0, 0, math.rad(7.5)))
		end
		debounce = false
	end
end

for _, trigger in pairs(script.Parent.Triggers:GetChildren()) do
	trigger.ClickDetector.MouseClick:Connect(function()
		executeTrigger(trigger.Name)
	end)
end

finalizeResetting()```
2 Likes