Creating a pattern system (Intermediate)

I wanna make a disco floor pattern system and so far
I’ve got the base system, but it lacks a few things;
(A):The ability to select individual tiles (Major Problem)
(B):The current way I add frames makes the script too big

The pattern template
local Tags = {
		["Line0"] = CollectionService:GetTagged("Line0"),

		["Line1Dot1"] = CollectionService:GetTagged("Line1Dot1"),
		["Line1Dot2"] = CollectionService:GetTagged("Line1Dot2"),

		["Line2Dot1A"] = CollectionService:GetTagged("Line2Dot1A"),
		["Line2Dot2A"] = CollectionService:GetTagged("Line2Dot2A"),

		["Line2Dot1B"] = CollectionService:GetTagged("Line2Dot1B"),
		["Line2Dot2B"] = CollectionService:GetTagged("Line2Dot2B"),

		["Line3A"] = CollectionService:GetTagged("Line3A"),
		["Line3B"] = CollectionService:GetTagged("Line3B"),

		["Line4A"] = CollectionService:GetTagged("Line4A"),
		["Line4B"] = CollectionService:GetTagged("Line4B"),

		["Line5Dot1A"] = CollectionService:GetTagged("Line5Dot1A"),
		["Line5Dot2A"] = CollectionService:GetTagged("Line5Dot2A"),
		["Line5Dot1B"] = CollectionService:GetTagged("Line5Dot1B"),
		["Line5Dot2B"] = CollectionService:GetTagged("Line5Dot2B"),
	}

	local LightData = {
		[1] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[2] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[3] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[4] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[5] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[6] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[7] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[8] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[9] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[10] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[11] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[12] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[13] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[14] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[15] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[16] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[17] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
		},
		[18] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[19] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
		},
		[20] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[21] = {
			--L0
			["Line0"] = Color3.fromRGB(181, 178, 138),

			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[22] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
		},
		[23] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[24] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
		},
		[25] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[26] = {
			--L0
			["Line0"] = Color3.fromRGB(181, 178, 138),

			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[27] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[28] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[29] = {
			--L1
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[30] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[31] = {
			--L0
			["Line0"] = Color3.fromRGB(181, 178, 138),

			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),

			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[32] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),
		},
		[33] = {
			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),
		},
		[34] = {
			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
		},
		[35] = {
			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[36] = {
			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[37] = {
			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[38] = {
			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
		},
		[39] = {
			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),
		},
		[40] = {
			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),
		},
		[41] = {
			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),
		},
		[42] = {
			--L3-4-5
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
		},
		[43] = {
			--L3-4-5
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[44] = {
			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
		},
		[45] = {
			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
		},
		[46] = {
			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
		},
		[47] = {
			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
		},
		[48] = {
			--L0
			["Line0"] = Color3.fromRGB(181, 178, 138),

			--L1
			["Line1Dot1"] = Color3.fromRGB(181, 178, 138),
			["Line1Dot2"] = Color3.fromRGB(181, 178, 138),


			--L2
			["Line2Dot1A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2A"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot1B"] = Color3.fromRGB(113, 53, 131),
			["Line2Dot2B"] = Color3.fromRGB(113, 53, 131),

			--L3-4-5
			["Line5Dot1A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2A"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot1B"] = Color3.fromRGB(255, 0, 0),
			["Line5Dot2B"] = Color3.fromRGB(255, 0, 0),
			["Line4A"] = Color3.fromRGB(255, 255, 255),
			["Line4B"] = Color3.fromRGB(255, 255, 255),
			["Line3A"] = Color3.fromRGB(255, 0, 0),
			["Line3B"] = Color3.fromRGB(255, 0, 0),
		},

Results:

(TL;DR):I wanna make a disco floor pattern system, but the code lacks a few abilitys and looks way too long.

1 Like

You could try generating a 2D array to map grid positions to each tile instance.

The shape of your floor is not a rectangular grid, so I would manually tag a "center" tile to represent (0, 0), then build the index for every other tile using their relative position to the center tile. Assuming each tile is a square of the same size, you might do something along the lines of:

local CollectionService = game:GetService("CollectionService")

local floor = ... -- some model containing the tiles
local center = CollectionService:GetTagged("Center")

local tile_size = center.Size

local grid = {}
for _, tile in floor:GetChildren() do
	local x = math.floor((center.X - tile.X) / tile_size)
	local y = math.floor((center.Y - tile.Y) / tile_size)
	
	if not grid[x] then
		grid[x] = {}
	end
	
	grid[x][y] = tile
end

In the past I’ve seen people design animations for an LED matrix by using an editor which lets them manually paint pixel for a frames, set the frame duration, etc., which then generates the code to play the animation (e.g. C for an Arduino). It should easy to create a similar editor for your Disco floor.

However, this approach seems too manual and time intensive to me. Instead, I would discretize a matrix-valued time series that I crafted programmatically. This way, I would not be manually designing each pixel individually for each frame. For example, if I wanted to animate a red-filled circle that grows from the origin, then I might do:

local anim = {} -- store the animation as a collection of frames stored as matrices 
local frame_count = 100
-- you would use this when playing the animation,
-- but you could use it when constructing each frame to do some interesting effects responsive to how long a frame should last 
local frame_delay = 10 -- uniform frame delay

local R = 0
local R_dt = .05
for frame_id = 1, frame_count do
	local frame = {}
	for x, col in grid do
		frame[x] = {}
		for y, tile in col do
			-- the implicit equation of a circle is: x^2 + y^2 = r^2
			local d = math.sqrt(x^2 + y^2)
			if d <= R then -- inside pixels red
				frame[x][y] = Color3.new(1)
			else -- outside pixels off
				frame[x][y] = Color3.new()
			end
		end
	end
	R += R_dt -- grow radius
	table.insert(anim, frame)
end

To create a more complex animation, you might want to create separate frames for each shape/segment/thing with separate loops then compose them into a single frame in the way you want. (e.g. using alpha blending, taking a convolution, a linear combination.)

This might not work well for you depending on your geometric intuition for parametric functions.

3 Likes

I figured out an easy way to multi-select specific tiles so I can group them for complex animation.

Step(1):Select the desired tiles
Step(2):Paste this into the console

local Parts = "{" for _, v in pairs(game.Selection:Get()) do Parts = Parts..'"'..v.Name..'",' end Parts = Parts..'}' print(Parts)

Step(3):Copy the console output
Step(4):Set a group to the output
Example:

Yeah, using the built-in editor is a good idea. You could write a plugin to generate the code for your selection upon a keypress. Even better, try using the Color Picker to set the colors of the tiles to speed things up up, as the plugin can just color the selection white again after generating the code.

A few suggestions:

  1. The FormattedGroup preprocessing loop is redundant, it’s copying the elements to a new table that will be structured identically.
  2. It’s often more performant to create a table and append each string and use table.concat because the string type is immutable, i.e. concatenating strings requires creating a completely new one, which is particularly detrimental in loops. (Additionally, this will fix the trailing comma!)
  3. Luau also has string interpolation, type gravemarks ( ` ) instead of quotes, then wrap an expression inside a pair of {}.
    Often better than concatenation in particularly simple cases or cases where using table.concat is not worth it. Sometimes string concatenation works best though.
  4. Luau provides a generalized iterator for tables that performs better than a factory like pairs, which you used in some of your code, but throughout your code I see pairs mixed in. Just use the generalized iterator.
  5. The Luau website has a lot of good to know information that is not really explained anywhere else.
local Parts = {}
for _, v in game.Selection:Get() do
    table.insert(Parts, v.Name)
end
-- \{ means use the literal character "{" instead of performing interpolation 
Parts = `\{ { table.concat(Parts, ",") } \}` 
print(Parts)
  1. Moving task.wait() into the loop body makes the code more self documented compared to putting it in the loop conditional. It’s not subtle that the conditional is executed before the first iteration, i.e. the wait occurs before the first iteration, but it’s less explicit about the scheduling.
-- immediately clear when the wait happens 
while true do
    task.wait()
end

-- the conditional is executed before the first iteration; less explicit
while task.wait() do
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.