RoboCatz.com
About FLL | Navigation | Playbook | Strategy | Models | Techniques | RobotC | Programming | Robot News |

--This is the genericShapes module script in the ReplicatedStorage space

--[[
Updated: 5/19/2023

Location of this file: ReplicatedStorage.genericShapes (module)
This module will be used to create generic shapes
Installation: Create a ModuleScript in the ReplicatedStorage folder.  Name the script: genericShapes

The functions shown below allow for a variety of methods for creating objects.  Each function will have multiple 
options for arguments passed into the function.  All of the shape functions will take from zero to some number of arguments.

Example Usage: 

*********************************
** 2D Shapes:

local s1 = s.square()  -- create a default square
local s1 = s.square(5)  -- create a square with sides of length 5 at the default location
local s1 = s.square(5, 0.4) -- create a square with sides of 5 and a thickness of 0.4 at the default location
local s1 = s.square(-10, 6, -15) -- create a square at the location of x=-10, y=6, z=-15
local s1 = s.square(0, 5, -15, 10) -- create a square at the location of 0,5,-15 with the size of 10
local s1 = s.square(0, 5, -15, 10, 0.5) -- create a square at the location of 0,5,-15 with the size of 10 and thickness of 0.5
local s1 = s.square(0, 5, -15, 10, 0.5) -- create a square at the location of 0,5,-15 with the size of 10 and thickness of 0.5
local s1 = s.square(0, 5, -15, 10, 0.5, Color3.new(1, 1, 0)) -- create a square ... with the color specified as a Color3 object
local s1 = s.square(0, 5, -15, 10, 0.5, "red") -- create a square ... with the color specified as a string
local s1 = s.square({ x=0, y=5, z=-15, size=10, thickness=0.5, color="red", luminosity=15, luminosityHue=Color3.new(1,1,0)})

local s1 = s.circle()  -- create a default circle
local s1 = s.circle(5)  -- create a circle with diameter of length 5 at the default location
local s1 = s.circle(5, 0.4) -- create a circle with diameter of 5 and a thickness of 0.4 at the default location
local s1 = s.circle(-10, 6, -15) -- create a circle at the location of x=-10, y=6, z=-15
local s1 = s.circle(0, 5, -15, 10) -- create a circle at the location of 0,5,-15 with the size of 10
local s1 = s.circle(0, 5, -15, 10, 0.5) -- create a circle at the location of 0,5,-15 with the size of 10 and thickness of 0.5
local s1 = s.circle(0, 5, -15, 10, 0.5) -- create a circle at the location of 0,5,-15 with the size of 10 and thickness of 0.5
local s1 = s.circle(0, 5, -15, 10, 0.5, Color3.new(1, 1, 0)) -- create a circle ... with the color specified as a Color3 object
local s1 = s.circle(0, 5, -15, 10, 0.5, "red") -- create a circle ... with the color specified as a string
local s1 = s.circle({ x=0, y=5, z=-15, size=10, thickness=0.5, color="red", luminosityValue=20, luminosityHue=Color3.new(1,1,0)})

local s1 = s.disc()  -- create a default disc
local s1 = s.disc(5)  -- create a disc with diameter of length 5 at the default location
local s1 = s.disc(5, 0.4) -- create a disc with diameter of 5 and a thickness of 0.4 at the default location
local s1 = s.disc(-10, 6, -15) -- create a disc at the location of x=-10, y=6, z=-15
local s1 = s.disc(0, 5, -15, 10) -- create a disc at the location of 0,5,-15 with the size of 10
local s1 = s.disc(0, 5, -15, 10, 0.5) -- create a disc at the location of 0,5,-15 with the size of 10 and thickness of 0.5
local s1 = s.disc(0, 5, -15, 10, 0.5, Color3.new(1, 1, 0)) -- create a disc ... with the color specified as a Color3 object
local s1 = s.disc(0, 5, -15, 10, 0.5, "red") -- create a disc ... with the color specified as a string
local s1 = s.disc(0, 5, -15, 10, 0.5, "red", Enum.Material.Foil) -- create a disc ... with the Material specified as an Enum
local s1 = s.disc({ x=0, y=5, z=-15, size=10, thickness=0.5, color="red", luminosityValue=10, luminosityHue=Color3.new(1,1,0)})


local s1 = s.panel()  -- create a default panel
local s1 = s.panel(5)  -- create a panel with sides of length 5 at the default location
local s1 = s.panel(5, 0.4) -- create a panel with sides of 5 and a thickness of 0.4 at the default location
local s1 = s.panel(-10, 6, -15) -- create a panel at the location of x=-10, y=6, z=-15
local s1 = s.panel(0, 5, -15, 10) -- create a panel at the location of 0,5,-15 with the size of 10
local s1 = s.panel(0, 5, -15, 10, 0.5) -- create a panel at the location of 0,5,-15 with the size of 10 and thickness of 0.5
local s1 = s.panel(0, 5, -15, 10, 0.5) -- create a panel at the location of 0,5,-15 with the size of 10 and thickness of 0.5
local s1 = s.panel(0, 5, -15, 10, 0.5, Color3.new(1, 1, 0)) -- create a panel ... with the color specified as a Color3 object
local s1 = s.panel(0, 5, -15, 10, 0.5, "red") -- create a panel ... with the color specified as a string
local s1 = s.panel(0, 5, -15, 10, 0.5, "red", Enum.Material.Foil) -- create a panel ... with a foil material
local s1 = s.panel({ x=0, y=5, z=-15, size=10, thickness=0.5, color="red", rotateBy=Vector3.new(0,0,90)})

*********************************
** 3D Shapes:

local s1 = s.cube()  -- create a default cube
local s1 = s.cube(5)  -- create a cube with sides of length 5 at the default location
local s1 = s.cube(5, 0.4) -- create a cube with sides of 5 and a thickness of 0.4 at the default location
local s1 = s.cube(-10, 6, -15) -- create a cube at the location of x=-10, y=6, z=-15
local s1 = s.cube(0, 5, -15, 7) -- create a cube at the location of 0,5,-15 with the size of 7
local s1 = s.cube(0, 5, -15, 7, Color3.new(1, 1, 0)) -- create a cube ... with the color specified as a Color3 object
local s1 = s.cube(0, 5, -15, 7, "red") -- create a cube ... with the color specified as a string
local s1 = s.cube(0, 5, -15, 7, "red", Enum.Material.Foil) -- create a cube ... with a foil material

local s1 = s.sphere()  -- create a default sphere
local s1 = s.sphere(5)  -- create a sphere with sides of length 5 at the default location
local s1 = s.sphere(5, 0.4) -- create a sphere with sides of 5 and a thickness of 0.4 at the default location
local s1 = s.sphere(-10, 6, -15) -- create a sphere at the location of x=-10, y=6, z=-15
local s1 = s.sphere(0, 5, -15, 7) -- create a sphere at the location of 0,5,-15 with the size of 7
local s1 = s.sphere(0, 5, -15, 7, Color3.new(1, 1, 0)) -- create a sphere ... with the color specified as a Color3 object
local s1 = s.sphere(0, 5, -15, 7, "red") -- create a sphere ... with the color specified as a string
local s1 = s.sphere(0, 5, -15, 7, Color3.new(0.631373, 0.52549, 0.407843),Enum.Material.Wood) -- create a sphere ... with a wood material

*********************************
** Properties of Shapes:
You can create shapes with different properties by passing a 'dictionary' (aka Object).  Examples shown below.  Although these examples
show just one property in each dictionary, you may combine multiple properties in a single dictionary by separating them with commas.
{ anchored = False }
{ size = 10 }
{ size = Vector3.new(10, 15, 20) }
{ position = Vector3.new(10, 15, 20) }
{ transparency = 0.3 }
{ opacity = 0.7 }
{ reflectance = 0.7 }
{ rotateBy = Vector3.new(10, 15, 20) }
{ material = "wood" }
{ material = Enum.Material.Plastic }
{ color = Color3.new(math. Random(), 0.456, 1 ) }
{ color = "green }

Examples of usage:
s.sphere({ x=0, y=5, z=-15, size=10, color="red", opacity=0.5 })
s.sphere({ x=-5, y=5, z=-5, anchored=False, size=1, color="blue", opacity=0.8 })
s.cube({ x=10, y=5, z=-15, anchored=False, size=1, color="yellow", reflectance=1 })
s.disc({ x=-10, y=10, z=-5, size=3, color="yellow", reflectance=1, rotateBy(math.random()*90, math.random()*90, math.random()*90) })
s.square({ x=20, y=10, z=-25, size=7, color="brown", material=Enum.Material.Foil, reflectance=1 })

]]

local shapes = {}

local defaultColor = Color3.new(0.0117647, 0.984314, 1)
local defaultBorderThickness = 0.5

local colorName={
	["pink"]={["RGB"]="FFC0CB", ["DEC"]={255,192,203}},
	["lightpink"]={["RGB"]="FFB6C1", ["DEC"]={255,182,193}},
	["hotpink"]={["RGB"]="FF69B4", ["DEC"]={255,105,180}},
	["deeppink"]={["RGB"]="FF1493", ["DEC"]={255,20,147}},
	["palevioletred"]={["RGB"]="DB7093", ["DEC"]={219,112,147}},
	["mediumvioletred"]={["RGB"]="C71585", ["DEC"]={199,21,133}},
	["lightsalmon"]={["RGB"]="FFA07A", ["DEC"]={255,160,122}},
	["salmon"]={["RGB"]="FA8072", ["DEC"]={250,128,114}},
	["darksalmon"]={["RGB"]="E9967A", ["DEC"]={233,150,122}},
	["lightcoral"]={["RGB"]="F08080", ["DEC"]={240,128,128}},
	["indianred"]={["RGB"]="CD5C5C", ["DEC"]={205,92,92}},
	["crimson"]={["RGB"]="DC143C", ["DEC"]={220,20,60}},
	["firebrick"]={["RGB"]="B22222", ["DEC"]={178,34,34}},
	["darkred"]={["RGB"]="8B0000", ["DEC"]={139,0,0}},
	["red"]={["RGB"]="FF0000", ["DEC"]={255,0,0}},
	["orangered"]={["RGB"]="FF4500", ["DEC"]={255,69,0}},
	["tomato"]={["RGB"]="FF6347", ["DEC"]={255,99,71}},
	["coral"]={["RGB"]="FF7F50", ["DEC"]={255,127,80}},
	["darkorange"]={["RGB"]="FF8C00", ["DEC"]={255,140,0}},
	["orange"]={["RGB"]="FFA500", ["DEC"]={255,165,0}},
	["yellow"]={["RGB"]="FFFF00", ["DEC"]={255,255,0}},
	["lightyellow"]={["RGB"]="FFFFE0", ["DEC"]={255,255,224}},
	["lemonchiffon"]={["RGB"]="FFFACD", ["DEC"]={255,250,205}},
	["lightgoldenrodyellow"]={["RGB"]="FAFAD2", ["DEC"]={250,250,210}},
	["papayawhip"]={["RGB"]="FFEFD5", ["DEC"]={255,239,213}},
	["moccasin"]={["RGB"]="FFE4B5", ["DEC"]={255,228,181}},
	["peachpuff"]={["RGB"]="FFDAB9", ["DEC"]={255,218,185}},
	["palegoldenrod"]={["RGB"]="EEE8AA", ["DEC"]={238,232,170}},
	["khaki"]={["RGB"]="F0E68C", ["DEC"]={240,230,140}},
	["darkkhaki"]={["RGB"]="BDB76B", ["DEC"]={189,183,107}},
	["gold"]={["RGB"]="FFD700", ["DEC"]={255,215,0}},
	["cornsilk"]={["RGB"]="FFF8DC", ["DEC"]={255,248,220}},
	["blanchedalmond"]={["RGB"]="FFEBCD", ["DEC"]={255,235,205}},
	["bisque"]={["RGB"]="FFE4C4", ["DEC"]={255,228,196}},
	["navajowhite"]={["RGB"]="FFDEAD", ["DEC"]={255,222,173}},
	["wheat"]={["RGB"]="F5DEB3", ["DEC"]={245,222,179}},
	["burlywood"]={["RGB"]="DEB887", ["DEC"]={222,184,135}},
	["tan"]={["RGB"]="D2B48C", ["DEC"]={210,180,140}},
	["rosybrown"]={["RGB"]="BC8F8F", ["DEC"]={188,143,143}},
	["sandybrown"]={["RGB"]="F4A460", ["DEC"]={244,164,96}},
	["goldenrod"]={["RGB"]="DAA520", ["DEC"]={218,165,32}},
	["darkgoldenrod"]={["RGB"]="B8860B", ["DEC"]={184,134,11}},
	["peru"]={["RGB"]="CD853F", ["DEC"]={205,133,63}},
	["chocolate"]={["RGB"]="D2691E", ["DEC"]={210,105,30}},
	["saddlebrown"]={["RGB"]="8B4513", ["DEC"]={139,69,19}},
	["sienna"]={["RGB"]="A0522D", ["DEC"]={160,82,45}},
	["brown"]={["RGB"]="A52A2A", ["DEC"]={165,42,42}},
	["maroon"]={["RGB"]="800000", ["DEC"]={128,0,0}},
	["darkolivegreen"]={["RGB"]="556B2F", ["DEC"]={85,107,47}},
	["olive"]={["RGB"]="808000", ["DEC"]={128,128,0}},
	["olivedrab"]={["RGB"]="6B8E23", ["DEC"]={107,142,35}},
	["yellowgreen"]={["RGB"]="9ACD32", ["DEC"]={154,205,50}},
	["limegreen"]={["RGB"]="32CD32", ["DEC"]={50,205,50}},
	["lime"]={["RGB"]="00FF00", ["DEC"]={0,255,0}},
	["lawngreen"]={["RGB"]="7CFC00", ["DEC"]={124,252,0}},
	["chartreuse"]={["RGB"]="7FFF00", ["DEC"]={127,255,0}},
	["greenyellow"]={["RGB"]="ADFF2F", ["DEC"]={173,255,47}},
	["springgreen"]={["RGB"]="00FF7F", ["DEC"]={0,255,127}},
	["mediumspringgreen"]={["RGB"]="00FA9A", ["DEC"]={0,250,154}},
	["lightgreen"]={["RGB"]="90EE90", ["DEC"]={144,238,144}},
	["palegreen"]={["RGB"]="98FB98", ["DEC"]={152,251,152}},
	["darkseagreen"]={["RGB"]="8FBC8F", ["DEC"]={143,188,143}},
	["mediumaquamarine"]={["RGB"]="66CDAA", ["DEC"]={102,205,170}},
	["mediumseagreen"]={["RGB"]="3CB371", ["DEC"]={60,179,113}},
	["seagreen"]={["RGB"]="2E8B57", ["DEC"]={46,139,87}},
	["forestgreen"]={["RGB"]="228B22", ["DEC"]={34,139,34}},
	["green"]={["RGB"]="008000", ["DEC"]={0,128,0}},
	["darkgreen"]={["RGB"]="006400", ["DEC"]={0,100,0}},
	["aqua"]={["RGB"]="00FFFF", ["DEC"]={0,255,255}},
	["cyan"]={["RGB"]="00FFFF", ["DEC"]={0,255,255}},
	["lightcyan"]={["RGB"]="E0FFFF", ["DEC"]={224,255,255}},
	["paleturquoise"]={["RGB"]="AFEEEE", ["DEC"]={175,238,238}},
	["aquamarine"]={["RGB"]="7FFFD4", ["DEC"]={127,255,212}},
	["turquoise"]={["RGB"]="40E0D0", ["DEC"]={64,224,208}},
	["mediumturquoise"]={["RGB"]="48D1CC", ["DEC"]={72,209,204}},
	["darkturquoise"]={["RGB"]="00CED1", ["DEC"]={0,206,209}},
	["lightseagreen"]={["RGB"]="20B2AA", ["DEC"]={32,178,170}},
	["cadetblue"]={["RGB"]="5F9EA0", ["DEC"]={95,158,160}},
	["darkcyan"]={["RGB"]="008B8B", ["DEC"]={0,139,139}},
	["teal"]={["RGB"]="008080", ["DEC"]={0,128,128}},
	["lightsteelblue"]={["RGB"]="B0C4DE", ["DEC"]={176,196,222}},
	["powderblue"]={["RGB"]="B0E0E6", ["DEC"]={176,224,230}},
	["lightblue"]={["RGB"]="ADD8E6", ["DEC"]={173,216,230}},
	["skyblue"]={["RGB"]="87CEEB", ["DEC"]={135,206,235}},
	["lightskyblue"]={["RGB"]="87CEFA", ["DEC"]={135,206,250}},
	["deepskyblue"]={["RGB"]="00BFFF", ["DEC"]={0,191,255}},
	["dodgerblue"]={["RGB"]="1E90FF", ["DEC"]={30,144,255}},
	["cornflowerblue"]={["RGB"]="6495ED", ["DEC"]={100,149,237}},
	["steelblue"]={["RGB"]="4682B4", ["DEC"]={70,130,180}},
	["royalblue"]={["RGB"]="041690", ["DEC"]={65,105,225}},
	["blue"]={["RGB"]="0000FF", ["DEC"]={0,0,255}},
	["mediumblue"]={["RGB"]="0000CD", ["DEC"]={0,0,205}},
	["darkblue"]={["RGB"]="00008B", ["DEC"]={0,0,139}},
	["navy"]={["RGB"]="000080", ["DEC"]={0,0,128}},
	["midnightblue"]={["RGB"]="191970", ["DEC"]={25,25,112}},
	["lavender"]={["RGB"]="E6E6FA", ["DEC"]={230,230,250}},
	["thistle"]={["RGB"]="D8BFD8", ["DEC"]={216,191,216}},
	["plum"]={["RGB"]="DDA0DD", ["DEC"]={221,160,221}},
	["violet"]={["RGB"]="EE82EE", ["DEC"]={238,130,238}},
	["orchid"]={["RGB"]="DA70D6", ["DEC"]={218,112,214}},
	["fuchsia"]={["RGB"]="FF00FF", ["DEC"]={255,0,255}},
	["magenta"]={["RGB"]="FF00FF", ["DEC"]={255,0,255}},
	["mediumorchid"]={["RGB"]="BA55D3", ["DEC"]={186,85,211}},
	["mediumpurple"]={["RGB"]="9370DB", ["DEC"]={147,112,219}},
	["blueviolet"]={["RGB"]="8A2BE2", ["DEC"]={138,43,226}},
	["darkviolet"]={["RGB"]="9400D3", ["DEC"]={148,0,211}},
	["darkorchid"]={["RGB"]="9932CC", ["DEC"]={153,50,204}},
	["darkmagenta"]={["RGB"]="8B008B", ["DEC"]={139,0,139}},
	["purple"]={["RGB"]="800080", ["DEC"]={128,0,128}},
	["indigo"]={["RGB"]="4B0082", ["DEC"]={75,0,130}},
	["darkslateblue"]={["RGB"]="483D8B", ["DEC"]={72,61,139}},
	["slateblue"]={["RGB"]="6A5ACD", ["DEC"]={106,90,205}},
	["mediumslateblue"]={["RGB"]="7B68EE", ["DEC"]={123,104,238}},
	["white"]={["RGB"]="FFFFFF", ["DEC"]={255,255,255}},
	["snow"]={["RGB"]="FFFAFA", ["DEC"]={255,250,250}},
	["honeydew"]={["RGB"]="F0FFF0", ["DEC"]={240,255,240}},
	["mintcream"]={["RGB"]="F5FFFA", ["DEC"]={245,255,250}},
	["azure"]={["RGB"]="F0FFFF", ["DEC"]={240,255,255}},
	["aliceblue"]={["RGB"]="F0F8FF", ["DEC"]={240,248,255}},
	["ghostwhite"]={["RGB"]="F8F8FF", ["DEC"]={248,248,255}},
	["whitesmoke"]={["RGB"]="F5F5F5", ["DEC"]={245,245,245}},
	["seashell"]={["RGB"]="FFF5EE", ["DEC"]={255,245,238}},
	["beige"]={["RGB"]="F5F5DC", ["DEC"]={245,245,220}},
	["oldlace"]={["RGB"]="FDF5E6", ["DEC"]={253,245,230}},
	["floralwhite"]={["RGB"]="FFFAF0", ["DEC"]={255,250,240}},
	["ivory"]={["RGB"]="FFFFF0", ["DEC"]={255,255,240}},
	["antiquewhite"]={["RGB"]="FAEBD7", ["DEC"]={250,235,215}},
	["linen"]={["RGB"]="FAF0E6", ["DEC"]={250,240,230}},
	["lavenderblush"]={["RGB"]="FFF0F5", ["DEC"]={255,240,245}},
	["mistyrose"]={["RGB"]="FFE4E1", ["DEC"]={255,228,225}},
	["gainsboro"]={["RGB"]="DCDCDC", ["DEC"]={220,220,220}},
	["lightgrey"]={["RGB"]="D3D3D3", ["DEC"]={211,211,211}},
	["silver"]={["RGB"]="C0C0C0", ["DEC"]={192,192,192}},
	["darkgray"]={["RGB"]="A9A9A9", ["DEC"]={169,169,169}},
	["gray"]={["RGB"]="808080", ["DEC"]={128,128,128}},
	["dimgray"]={["RGB"]="696969", ["DEC"]={105,105,105}},
	["lightslategray"]={["RGB"]="778899", ["DEC"]={119,136,153}},
	["slategray"]={["RGB"]="708090", ["DEC"]={112,128,144}},
	["darkslategray"]={["RGB"]="2F4F4F", ["DEC"]={47,79,79}},
	["black"]={["RGB"]="000000", ["DEC"]={0,0,0}}
}

local materialNames = {
	"Plastic",
	"Wood",
	"Slate",
	"Concrete",
	"CorrodedMetal",
	"DiamondPlate",
	"Foil",
	"Grass",
	"Ice",
	"Marble",
	"Granite",
	"Brick",
	"Pebble",
	"Sand",
	"Fabric",
	"SmoothPlastic",
	"Metal",
	"WoodPlanks",
	"Cobblestone",
	"Air",
	"Water",
	"Rock",
	"Glacier",
	"Snow",
	"Sandstone",
	"Mud",
	"Basalt",
	"Ground",
	"CrackedLava",
	"Neon",
	"Glass",
	"Asphalt",
	"LeafyGrass",
	"Salt",
	"Limestone",
	"Pavement",
	"ForceField"
}



--This function returns a string value
function shapes.helloWorld()
	return "Hello World"	
end

--[[
CUBE ------------------------------------------------------------------
This function creates a cube
A variable number of arguments (from none to 6) can be provided:
 size
 x, y, z
 x, y, z, size
 x, y, z, size, color
 x, y, z, size, color, material
The non-numeric arguments will be of specific types: string, Color3, Enum.Material.  Because these arguments have specific types, 
the function will examine the arguments, determine their type, and then use them as specific parameters for the function based on the argument type.
The non-numeric arguments can be placed in any order in any position of the arguments list
For examples:
  color, material, size
  size, color, material
  color, x, y, z
  x, y, z, color
The numeric arguments will always be interpreted as size if only 1 argument and x, y, z if 3 or more arguments.
]]
function shapes.cube(...)
	local arguments = table.pack(...)
	local size = 10 -- Default size if none specified
	local x, y, z = 0, 0, -15
	local needToCreateYvalue = true
	local color = defaultColor
	local material = Enum.Material.Plastic
	local mainPart = Instance.new("Part")
	local luminosityValue = 30
	local luminosityHue = Color3.new(1, 1, 1)
	local luminosityType = "PointLight"
	local luminosityRange = 20
	mainPart.Anchored = true
	mainPart.Shape = Enum.PartType.Block
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.Transparency = 0
	mainPart.Reflectance = 0.6
	mainPart.Parent = workspace
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local workingNumber = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "table" then
			for key, value in pairs(arguments[i]) do
				--print(key)
				local lkey = string.lower(key)
				if lkey == "anchored" then mainPart.Anchored = value end
				if lkey == "x" then x = value end
				if lkey == "y" then	y,needToCreateYvalue = value, false	end
				if lkey == "z" then z = value end
				if lkey == "size" or lkey == "width" or lkey == "height" then -- Any of these keys can be used and they will all result in setting the scalar value: size 
					size = value                    -- Default size type should be a number.  If a vector, then use the X value from the vector.
					if typeof(value) == "Vector3" then size = value.X end
				end
				if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
				if lkey == "transparency" then mainPart.Transparency = value end
				if lkey == "opacity" then mainPart.Transparency = 1 - value end
				if lkey == "reflectance" then mainPart.Reflectance = value end
				if lkey == "rotateby" then mainPart.Orientation = value end
				if lkey == "material" then material = value end
				if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
				if lkey == "luminosityrange" then luminosityRange = value end
				if lkey == "luminosityhue" then 
					if typeof(value) == "Color3" then luminosityHue = value end
					if typeof(value) == "string" then
						local luminosityColor = string.lower(value)
						local red = colorName[luminosityColor]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[luminosityColor]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[luminosityColor]["DEC"][3]/255   --rescale from 0-255 to 0-1
						luminosityHue = Color3.new(red, green, blue)
					end
				end
				if lkey == "luminositytype" then luminosityType = value	end
				if lkey == "color" then
					if typeof(value) == "Color3" then color = value end
					if typeof(value) == "string" then
						color = string.lower(value)
						local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
						color = Color3.new(red, green, blue)
					end
				end
			end
			for key, value in pairs(arguments[i]) do  -- Check to see if there is any luminosity to this object
				local lkey = string.lower(key)
				if lkey == "luminosity" or lkey == "luminosityvalue" or lkey == "luminosityhue" or lkey == "luminosityrange" or lkey == "luminositytype" then -- If there is luminosity, then install the surface light
					--print(`Creating luminosity: {luminosityType} {luminosityHue} {luminosityValue}`)
					local lightOfPart = Instance.new(luminosityType)
					lightOfPart.Color = luminosityHue
					lightOfPart.Brightness = luminosityValue
					lightOfPart.Range = luminosityRange
					lightOfPart.Parent = mainPart
				end
			end
		end
		if typeof(arguments[i]) == "Color3" then 
			color = arguments[i] 
		end
		if typeof(arguments[i]) == "string" then
			local color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
		if typeof(arguments[i]) == "EnumItem" then mainPart.Material = arguments[i] end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				size = arguments[i]
				y = size/2
			else
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y,needToCreateYvalue = arguments[i],false end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
			end
		end
	end
	if numNumericArguments == 0 and needToCreateYvalue == true then	y = size/2 end
	mainPart.Color = color
	mainPart.Size = Vector3.new(size,size,size)
	mainPart.Position = Vector3.new(x,y,z)
	return mainPart
end

--[[
PANEL ------------------------------------------------------------------
This function creates a panel
A variable number of arguments (from none to 6) can be provided:
 size
 width, height
 width, height, thickness
 x, y, z
 x, y, z, size
 x, y, z, width, height
 x, y, z, width, height, thickness
 x, y, z, width, height, size, thickness, color
 x, y, z, width, height, size, thickness, color, material
The non-numeric arguments will be of specific types: string, Color3, Enum.Material.  Because these arguments have specific types, 
the function will examine the arguments, determine their type, and then use them as specific parameters for the function based on the argument type.
The non-numeric arguments can be placed in any order in any position of the arguments list
For examples:
  color, material, width, height
  size, color, material
  color, x, y, z
  x, y, z, material, color
The numeric arguments will always be interpreted as size if only 1 argument and x, y, z if 3 or more arguments.
]]		
function shapes.panel(...)
	local arguments = table.pack(...)
	local width = 10  -- Default size if none specified
	local height = 10 -- Default size if none specified
	local thickness = 0.1
	local x, y, z = 0, 0, -15
	local needToCreateYvalue = true
	local color = defaultColor
	local orientation = Vector3.new(90, 0, 0)
	local material = Enum.Material.Plastic
	if thickness < 0.1 then thickness = 0.1 end	
	local mainPart = Instance.new("Part")
	local luminosityValue = 30
	local luminosityHue = Color3.new(1, 1, 1)
	local luminosityType = "PointLight"
	local luminosityRange = 20
	mainPart.Anchored = true
	mainPart.Shape = Enum.PartType.Block
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.FrontSurface = Enum.SurfaceType.Smooth
	mainPart.BackSurface = Enum.SurfaceType.Smooth
	mainPart.LeftSurface = Enum.SurfaceType.Smooth
	mainPart.RightSurface = Enum.SurfaceType.Smooth
	mainPart.Transparency = 0
	mainPart.Reflectance = 0
	mainPart.Parent = workspace
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local numVector3Arguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "Vector3" then numVector3Arguments += 1 end
	end
	local workingNumber = 0
	local workingVector = 0
	for i = 1, #arguments do
		--print(typeof(arguments[i]))
		if typeof(arguments[i]) == "table" then
			for key, value in pairs(arguments[i]) do
				--print(key)
				local lkey = string.lower(key)
				if lkey == "anchored" then mainPart.Anchored = value end
				if lkey == "x" then x = value end
				if lkey == "y" then	y,needToCreateYvalue = value, false end
				if lkey == "z" then z = value end
				if lkey == "size" then -- Any of these keys can be used and they will all result in setting the scalar value: size 
					width = value                     -- Default size type should be a number.  If a vector, then use the X value from the vector.
					height = value                    -- Default size type should be a number.  If a vector, then use the X value from the vector.
					if typeof(value) == "Vector3" then width,height,thickness = value.X,value.Y,value.Z end
				end
				if lkey == "width" then	width = value end
				if lkey == "height" then height = value end
				if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
				if lkey == "thickness" then	thickness = value end
				if lkey == "transparency" then mainPart.Transparency = value end
				if lkey == "opacity" then mainPart.Transparency = 1 - value end
				if lkey == "reflectance" then mainPart.Reflectance = value end
				if lkey == "rotateby" then orientation = value end
				if lkey == "material" then material = value end
				if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
				if lkey == "luminosityrange" then luminosityRange = value end
				if lkey == "luminosityhue" then 
					if typeof(value) == "Color3" then luminosityHue = value end
					if typeof(value) == "string" then
						local luminosityColor = string.lower(value)
						local red = colorName[luminosityColor]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[luminosityColor]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[luminosityColor]["DEC"][3]/255   --rescale from 0-255 to 0-1
						luminosityHue = Color3.new(red, green, blue)
					end
				end
				if lkey == "luminositytype" then luminosityType = value	end
				if lkey == "color" then 
					if typeof(value) == "Color3" then color = value end
					if typeof(value) == "string" then
						color = string.lower(value)
						local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
						color = Color3.new(red, green, blue)
					end
				end
			end
			for key, value in pairs(arguments[i]) do  -- Check to see if there is any luminosity to this object
				local lkey = string.lower(key)
				if lkey == "luminosity" or lkey == "luminosityvalue" or lkey == "luminosityhue" or lkey == "luminosityrange" or lkey == "luminositytype" then -- If there is luminosity, then install the surface light
					local lightOfPart = Instance.new(luminosityType)
					lightOfPart.Color = luminosityHue
					lightOfPart.Brightness = luminosityValue
					lightOfPart.Range = luminosityRange
					lightOfPart.Parent = mainPart
				end
			end
		end
		if typeof(arguments[i]) == "Vector3" then
			if numVector3Arguments == 2 then
				-- first vector is x,y,z
				-- second vector is width, height, length
			end
			mainPart.Color = arguments[i]
		end
		if typeof(arguments[i]) == "Color3" then color = arguments[i] end
		if typeof(arguments[i]) == "string" then
			local color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
		if typeof(arguments[i]) == "EnumItem" then material = arguments[i] end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				width = arguments[i]
				height = arguments[i]
				y,needToCreateYvalue = height/2, false
			elseif numNumericArguments == 3 then
				workingNumber += 1
				if workingNumber == 1 then width = arguments[i] end
				if workingNumber == 2 then height = arguments[i] end
				if workingNumber == 3 then thickness = arguments[i] end
				y,needToCreateYvalue = height/2, false
			elseif numNumericArguments == 4 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then 
					width = arguments[i] 
					height = arguments[i] 
				end
			elseif numNumericArguments == 5 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then width = arguments[i] end
				if workingNumber == 5 then height = arguments[i] end
			elseif numNumericArguments == 6 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then width = arguments[i] end
				if workingNumber == 5 then height = arguments[i] end
				if workingNumber == 6 then thickness = arguments[i] end
			else
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then 
					width = arguments[i]
					height = arguments[i]
				end
			end
		end
	end
	if numNumericArguments == 0 and needToCreateYvalue == true then y = width/2 end
	mainPart.Material = material
	mainPart.Color = color
	mainPart.Size = Vector3.new(width,thickness,height)
	mainPart.Orientation = orientation
	mainPart.Position = Vector3.new(x,y,z)
	return mainPart
end

--[[
WALL ------------------------------------------------------------------
This function creates a wall from x1,y1,z1 to x2,y2,z2
A variable number of arguments (from none to 6) can be provided:
 size
 width, height
 width, height, thickness
 x1, y1, z1, x2, y3, z2
 Vector3_1, Vector3_2
 x1, y1, z1, x2, y3, z2, color
 Vector3_1, Vector3_2, color
 x1, y1, z1, x2, y3, z2, color, material
 Vector3_1, Vector3_2, color, material
The non-numeric arguments will be of specific types: string, Color3, Enum.Material.  Because these arguments have specific types, 
the function will examine the arguments, determine their type, and then use them as specific parameters for the function based on the argument type.
The non-numeric arguments can be placed in any order in any position of the arguments list
For examples:
  s.wall(Vector3.new(-10,0,-15), Vector3.new(10,10,-36), 2)
  s.wall(Vector3.new(-10,0,-15), Vector3.new(10,10,-36), Enum.Material.Brick, Color3.new(1, 0.545098, 0.545098), 2)
  color, material, width, height
  size, color, material
  color, Vector3_1, Vector3_2
The numeric arguments will always be interpreted as size if only 1 argument and x, y, z if 3 or more arguments.
]]		
function shapes.wall(...)
	local arguments = table.pack(...)
	local width = 10  -- Default size if none specified
	local height = 10 -- Default size if none specified
	local thickness = 0.1
	local v1 = Vector3.new(-10, 0, -15)
	local v2 = Vector3.new(10, 10, -15)
	local color = defaultColor
	local material = Enum.Material.Plastic
	if thickness < 0.1 then thickness = 0.1 end	
	local mainPart = Instance.new("Part")
	mainPart.Anchored = true
	mainPart.Shape = Enum.PartType.Block
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.FrontSurface = Enum.SurfaceType.Smooth
	mainPart.BackSurface = Enum.SurfaceType.Smooth
	mainPart.LeftSurface = Enum.SurfaceType.Smooth
	mainPart.RightSurface = Enum.SurfaceType.Smooth
	mainPart.Transparency = 0
	mainPart.Reflectance = 0
	mainPart.Parent = workspace
	color = defaultColor

	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local numVector3Arguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "Vector3" then numVector3Arguments += 1 end
	end
	local workingNumber = 0
	local workingVector = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "Vector3" then
			if numVector3Arguments == 2 then
				workingVector += 1
				if workingVector == 1 then v1 = arguments[i] end  -- first vector is x1,y1,z1
				if workingVector == 2 then v2 = arguments[i] end  -- second vector is x2,y2,z2
			end
		end
		if typeof(arguments[i]) == "Color3" then
			color = arguments[i]
		end
		if typeof(arguments[i]) == "string" then
			color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
		if typeof(arguments[i]) == "EnumItem" then
			mainPart.Material = arguments[i]
		end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				thickness = arguments[i]
			end
		end
	end
	mainPart.Color = color
	mainPart.Size = Vector3.new(math.sqrt((v1.X-v2.X)*(v1.X-v2.X)+(v1.Z-v2.Z)*(v1.Z-v2.Z)),math.abs(v1.Y-v2.Y),thickness)
	mainPart.Orientation = Vector3.new(0, 180*math.atan2(v1.Z-v2.Z, v2.X-v1.X)/math.pi, 0)  -- This formula must be: atan2(z1-z2, x2-x1)
	mainPart.Position = Vector3.new((v1.X+v2.X)/2,(v1.Y+v2.Y)/2,(v1.Z+v2.Z)/2)
	return mainPart
end

--[[
-- SQUARE ------------------------------------------------------------------
-- This function creates a square
-- A variable number of arguments (from none to 6) can be provided:
-- size
-- size, thickness
-- x, y, z
-- x, y, z, size
-- x, y, z, size, thickness
-- x, y, z, size, thickness, color
-- x, y, z, size, thickness, color, material
The non-numeric arguments will be of specific types: string, Color3, Enum.Material.  Because these arguments have specific types, 
the function will examine the arguments, determine their type, and then use them as specific parameters for the function based on the argument type.
The non-numeric arguments can be placed in any order in any position of the arguments list
For examples:
  color, material, size, thickness
  size, color, material
  color, x, y, z
  x, y, z, material, color
The numeric arguments will always be interpreted as size if only 1 argument and x, y, z if 3 or more arguments.
]]
function shapes.square(...)
	local arguments = table.pack(...)
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local size = 10 -- Default size if none specified
	local thickness = defaultBorderThickness
	local x, y, z = 0, 0, -15
	local needToCreateYvalue = true
	local color = defaultColor
	local orientation = Vector3.new(90, 0, 0)
	local material = Enum.Material.Plastic
	local panel = Instance.new("Part")
	local luminosityValue = 30
	local luminosityHue = Color3.new(1, 1, 1)
	local luminosityType = "PointLight"
	local luminosityRange = 20
	local usingLuminosity = false
	panel.Anchored = true
	panel.Shape = Enum.PartType.Block
	panel.TopSurface = Enum.SurfaceType.Smooth
	panel.BottomSurface = Enum.SurfaceType.Smooth
	panel.Transparency = 0
	panel.Reflectance = 0
	panel.Parent = workspace
	local workingNumber = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "table" then
			for key, value in pairs(arguments[i]) do
				local lkey = string.lower(key)
				if lkey == "anchored" then panel.Anchored = value end
				if lkey == "x" then x = value end
				if lkey == "y" then	y,needToCreateYvalue = value, false end
				if lkey == "z" then z = value end
				if lkey == "size" then -- Any of these keys can be used and they will all result in setting the scalar value: size 
					size = value                     -- Default size type should be a number.  If a vector, then use the X value from the vector.
					if typeof(value) == "Vector3" then size = value.X end
				end
				if lkey == "width" then	size = value end
				if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
				if lkey == "thickness" then	thickness = value end
				if lkey == "transparency" then panel.Transparency = value end
				if lkey == "opacity" then panel.Transparency = 1 - value end
				if lkey == "reflectance" then panel.Reflectance = value end
				if lkey == "rotateby" then orientation = value end
				if lkey == "material" then material = value end
				if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
				if lkey == "luminosityrange" then luminosityRange = value end
				if lkey == "luminosityhue" then 
					if typeof(value) == "Color3" then luminosityHue = value end
					if typeof(value) == "string" then
						local luminosityColor = string.lower(value)
						local red = colorName[luminosityColor]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[luminosityColor]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[luminosityColor]["DEC"][3]/255   --rescale from 0-255 to 0-1
						luminosityHue = Color3.new(red, green, blue)
					end
				end
				if lkey == "luminositytype" then luminosityType = value	end
				if lkey == "color" then 
					if typeof(value) == "Color3" then panel.Color = value end
					if typeof(value) == "string" then
						color = string.lower(value)
						local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
						panel.Color = Color3.new(red, green, blue)
					end
				end
			end
			for key, value in pairs(arguments[i]) do  -- Check to see if there is any luminosity to this object
				if string.match(string.lower(key), "luminosity") then usingLuminosity = true end
			end
		end

		if typeof(arguments[i]) == "Color3" then color = arguments[i] end
		if typeof(arguments[i]) == "string" then
			color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
		if typeof(arguments[i]) == "EnumItem" then material = arguments[i] end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				size = arguments[i]
			elseif numNumericArguments == 2 then
				workingNumber += 1
				if workingNumber == 1 then size = arguments[i] end
				if workingNumber == 2 then thickness = arguments[i] end
			elseif numNumericArguments == 4 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
			else
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
				if workingNumber == 5 then thickness = arguments[i] end
			end
		end
	end
	if thickness < 0.1 then thickness = 0.1 end	
	panel.Size = Vector3.new(size,thickness,size)
	if numNumericArguments <= 2 and needToCreateYvalue then y = size/2 end
	panel.Position = panel.Position + Vector3.new(x,y,z)
	panel.Color = color

	local panelN = Instance.new("Part")
	panelN.Anchored = true
	panelN.Shape = Enum.PartType.Block
	panelN.TopSurface = Enum.SurfaceType.Smooth
	panelN.BottomSurface = Enum.SurfaceType.Smooth
	panelN.Transparency = 0
	panelN.Reflectance = 0
	panelN.Parent = workspace
	panelN.Size = Vector3.new(size-thickness,1,size-thickness)
	panelN.Position += Vector3.new(x,y,z)
	panelN.Color = color

	local otherParts = {panelN}
	-- Perform subtract operation
	local success, newSquare = pcall(function()
		return panel:SubtractAsync(otherParts)
	end)
	-- If operation succeeds, position it at the same location and parent it to the workspace
	if success and newSquare then
		newSquare.Position = panel.Position
		newSquare.Parent = workspace
	end
	-- Destroy original parts which remain intact after operation
	panel:Destroy()
	for i = 1, #otherParts do
		otherParts[i]:Destroy()
	end
	if numNumericArguments <= 2 and needToCreateYvalue then y = size/2 end
	if usingLuminosity then
		--print(`Creating luminosity: {luminosityType} {luminosityHue} {luminosityValue}`)
		local lightOfPart = Instance.new(luminosityType)
		lightOfPart.Color = luminosityHue
		lightOfPart.Brightness = luminosityValue
		lightOfPart.Range = luminosityRange
		lightOfPart.Parent = newSquare
	end
	newSquare.Material = material
	newSquare.Color = color
	newSquare.Size = Vector3.new(size,thickness,size)
	newSquare.Orientation = orientation
	newSquare.Position = Vector3.new(x,y,z)
	return newSquare
end

--[[
RECTANGLE ------------------------------------------------------------------
This function creates a rectangle
A variable number of arguments (from none to 6) can be provided:
 size
 width, height
 width, height, thickness
 x, y, z
 x, y, z, size
 x, y, z, width, height
 x, y, z, width, height, thickness
 x, y, z, width, height, thickness, color
 x, y, z, width, height, thickness, color, material
The non-numeric arguments will be of specific types: string, Color3, Enum.Material.  Because these arguments have specific types, 
the function will examine the arguments, determine their type, and then use them as specific parameters for the function based on the argument type.
The non-numeric arguments can be placed in any order in any position of the arguments list
For examples:
  color, material, size, thickness
  size, color, material
  color, x, y, z
  x, y, z, material, color
The numeric arguments will always be interpreted as size if only 1 argument and x, y, z if 3 or more arguments.
]]
function shapes.rectangle(...)
	local arguments = table.pack(...)
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local width = 10  -- Default size if none specified
	local height = 10 -- Default size if none specified
	local thickness = defaultBorderThickness
	local x, y, z = 0, 0, -15
	local needToCreateYvalue = true
	local color = defaultColor
	local orientation = Vector3.new(90, 0, 0)
	local material = Enum.Material.Plastic
	local panel = Instance.new("Part")
	panel.Anchored = true
	panel.Shape = Enum.PartType.Block
	panel.TopSurface = Enum.SurfaceType.Smooth
	panel.BottomSurface = Enum.SurfaceType.Smooth
	panel.Transparency = 0
	panel.Reflectance = 0
	panel.Parent = workspace
	local luminosityValue = 30
	local luminosityHue = Color3.new(1, 1, 1)
	local luminosityType = "PointLight"
	local luminosityRange = 20
	local usingLuminosity = false
	local workingNumber = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "table" then
			for key, value in pairs(arguments[i]) do
				--print(key)
				local lkey = string.lower(key)
				if lkey == "anchored" then panel.Anchored = value end
				if lkey == "x" then x = value end
				if lkey == "y" then	y = value end
				if lkey == "z" then z = value end
				if lkey == "size" then -- Any of these keys can be used and they will all result in setting the scalar value: size 
					width = value                     -- Default size type should be a number.  If a vector, then use the X value from the vector.
					height = value                     -- Default size type should be a number.  If a vector, then use the X value from the vector.
					if typeof(value) == "Vector3" then width,height = value.X,value.Y end
				end
				if lkey == "width" then width= value end
				if lkey == "height" then height = value end
				if lkey == "thickness" then	thickness = value end
				if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
				if lkey == "transparency" then panel.Transparency = value end
				if lkey == "opacity" then panel.Transparency = 1 - value end
				if lkey == "reflectance" then panel.Reflectance = value end
				if lkey == "rotateby" then orientation = value end
				if lkey == "material" then material = value end
				if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
				if lkey == "luminosityrange" then luminosityRange = value end
				if lkey == "luminosityhue" then 
					if typeof(value) == "Color3" then luminosityHue = value end
					if typeof(value) == "string" then
						local luminosityColor = string.lower(value)
						local red = colorName[luminosityColor]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[luminosityColor]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[luminosityColor]["DEC"][3]/255   --rescale from 0-255 to 0-1
						luminosityHue = Color3.new(red, green, blue)
					end
				end
				if lkey == "luminositytype" then luminosityType = value	end
				if lkey == "color" then 
					if typeof(value) == "Color3" then panel.Color = value end
					if typeof(value) == "string" then
						color = string.lower(value)
						local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
						panel.Color = Color3.new(red, green, blue)
					end
				end
			end
			for key, value in pairs(arguments[i]) do  -- Check to see if there is any luminosity to this object
				if string.match(string.lower(key), "luminosity") then usingLuminosity = true end
			end
		end
		if typeof(arguments[i]) == "Color3" then color = arguments[i] end
		if typeof(arguments[i]) == "string" then
			color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
			--print(tostring(red) .. " " .. tostring(green) .. " " .. tostring(blue))
			--print(tostring(newSquare.Color))
		end
		if typeof(arguments[i]) == "EnumItem" then material = arguments[i] end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				width = arguments[i]
				height = arguments[i]
			elseif numNumericArguments == 2 then
				workingNumber += 1
				if workingNumber == 1 then width = arguments[i] end
				if workingNumber == 2 then height = arguments[i] end
			elseif numNumericArguments == 3 then
				workingNumber += 1
				if workingNumber == 1 then width = arguments[i] end
				if workingNumber == 2 then height = arguments[i] end
				if workingNumber == 3 then thickness = arguments[i] end
			elseif numNumericArguments == 4 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then 
					width = arguments[i] 
					height = arguments[i] 
				end
			elseif numNumericArguments == 5 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then width = arguments[i] end
				if workingNumber == 5 then height = arguments[i] end
			else
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then width = arguments[i] end
				if workingNumber == 5 then height = arguments[i] end
				if workingNumber == 6 then thickness = arguments[i] end
			end
		end
	end
	if thickness < 0.1 then thickness = 0.1 end	
	if numNumericArguments <= 2 and needToCreateYvalue then y = height/2 end
	panel.Size = Vector3.new(width,thickness,height)
	panel.Position = panel.Position + Vector3.new(x,y,z)
	panel.Color = color

	local panelN = Instance.new("Part")
	panelN.Anchored = true
	panelN.Shape = Enum.PartType.Block
	panelN.TopSurface = Enum.SurfaceType.Smooth
	panelN.BottomSurface = Enum.SurfaceType.Smooth
	panelN.Transparency = 0
	panelN.Reflectance = 0
	panelN.Parent = workspace
	panelN.Size = Vector3.new(width-thickness,1,height-thickness)
	panelN.Position += Vector3.new(x,y,z)
	panelN.Color = color

	local otherParts = {panelN}
	-- Perform subtract operation
	local success, newRectangle = pcall(function()
		return panel:SubtractAsync(otherParts)
	end)
	-- If operation succeeds, position it at the same location and parent it to the workspace
	if success and newRectangle then
		newRectangle.Position = panel.Position
		newRectangle.Parent = workspace
	end
	-- Destroy original parts which remain intact after operation
	panel:Destroy()
	for i = 1, #otherParts do
		otherParts[i]:Destroy()
	end
	newRectangle.Color = color
	newRectangle.Orientation = orientation
	newRectangle.Position = Vector3.new(x,y,z)
	newRectangle.Material = material
	if usingLuminosity then
		--print(`Creating luminosity: {luminosityType} {luminosityHue} {luminosityValue}`)
		local lightOfPart = Instance.new(luminosityType)
		lightOfPart.Color = luminosityHue
		lightOfPart.Brightness = luminosityValue
		lightOfPart.Range = luminosityRange
		lightOfPart.Parent = newRectangle
	end

	return newRectangle
end

-- DISC ------------------------------------------------------------------
-- This function creates a disc
-- A variable number of arguments (from none to 6) can be provided:
-- size
-- size, thickness
-- x, y, z
-- x, y, z, size
-- x, y, z, size, thickness
-- x, y, z, size, thickness, color
-- x, y, z, size, thickness, color, material
function shapes.disc(...)
	local arguments = table.pack(...)
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local size = 10 -- Default size if none specified
	local thickness = 0.1
	local x, y, z = 0, 0, -15
	local needToCreateYvalue = true
	local color = defaultColor
	local orientation = Vector3.new(90, 0, 90)
	local material = Enum.Material.Plastic
	local mainPart = Instance.new("Part")
	local luminosityValue = 30
	local luminosityHue = Color3.new(1, 1, 1)
	local luminosityType = "PointLight"
	local luminosityRange = 20
	mainPart.Anchored = true
	mainPart.Shape = Enum.PartType.Cylinder
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.Transparency = 0
	mainPart.Reflectance = 0.6
	mainPart.Parent = workspace
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local numVector3Arguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "Vector3" then numVector3Arguments += 1 end
	end
	local workingNumber = 0
	local workingVector = 0
	for i = 1, #arguments do
		--print(typeof(arguments[i]))
		if typeof(arguments[i]) == "table" then
			for key, value in pairs(arguments[i]) do
				--print(key)
				local lkey = string.lower(key)
				if lkey == "anchored" then mainPart.Anchored = value end
				if lkey == "x" then x = value end
				if lkey == "y" then	y,needToCreateYvalue = value, false end
				if lkey == "z" then z = value end
				if lkey == "size" then -- Any of these keys can be used and they will all result in setting the scalar value: size 
					size = value                     -- Default size type should be a number.  If a vector, then use the X value from the vector.
					if typeof(value) == "Vector3" then size = value.X end
				end
				if lkey == "width" then	size = value end
				if lkey == "height" then size = value end
				if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
				if lkey == "thickness" then	thickness = value end
				if lkey == "transparency" then mainPart.Transparency = value end
				if lkey == "opacity" then mainPart.Transparency = 1 - value end
				if lkey == "reflectance" then mainPart.Reflectance = value end
				if lkey == "rotateby" then orientation = value end
				if lkey == "material" then material = value end
				if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
				if lkey == "luminosityrange" then luminosityRange = value end
				if lkey == "luminosityhue" then 
					if typeof(value) == "Color3" then luminosityHue = value end
					if typeof(value) == "string" then
						local luminosityColor = string.lower(value)
						local red = colorName[luminosityColor]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[luminosityColor]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[luminosityColor]["DEC"][3]/255   --rescale from 0-255 to 0-1
						luminosityHue = Color3.new(red, green, blue)
					end
				end
				if lkey == "luminositytype" then luminosityType = value	end
				if lkey == "color" then 
					if typeof(value) == "Color3" then color = value end
					if typeof(value) == "string" then
						color = string.lower(value)
						local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
						color = Color3.new(red, green, blue)
					end
				end
			end
			for key, value in pairs(arguments[i]) do  -- Check to see if there is any luminosity to this object
				local lkey = string.lower(key)
				if lkey == "luminosity" or lkey == "luminosityvalue" or lkey == "luminosityhue" or lkey == "luminosityrange" or lkey == "luminositytype" then -- If there is luminosity, then install the surface light
					local lightOfPart = Instance.new(luminosityType)
					lightOfPart.Color = luminosityHue
					lightOfPart.Brightness = luminosityValue
					lightOfPart.Range = luminosityRange
					lightOfPart.Parent = mainPart
				end
			end
		end
		if typeof(arguments[i]) == "Vector3" then
			if numVector3Arguments == 2 then
				-- first vector is x,y,z
				-- second vector is width, height, length
			end
		end
		if typeof(arguments[i]) == "Color3" then mainPart.Color = arguments[i] end
		if typeof(arguments[i]) == "string" then
			local color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
		if typeof(arguments[i]) == "EnumItem" then mainPart.Material = arguments[i] end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				size = arguments[i]
				y,needToCreateYvalue = size/2, false
			elseif numNumericArguments == 2 then
				workingNumber += 1
				if workingNumber == 1 then size = arguments[i] end
				if workingNumber == 2 then thickness = arguments[i] end
				y,needToCreateYvalue = size/2, false
			elseif numNumericArguments == 4 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
			elseif numNumericArguments == 5 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
				if workingNumber == 5 then thickness = arguments[i] end
			else
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
			end
		end
	end
	if numNumericArguments == 0 and needToCreateYvalue == true then y = size/2 end
	if thickness < 0.1 then thickness = 0.1 end	
	mainPart.Color = color
	mainPart.Orientation = orientation
	mainPart.Size = Vector3.new(thickness,size,size) -- must stay thickness, size, size
	mainPart.Position = Vector3.new(x,y,z)
	mainPart.Material = material
	return mainPart
end

-- CIRCLE ------------------------------------------------------------------
-- This function creates a circle
-- A variable number of arguments (from none to 6) can be provided:
-- size
-- size, thickness
-- x, y, z
-- x, y, z, size
-- x, y, z, size, thickness
-- x, y, z, size, thickness, color
-- x, y, z, size, thickness, color, material
function shapes.circle(...)
	local arguments = table.pack(...)
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local size = 10 -- Default size if none specified
	local thickness = defaultBorderThickness
	local x, y, z = 0, 0, -15
	local needToCreateYvalue = true
	local color = defaultColor
	local orientation = Vector3.new(0, 90, 0)
	local material = Enum.Material.Plastic
	local disc = Instance.new("Part")
	local luminosityValue = 30
	local luminosityHue = Color3.new(1, 1, 1)
	local luminosityType = "PointLight"
	local luminosityRange = 20
	local usingLuminosity = false
	disc.Anchored = true
	disc.Shape = Enum.PartType.Cylinder
	disc.TopSurface = Enum.SurfaceType.Smooth
	disc.BottomSurface = Enum.SurfaceType.Smooth
	disc.Transparency = 0
	disc.Reflectance = 0.6
	disc.Parent = workspace
	local workingNumber = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "table" then
			for key, value in pairs(arguments[i]) do
				--print(key)
				local lkey = string.lower(key)
				if lkey == "anchored" then disc.Anchored = value end
				if lkey == "x" then x = value end
				if lkey == "y" then	y,needToCreateYvalue = value, false end
				if lkey == "z" then z = value end
				if lkey == "size" then -- Any of these keys can be used and they will all result in setting the scalar value: size 
					size = value                     -- Default size type should be a number.  If a vector, then use the X value from the vector.
					if typeof(value) == "Vector3" then size = value.X end
				end
				if lkey == "width" then	size = value end
				if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
				if lkey == "thickness" then	thickness = value end
				if lkey == "transparency" then disc.Transparency = value end
				if lkey == "opacity" then disc.Transparency = 1 - value end
				if lkey == "reflectance" then disc.Reflectance = value end
				if lkey == "rotateby" then orientation = value end
				if lkey == "material" then material = value end
				if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
				if lkey == "luminosityrange" then luminosityRange = value end
				if lkey == "luminosityhue" then 
					if typeof(value) == "Color3" then luminosityHue = value end
					if typeof(value) == "string" then
						local luminosityColor = string.lower(value)
						local red = colorName[luminosityColor]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[luminosityColor]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[luminosityColor]["DEC"][3]/255   --rescale from 0-255 to 0-1
						luminosityHue = Color3.new(red, green, blue)
					end
				end
				if lkey == "luminositytype" then luminosityType = value	end
				if lkey == "color" then 
					if typeof(value) == "Color3" then disc.Color = value end
					if typeof(value) == "string" then
						color = string.lower(value)
						local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
						color = Color3.new(red, green, blue)
					end
				end
			end
			for key, value in pairs(arguments[i]) do  -- Check to see if there is any luminosity to this object
				if string.match(string.lower(key), "luminosity") then usingLuminosity = true end
			end
		end

		if typeof(arguments[i]) == "Color3" then color = arguments[i] end
		if typeof(arguments[i]) == "string" then
			color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
		if typeof(arguments[i]) == "EnumItem" then material = arguments[i] end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				size = arguments[i]
			elseif numNumericArguments == 2 then
				workingNumber += 1
				if workingNumber == 1 then size = arguments[i] end
				if workingNumber == 2 then thickness = arguments[i] end
			elseif numNumericArguments == 4 then
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
			else
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y = arguments[i] end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
				if workingNumber == 5 then thickness = arguments[i] end
			end
		end
	end
	if thickness < 0.1 then thickness = 0.1 end	
	disc.Size = Vector3.new(thickness,size,size)
	disc.Orientation = Vector3.new(0, 90, 0)
	local zCoord = -15
	local xCoord = 0
	disc.Position = disc.Position + Vector3.new(xCoord,size/2,zCoord)

	local discN = Instance.new("Part")
	discN.Anchored = true
	discN.Shape = Enum.PartType.Cylinder
	discN.TopSurface = Enum.SurfaceType.Smooth
	discN.BottomSurface = Enum.SurfaceType.Smooth
	discN.Transparency = 0
	discN.Reflectance = 0.6
	discN.Parent = workspace
	discN.Size = Vector3.new(thickness+2,size-thickness,size-thickness)
	discN.Orientation = Vector3.new(0, 90, 0)
	local zCoord = -15
	local xCoord = 0
	discN.Position = discN.Position + Vector3.new(xCoord,size/2,zCoord)
	--print(typeof(discN.Position))

	local otherParts = {discN}
	-- Perform subtract operation
	local success, newCircle = pcall(function()
		return disc:SubtractAsync(otherParts)
	end)
	-- If operation succeeds, position it at the same location and parent it to the workspace
	if success and newCircle then
		newCircle.Position = disc.Position
		newCircle.Parent = workspace
	end
	-- Destroy original parts which remain intact after operation
	disc:Destroy()
	for i = 1, #otherParts do
		otherParts[i]:Destroy()
	end
	newCircle.Archivable=true
	if numNumericArguments <= 2 and needToCreateYvalue then y = size/2 end
	newCircle.Position = Vector3.new(x, y, z)
	newCircle.Orientation = orientation
	if typeof(color) == "Color3" then
		newCircle.Color = color
	else
		if typeof(color) == "string" then
			color = string.lower(color)
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			newCircle.Color = Color3.new(red, green, blue)
		end
	end
	if usingLuminosity then
		--print(`Creating luminosity: {luminosityType} {luminosityHue} {luminosityValue}`)
		local lightOfPart = Instance.new(luminosityType)
		lightOfPart.Color = luminosityHue
		lightOfPart.Brightness = luminosityValue
		lightOfPart.Range = luminosityRange
		lightOfPart.Parent = newCircle
	end

	--newCircle:SetAttribute("A", 4)
	--print(typeof(newCircle.Position))
	return newCircle

end

-- SPHERE ------------------------------------------------------------------
-- This function creates a sphere
-- A variable number of arguments (from none to 6) can be provided:
-- size
-- x, y, z
-- x, y, z, size
-- x, y, z, size, color
-- x, y, z, size, color, material
function shapes.sphere(...)
	local arguments = table.pack(...)
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local size = 10 -- Default size if none specified
	local x, y, z = 0, 0, -15
	local needToCreateYvalue = true
	local color = defaultColor
	local material = Enum.Material.Plastic
	local mainPart = Instance.new("Part")
	local luminosityValue = 30
	local luminosityHue = Color3.new(1, 1, 1)
	local luminosityType = "PointLight"
	local luminosityRange = 20
	mainPart.Anchored = true
	mainPart.Shape = Enum.PartType.Ball
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.Transparency = 0
	mainPart.Reflectance = 0.6
	mainPart.Parent = workspace
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local workingNumber = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "table" then
			for key, value in pairs(arguments[i]) do
				--print(key)
				local lkey = string.lower(key)
				if lkey == "anchored" then mainPart.Anchored = value end
				if lkey == "x" then x = value end
				if lkey == "y" then	y,needToCreateYvalue = value, false	end
				if lkey == "z" then z = value end
				if lkey == "size" or lkey == "width" or lkey == "height" then -- Any of these keys can be used and they will all result in setting the scalar value: size 
					size = value                    -- Default size type should be a number.  If a vector, then use the X value from the vector.
					if typeof(value) == "Vector3" then size = value.X end
				end
				if lkey == "position" and typeof(value) == "Vector3" then x,y,z,needToCreateYvalue=value.X,value.Y,value.Z,false end
				if lkey == "transparency" then mainPart.Transparency = value end
				if lkey == "opacity" then mainPart.Transparency = 1 - value end
				if lkey == "reflectance" then mainPart.Reflectance = value end
				if lkey == "material" then material = value end
				if lkey == "luminosityvalue" or lkey == "luminosity" then luminosityValue = value end
				if lkey == "luminosityrange" then luminosityRange = value end
				if lkey == "luminosityhue" then 
					if typeof(value) == "Color3" then luminosityHue = value end
					if typeof(value) == "string" then
						local luminosityColor = string.lower(value)
						local red = colorName[luminosityColor]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[luminosityColor]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[luminosityColor]["DEC"][3]/255   --rescale from 0-255 to 0-1
						luminosityHue = Color3.new(red, green, blue)
					end
				end
				if lkey == "luminositytype" then luminosityType = value	end
				if lkey == "color" then 
					if typeof(value) == "Color3" then color = value end
					if typeof(value) == "string" then
						color = string.lower(value)
						local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
						local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
						local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
						color = Color3.new(red, green, blue)
					end
				end
			end
			for key, value in pairs(arguments[i]) do  -- Check to see if there is any luminosity to this object
				local lkey = string.lower(key)
				if lkey == "luminosity" or lkey == "luminosityvalue" or lkey == "luminosityhue" or lkey == "luminosityrange" or lkey == "luminositytype" then -- If there is luminosity, then install the surface light
					--print(`Creating luminosity: {luminosityType} {luminosityHue} {luminosityValue}`)
					local lightOfPart = Instance.new(luminosityType)
					lightOfPart.Color = luminosityHue
					lightOfPart.Brightness = luminosityValue
					lightOfPart.Range = luminosityRange
					lightOfPart.Parent = mainPart
				end
			end
		end
		if typeof(arguments[i]) == "Color3" then color = arguments[i] end
		if typeof(arguments[i]) == "string" then
			local color = string.lower(arguments[i])
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
		if typeof(arguments[i]) == "EnumItem" then mainPart.Material = arguments[i] end
		if typeof(arguments[i]) == "number" then
			if numNumericArguments == 1 then
				size = arguments[i]
				y = size/2
			else
				workingNumber += 1
				if workingNumber == 1 then x = arguments[i] end
				if workingNumber == 2 then y,needToCreateYvalue = arguments[i],false end
				if workingNumber == 3 then z = arguments[i] end
				if workingNumber == 4 then size = arguments[i] end
			end
		end
	end
	mainPart.Size = Vector3.new(size,size,size)
	if numNumericArguments == 0 and needToCreateYvalue == true then y = size/2 end
	if typeof(color) == "Color3" then
		mainPart.Color = color
	else
		if typeof(color) == "string" then
			color = string.lower(color)
			local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
			color = Color3.new(red, green, blue)
		end
	end
	mainPart.Color = color
	mainPart.Position = Vector3.new(x,y,z)
	mainPart.Material = material
	return mainPart
end

-- LIGHTSOURCE ------------------------------------------------------------------
-- This function creates a lightSource
-- A variable number of arguments (from none to 6) can be provided:
-- size
-- width, height
-- width, height, thickness
-- x, y, z
-- x, y, z, size
-- x, y, z, width, height
-- x, y, z, width, height, thickness
-- x, y, z, width, height, size, thickness, color
-- x, y, z, width, height, size, thickness, color, material
function shapes.lightSource(...)
	local arguments = table.pack(...)
	local width = 10  -- Default size if none specified
	local height = 10 -- Default size if none specified
	local thickness = 0.1
	local x, y, z = 0, 0, -15
	local color = Color3.new(1, 1, 1)                   -- Default color for lights
	local material = Enum.Material.Plastic
	if #arguments == 1 then 
		width = arguments[1]
		height = arguments[1]
		y = height/2
	elseif #arguments == 2 then	
		width,height = arguments[1],arguments[2]
		y = height/2
	elseif #arguments == 3 then
		width,height,thickness = arguments[1],arguments[2],arguments[3]
		y = height/2
	elseif #arguments == 4 then x,y,z, width, height = arguments[1],arguments[2],arguments[3],arguments[4],arguments[4]
	elseif #arguments == 5 then x,y,z, width, height = arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]
	elseif #arguments == 6 then x,y,z, width, height, thickness = arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]
	elseif #arguments == 7 then x,y,z, width, height, thickness, color = arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7]
	elseif #arguments == 8 then x,y,z, width, height, thickness, color, material = arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8]
	elseif #arguments > 9 then print("Too many arguments")	
	else
	end
	if thickness < 0.1 then thickness = 0.1 end	
	local mainPart = Instance.new("Part")
	mainPart.Anchored = true
	mainPart.Shape = Enum.PartType.Block
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.FrontSurface = Enum.SurfaceType.Smooth
	mainPart.BackSurface = Enum.SurfaceType.Smooth
	mainPart.LeftSurface = Enum.SurfaceType.Smooth
	mainPart.RightSurface = Enum.SurfaceType.Smooth
	mainPart.Transparency = 0
	mainPart.Reflectance = 0
	mainPart.Parent = workspace
	mainPart.Size = Vector3.new(width,thickness,height)
	mainPart.Orientation = Vector3.new(-90, 0, 180)
	if typeof(color) == "string" then
		color = string.lower(color)
		local red = colorName[color]["DEC"][1]/255    --rescale from 0-255 to 0-1
		local green = colorName[color]["DEC"][2]/255  --rescale from 0-255 to 0-1
		local blue = colorName[color]["DEC"][3]/255   --rescale from 0-255 to 0-1
		color = Color3.new(red, green, blue)
	end
	mainPart.Color = color
	mainPart.Position = Vector3.new(x,y,z)
	mainPart.Material = material
	local lightOfPart = Instance.new("SurfaceLight")
	lightOfPart.Color = Color3.fromRGB(255, 255, 255)
	lightOfPart.Brightness = 0.7
	lightOfPart.Range = 55 -- 55
	lightOfPart.Parent = mainPart

	return mainPart
end


--This will subtract part B from part A
function shapes.subtract(mainPart, subPart, destroySubPart)
	local success
	local newMainPart
	if typeof(destroySubPart) == "nil" then
		destroySubPart = true
	end
	if typeof(subPart) == "table" then
		success, newMainPart = pcall(function()
			return mainPart:SubtractAsync(subPart)
		end)
	else
		success, newMainPart = pcall(function()
			return mainPart:SubtractAsync({subPart})
		end)
	end
	-- If operation succeeds, position it at the same location and parent it to the workspace
	if success and newMainPart then
		newMainPart.Position = mainPart.Position
		newMainPart.Parent = workspace
	end
	-- Destroy original parts which remain intact after operation
	mainPart:Destroy()
	if destroySubPart then subPart:Destroy() end
	return newMainPart
end

--This will Union part B to part A
function shapes.union(mainPart, subPartList)
	local success, newMainPart = pcall(function()
		return mainPart:UnionAsync(subPartList)
	end)
	-- If operation succeeds, position it at the same location and parent it to the workspace
	if success and newMainPart then
		newMainPart.Position = mainPart.Position
		newMainPart.Parent = workspace
	end
	-- Destroy original parts which remain intact after operation
	mainPart:Destroy()
	for i = 1, #subPartList do
		subPartList[i]:Destroy()
	end
	return newMainPart
end

--This function changes the color of the object
function shapes.fill(mainPart, colorValue)
	if typeof(colorValue) == "Color3" then
		mainPart.Color = colorValue
	else
		if typeof(colorValue) == "string" then
			colorValue = string.lower(colorValue)
			local red = colorName[colorValue]["DEC"][1]/255    --rescale from 0-255 to 0-1
			local green = colorName[colorValue]["DEC"][2]/255  --rescale from 0-255 to 0-1
			local blue = colorName[colorValue]["DEC"][3]/255   --rescale from 0-255 to 0-1
			mainPart.Color = Color3.new(red, green, blue)
		else
			print("Error in the Fill method.  You need to pass a Color3 vector or a string")
		end
	end
	return mainPart
end

--This function changes the location of the object
function shapes.moveBy(...)
	local arguments = table.pack(...)
	local x, y, z = 0, 0, 0
	local moveValue = 0
	local mainPart = arguments[1]
	if #arguments == 2 then
		mainPart = arguments[1]
		moveValue = arguments[2]
	elseif #arguments == 4 then moveValue = Vector3.new(arguments[2],arguments[3],arguments[4])
	else
	end
	if typeof(moveValue) == "Vector3" then
		mainPart.Position += moveValue
	else
		print("Error in the moveBy method.  You need to pass a Vector3.  You passed a: "..typeof(moveValue))
	end
	return mainPart
end

--This function changes the location of the object
function shapes.moveTo(...)
	local arguments = table.pack(...)
	local x, y, z = 0, 0, 0
	local locationValue = 0
	local mainPart = arguments[1]
	if #arguments == 2 then
		mainPart = arguments[1]
		locationValue = arguments[2]
	elseif #arguments == 4 then locationValue = Vector3.new(arguments[2],arguments[3],arguments[4])
	else
	end
	if typeof(locationValue) == "Vector3" then
		mainPart.Position = locationValue
	else
		print("Error in the moveTo method.  You need to pass a Vector3.  You passed a: "..typeof(locationValue))
	end
	return mainPart
end


--This function changes the size of the object
function shapes.size(mainPart, sizeValue)
	if typeof(sizeValue) == "Vector3" then
		mainPart.Size = sizeValue
	else
		print("Error in the Size method.  You need to pass a Vector3.  You passed a: "..typeof(sizeValue))
	end
	return mainPart
end

--This function changes the size of the object
function shapes.resizeBy(mainPart, sizeValue)
	if typeof(sizeValue) == "Vector3" then
		mainPart.Size += sizeValue
	else
		print("Error in the Size method.  You need to pass a Vector3.  You passed a: "..typeof(sizeValue))
	end
	return mainPart
end

--This function changes the rotation of the object
function shapes.rotate(...)
	local arguments = table.pack(...)
	local rotateValue = 0
	local mainPart = arguments[1]
	if #arguments == 2 then
		mainPart = arguments[1]
		rotateValue = arguments[2]
	elseif #arguments == 4 then rotateValue = Vector3.new(arguments[2],arguments[3],arguments[4])
	else
	end
	if typeof(rotateValue) == "Vector3" then
		mainPart.Orientation = rotateValue
	else
		print("Error in the Rotation method.  You need to pass a Vector3.  You passed a: "..typeof(rotateValue))
	end
	return mainPart
end

--This function changes the rotation of the object
function shapes.rotateBy(...)
	local arguments = table.pack(...)
	local rotateValue = 0
	local mainPart = arguments[1]
	if #arguments == 2 then
		mainPart = arguments[1]
		rotateValue = arguments[2]
	elseif #arguments == 4 then rotateValue = Vector3.new(arguments[2],arguments[3],arguments[4])
	else
	end
	if typeof(rotateValue) == "Vector3" then
		--mainPart.Orientation += rotateValue
		--mainPart.CFrame += rotateValue

		local pivot = mainPart.Position

		local newpivot = CFrame.new(pivot) -- Create decoy pivot that will "rotate"
		local offset = newpivot:toObjectSpace(mainPart.CFrame) -- Get the offset from the part to the pivot
		newpivot = newpivot * CFrame.Angles(math.rad(rotateValue.X), math.rad(rotateValue.Y), math.rad(rotateValue.Z)) -- Rotate the pivot
		mainPart.CFrame = newpivot * offset -- Re-offset the part from the new rotation

	else
		print("Error in the Rotation method.  You need to pass a Vector3.  You passed a: "..typeof(rotateValue))
	end
	return mainPart
end


--This function changes the transparency of the object
function shapes.transparency(mainPart, value)
	if typeof(value) == "number" then
		mainPart.Transparency = value
	else
		print("Error in the Transparency method.  You need to pass a number.  You passed a: "..typeof(value))
	end
	return mainPart
end

--This function changes the transparency of the object
function shapes.opacity(mainPart, value)
	if typeof(value) == "number" then
		mainPart.Transparency = 1-value
	else
		print("Error in the Opacity method.  You need to pass a number.  You passed a: "..typeof(value))
	end
	return mainPart
end

--This function changes the reflectance of the object
function shapes.reflectance(mainPart, value)
	if typeof(value) == "number" then
		mainPart.Reflectance = value
	else
		print("Error in the Reflectance method.  You need to pass a number.  You passed a: "..typeof(value))
	end
	return mainPart
end

--This function changes the material of the object
function shapes.material(mainPart, value)
	--local Materials = Enum.Material:GetEnumItems()
	if typeof(value) == "string" or typeof(value) == "EnumItem" then
		mainPart.Material = value
	else
		print("Error in the Material method.  You need to pass a string.  You passed a: "..typeof(value))
	end
	return mainPart
end

return shapes