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

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

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

Updated 2024-04-12

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 defaultReflectance = 0.05
shapes.zDirection = -1

local fontName={  -- Creating a Dictionary of font names
	Creepster = Enum.Font.Creepster,
	IndieFlower = Enum.Font.IndieFlower,
	Antique = Enum.Font.Antique,
	SpecialElite = Enum.Font.SpecialElite,
	FredokaOne = Enum.Font.FredokaOne,
	Code = Enum.Font.Code,
	SciFi = Enum.Font.SciFi,
	ArialBold = Enum.Font.ArialBold,
	Oswald = Enum.Font.Oswald,
	Bodoni = Enum.Font.Bodoni,
	Cartoon = Enum.Font.Cartoon,
	Fantasy = Enum.Font.Fantasy,
	Highway = Enum.Font.Highway,
	Roboto = Enum.Font.Roboto,
	Kalam = Enum.Font.Kalam,
	Gotham = Enum.Font.Gotham
}

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 = defaultReflectance
	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
			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.Material = material
	mainPart.Size = Vector3.new(size,size,size)
	mainPart.Position = Vector3.new(x,y,z*shapes.zDirection)
	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 = defaultReflectance
	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
			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*shapes.zDirection)
	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 x1,y1,z1,x2,y2,z2 = 0,0,0,0,0,0
	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 = defaultReflectance
	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]) == "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 == "x1" then x1 = value end
				if lkey == "y1" then y1 = value end
				if lkey == "z1" then z1 = value end
				if lkey == "x2" then x2 = value end
				if lkey == "y2" then y2 = value end
				if lkey == "z2" then z2 = 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 == "point1" and typeof(value) == "Vector3" then x1,y1,z1=value.X,value.Y,value.Z end
				if lkey == "point2" and typeof(value) == "Vector3" then x2,y2,z2=value.X,value.Y,value.Z 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 == "material" then mainPart.Material = 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
			if x1>0 or x2>0 or y1>0 or y2>0 or z1>0 or z2>0 then
				if y1 == y2 and height>0 then 
					y1 = y1 - height/2
					y2 = y2 + height/2
				end
				v1 = Vector3.new(x1, y1, z1)
				v2 = Vector3.new(x2, y2, z2)
			end
		end

		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*shapes.zDirection)
	return mainPart
end

--[[
Archway ------------------------------------------------------------------
This function creates an archway
A variable number of arguments (from none to 6) can be provided:
 size
 width, height
 width, height, thickness
 x, y, z
 Vector3
 x, y, z, color
 Vector3, color
 x, y, z, color, material
 Vector3, 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.archway(Vector3.new(-10,0,-15), 2)
  s.archway(Vector3.new(-10,0,-15), Enum.Material.Brick, Color3.new(1, 0.545098, 0.545098), 2)
  color, material, width, height
  size, color, material
The numeric arguments will always be interpreted as size if only 1 argument and x, y, z if 3 or more arguments.
]]		
function shapes.archway(...)
	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(0, 0, -15)
	local needToCreateYvalue = true
	local x,y,z = 0,0,0
	local color = defaultColor
	local material = Enum.Material.Plastic
	local orientation = Vector3.new(0,0,0)
	if thickness < 0.1 then thickness = 0.1 end	

	color = defaultColor
	
	local mainPart = Instance.new("Part")
	mainPart.Anchored = true
	mainPart.Shape = Enum.PartType.Block
	mainPart.CanCollide = true

	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]) == "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 
					thickness = value                     -- Default size type should be a number. 
					if typeof(value) == "Vector3" then width,height,thickness = value.X,value.Y,value.Z end
				end
				if lkey == "rotateby" then orientation = value end
				if lkey == "width" then	width = value end
				if lkey == "height" then height = value 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 == "material" then mainPart.Material = 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
		end

		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
			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
	

	-- Create the block for a doorway
	mainPart.Color = color
	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.6
	mainPart.Parent = workspace
	mainPart.Size = Vector3.new(12,20,2)
	local zCoord = -15
	local xCoord = 0
	mainPart.Position = mainPart.Position + Vector3.new(xCoord,2,zCoord)

	-- Create the inner arch
	local archPart = Instance.new("Part")
	archPart.Anchored = true
	archPart.Shape = Enum.PartType.Cylinder
	archPart.CanCollide = false
	archPart.Color = color
	archPart.TopSurface = Enum.SurfaceType.Smooth
	archPart.BottomSurface = Enum.SurfaceType.Smooth
	archPart.Transparency = 0
	archPart.Reflectance = 0.6
	archPart.Parent = workspace
	archPart.Size = Vector3.new(4,60,6)
	archPart.Orientation = Vector3.new(0, 90, 0)
	local yCoord = 6
	local xCoord = 0
	archPart.Position = archPart.Position + Vector3.new(xCoord,yCoord,zCoord)

	-- Create the bottom through
	local walkThruPart = Instance.new("Part")
	walkThruPart.Anchored = true
	walkThruPart.Shape = Enum.PartType.Block
	walkThruPart.CanCollide = false
	walkThruPart.Color = color
	walkThruPart.TopSurface = Enum.SurfaceType.Smooth
	walkThruPart.BottomSurface = Enum.SurfaceType.Smooth
	walkThruPart.Transparency = 0
	walkThruPart.Reflectance = 0.6
	walkThruPart.Parent = workspace
	walkThruPart.Size = Vector3.new(5.8, 12, 4)
	local yCoord = 1
	local xCoord = 0
	walkThruPart.Position = walkThruPart.Position + Vector3.new(xCoord,yCoord,zCoord)

	local otherParts = {archPart, walkThruPart}
	-- Perform subtract operation
	local success, newArchway = pcall(function()
		return mainPart:SubtractAsync(otherParts)
	end)
	-- If operation succeeds, position it at the same location and parent it to the workspace
	if success and newArchway then
		newArchway.Position = mainPart.Position
		newArchway.Parent = workspace
	end
	-- Destroy original parts which remain intact after operation
	mainPart:Destroy()
	for i = 1, #otherParts do
		otherParts[i]:Destroy()
	end
	-- The resulting Archway is called: newArchway
	newArchway.Position = Vector3.new(x,y,z*shapes.zDirection)
	newArchway.Orientation = orientation
	newArchway.Color = color
	newArchway.Size = Vector3.new(width, height ,thickness)
	return newArchway
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 = defaultReflectance
	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 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	
	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 = defaultReflectance
	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*shapes.zDirection)
	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, length = 0, 0, 15, 0.05
	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 = defaultReflectance
	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,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 = 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 == "length" then length = 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 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)
			--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+length,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 = defaultReflectance
	panelN.Parent = workspace
	panelN.Size = Vector3.new(width-thickness,length+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*shapes.zDirection)
	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 = defaultReflectance
	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 == "radius" then size = value 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 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
				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*shapes.zDirection)
	mainPart.Material = material
	mainPart:SetAttribute("Thickness", thickness)
	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
-- You can pass an object with properties
-- s.circle({ x=-8, y=3, z=15, size=6, thickness=0.5, color="red", luminosityRange=1, luminosityHue=Color3.new(1,1,0)})
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, length = 0, 0, 15, 0.05
	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 = defaultReflectance
	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 == "radius" 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 == "length" then length = 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+length,size,size)
	disc.Orientation = Vector3.new(0, 90, 0)
	disc.Color = color
	disc.TopSurface = Enum.SurfaceType.Smooth
	disc.BottomSurface = Enum.SurfaceType.Smooth
	disc.Transparency = 0
	disc.Reflectance = defaultReflectance
	disc.Material = material
	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.Parent = workspace
	discN.Size = Vector3.new(thickness+length+0.5,size-thickness,size-thickness)
	discN.Orientation = Vector3.new(0, 90, 0)
	discN.Transparency = 0
	discN.Reflectance = defaultReflectance
	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*shapes.zDirection)
	newCircle.Orientation = orientation
	newCircle:SetAttribute("Thickness", thickness)
	print("Setting Thickness to ".. tostring(thickness))
	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

-- TUBE ------------------------------------------------------------------
-- This function creates a hollow tube
-- A variable number of arguments (from none to 6) can be provided:
-- size
-- size, thickness
-- x1, y1, z1, x2, y2, z2  -- two coordinates are required specifying the beginning and end of the tube
-- x1, y1, z1, x2, y2, z2, size
-- x1, y1, z1, x2, y2, z2, size, thickness
-- x1, y1, z1, x2, y2, z2, size, thickness, color
-- x1, y1, z1, x2, y2, z2, size, thickness, color, material
-- You can pass an object with parameters
-- s.tube({ x1=-10, y1=4, z1=25, x2=10, y2=4, z2=5, size=10, thickness=2, color=Color3.new(1, 0.243137, 0.054902), material=Enum.Material.Wood })
function shapes.tube(...)
	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 v1 = Vector3.new(-10, 0, 15)
	local v2 = Vector3.new(10, 10, 15)
	local x1,y1,z1,x2,y2,z2 = 0,0,0,0,0,0
	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 = defaultReflectance
	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 == "x1" then x1 = value end
				if lkey == "y1" then y1 = value end
				if lkey == "z1" then z1 = value end
				if lkey == "x2" then x2 = value end
				if lkey == "y2" then y2 = value end
				if lkey == "z2" then z2 = 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 == "radius" 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 == "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 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
			if x1>0 or x2>0 or y1>0 or y2>0 or z1>0 or z2>0 then
				v1 = Vector3.new(x1, y1, z1)
				v2 = Vector3.new(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 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


	-- in 3D the distance of a line is sqrt(DeltaX^2 + DeltaY^2 + DeltaZ^2)
	disc.Size = Vector3.new(math.sqrt((v1.X-v2.X)*(v1.X-v2.X)+(v1.Y-v2.Y)*(v1.Y-v2.Y)+(v1.Z-v2.Z)*(v1.Z-v2.Z)),size,size)
	disc.Orientation = Vector3.new(0, 90, 0)
	disc.Position = Vector3.new((v1.X+v2.X)/2,(v1.Y+v2.Y)/2,(v1.Z+v2.Z)/2*shapes.zDirection)

	if thickness < 0.1 then thickness = 0.1 end	
	disc.Color = color
	disc.TopSurface = Enum.SurfaceType.Smooth
	disc.BottomSurface = Enum.SurfaceType.Smooth
	disc.Transparency = 0
	disc.Reflectance = defaultReflectance
	disc.Material = material
	local zCoord = -15
	local xCoord = 0

	local discN = Instance.new("Part")
	discN.Anchored = true
	discN.Shape = Enum.PartType.Cylinder
	discN.Parent = workspace
	discN.Size = Vector3.new(math.sqrt((v1.X-v2.X)*(v1.X-v2.X)+(v1.Y-v2.Y)*(v1.Y-v2.Y)+(v1.Z-v2.Z)*(v1.Z-v2.Z))+0.5,size-thickness,size-thickness)
	discN.Orientation =  Vector3.new(0, 90, 0)
	discN.Position = Vector3.new((v1.X+v2.X)/2,(v1.Y+v2.Y)/2,(v1.Z+v2.Z)/2*shapes.zDirection)
	discN.Transparency = 0
	discN.Reflectance = defaultReflectance
	local zCoord = -15
	local xCoord = 0
	--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
	--print("180*math.atan2("..tostring(v1.Z).."-" .. tostring(v2.Z).." , "..tostring(v2.X).."-"..tostring(v1.X).."/math.pi")
	print(180*math.atan2(v1.Z-v2.Z, v2.X-v1.X)/math.pi)
	newCircle.Position = Vector3.new((v1.X+v2.X)/2,(v1.Y+v2.Y)/2,(v1.Z+v2.Z)/2*shapes.zDirection)
	newCircle.Orientation = Vector3.new(0, 180*math.atan2(v2.Z*shapes.zDirection-v1.Z*shapes.zDirection, v1.X-v2.X)/math.pi, 180*math.atan2(v1.Y-v2.Y, v1.X-v2.X)/math.pi)  -- Transforms Y based on z and x
	--newCircle.Orientation = Vector3.new(0, 180*math.atan2(v1.Z*shapes.zDirection-v2.Z*shapes.zDirection, v2.X-v1.X)/math.pi, 0)  -- This formula must be: atan2(z1-z2, x2-x1)
	--newCircle.Orientation = Vector3.new(0, 180*math.atan2(v2.X-v1.X, v1.Z*shapes.zDirection-v2.Z*shapes.zDirection)/math.pi, 180*math.atan2(v1.Y-v2.Y, v1.X-v2.X)/math.pi)  -- Transforms Y based on z and x
	--newCircle.Orientation = Vector3.new(180*math.atan2(v2.Z*shapes.zDirection-v1.Z*shapes.zDirection, v1.Y-v2.Y)/math.pi, 180*math.atan2(v2.X-v1.X, v1.Z*shapes.zDirection-v2.Z*shapes.zDirection)/math.pi, 180*math.atan2(v2.Y-v1.Y, v1.X-v2.X)/math.pi)  -- This formula must be: atan2(z1-z2, x2-x1)
	newCircle:SetAttribute("Thickness", thickness)
	print("Setting Thickness to ".. tostring(thickness))
	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
-- You can pass an object with properties
-- s.sphere( { x=-24,y=3, z=15, size=2, color="green",  rotateBy=Vector3.new( 0, 0,90) })
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 = defaultReflectance
	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
			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*shapes.zDirection)
	mainPart.Material = material
	return mainPart
end

-- DRAWTEXT ------------------------------------------------------------------
-- This function creates a billboard with text
-- A variable number of arguments (from none to 6) can be provided.  Examples:
-- s.drawText("Hello World!")
-- s.drawText(0, 5, 15, "Hello World!")
-- s.drawText(0, 5, 15, "Hello World!", Enum.Font.Creepster)
-- s.drawText({ x=0, y=5, z=15, text="Hello World!", font="Creepster", Opacity=0, color="red" })
-- s.drawText({ x=0, y=5, z=15, text="Hello World!", font="Creepster", Opacity=0.9, color="red", backgroundColor=Color3.new(0.3, 0.5, 0.8) })
-- s.drawText({ x=0, y=5, z=15, width=50, height=20, text="Hello World!", font="Creepster", Opacity=0.9, color="red", backgroundColor=Color3.new(0.3, 0.5, 0.8) })

function shapes.drawText(...)
	local arguments = table.pack(...) 
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local width = 30  -- Default size if none specified
	local height = 6  -- Default size if none specified
	local thickness = 0.1
	local x, y, z = 0, 0, -15  -- Coordinates for placement of the billboard
	local needToCreateYvalue = true
	local color = Color3.new(1, 1, 1)                   -- Default color for lights
	local material = Enum.Material.Plastic
	local mainPart = Instance.new("Part")
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.Size = Vector3.new(45, 7, .1) -- Set the size of the part
	mainPart.Anchored = true
	mainPart.Rotation = Vector3.new(0, 180, 0)
	mainPart.Transparency = 0.5
	local theText = "Hello, Roblox!"
	local textFont = Enum.Font.Code
	local textSize = 30  -- This is a number that varies between 0 and 100
	local textColor = Color3.new(1, 1, 1)
	local textRotate = 0  -- A scalar value from 0 to 360 representing the number of degrees to rotate the text that is displayed on the surfaceGui.
	local workingNumber = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "string" then theText = arguments[i]	end
		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 == "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 -- A tranparency of 1 is see-thru.  An transparency of 0 is opaque.
				if lkey == "opacity" then mainPart.Transparency = 1 - value end  -- An opacity of 1 is opaque.  An opacity of 0 is transparent.
				if lkey == "reflectance" then mainPart.Reflectance = value end
				if lkey == "material" then material = value end
				if lkey == "size" then 	mainPart.Size = value end  -- In this case, Size needs to be a Vector3
				if lkey == "width" then width = value end
				if lkey == "height" then height = value end
				if lkey == "rotation" then 	mainPart.Rotation = value end  -- In this case, Size needs to be a Vector3
				if lkey == "text" then 	theText = value end
				if lkey == "fontsize" then 	textSize = value end  -- fontSize is an alias for textSize
				if lkey == "textsize" then 	textSize = value end
				if lkey == "textrotate" then
					if typeof(value) == "number" then
						textRotate = value
					else 
						if typeof(value) == "Vector3" then
							textRotate = value.X
						end
					end
				end
				if lkey == "color" then 
					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
						textColor = Color3.new(red, green, blue)
					end
					if typeof(value) == "Color3" then textColor = value end
				end
				if lkey == "backgroundcolor" then 
					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
						mainPart.Color = Color3.new(red, green, blue)
					end
					if typeof(value) == "Color3" then mainPart.Color = value end
				end
				if lkey == "font" then
					if typeof(value) == "string" then textFont = fontName[value] end
					if typeof(value) == Enum.Font then textFont = value end
				end
			end
		end
		if typeof(arguments[i]) == Enum.Font then textFont = arguments[i] end
		if typeof(arguments[i]) == "number" then
			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
		end
	end
	mainPart.Position = Vector3.new(x, y, z)              -- Set the position of the part
	if thickness < 0.1 then thickness = 0.1 end	
	mainPart.Size = Vector3.new(width, height, thickness) -- Set the size of the part
	mainPart.Parent = workspace
	local surfaceGui = Instance.new("SurfaceGui")
	surfaceGui.Parent = mainPart
	surfaceGui.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
	surfaceGui.PixelsPerStud = 20
	local textLabel = Instance.new("TextLabel")
	textLabel.TextScaled = false
	textLabel.Parent = surfaceGui
	textLabel.Size = UDim2.fromOffset(0, 0)
	textLabel.Position = UDim2.new(0.5, 0, 0.5, 0)
	textLabel.Rotation = textRotate
	textLabel.AnchorPoint = Vector2.new(0, 0)
	textLabel.TextColor3 = textColor
	textLabel.BackgroundTransparency = 1
	textLabel.Text = theText
	textLabel.TextSize = textSize
	textLabel.Font = textFont
	return mainPart
end

function shapes.drawText2(...)
	local arguments = table.pack(...) 
	local numNumericArguments = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "number" then numNumericArguments += 1 end
	end
	local orientation = Vector3.new(0, 90, 0)
	local width = 30  -- Default size if none specified
	local height = 6  -- Default size if none specified
	local thickness = 0.1
	local x, y, z = 0, 0, 15  -- Coordinates for placement of the billboard
	local needToCreateYvalue = true
	local color = Color3.new(1, 1, 1)                   -- Default color for lights
	local material = Enum.Material.Plastic
	local mainPart = Instance.new("Part")
	mainPart.TopSurface = Enum.SurfaceType.Smooth
	mainPart.BottomSurface = Enum.SurfaceType.Smooth
	mainPart.Size = Vector3.new(45, 7, .1) -- Set the size of the part
	mainPart.Anchored = true
	mainPart.Rotation = Vector3.new(0, 180, 0)
	mainPart.Transparency = 0.5
	local theText = "Hello, Roblox!"
	local textFont = Enum.Font.Code
	local textSize = 30  -- This is a number that varies between 0 and 100
	local textColor = Color3.new(1, 1, 1)
	local textRotate = 0  -- A scalar value from 0 to 360 representing the number of degrees to rotate the text that is displayed on the surfaceGui.
	local workingNumber = 0
	for i = 1, #arguments do
		if typeof(arguments[i]) == "string" then theText = arguments[i]	end
		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 == "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 -- A tranparency of 1 is see-thru.  An transparency of 0 is opaque.
				if lkey == "opacity" then mainPart.Transparency = 1 - value end  -- An opacity of 1 is opaque.  An opacity of 0 is transparent.
				if lkey == "reflectance" then mainPart.Reflectance = value end
				if lkey == "material" then material = value end
				if lkey == "size" then 	mainPart.Size = value end  -- In this case, Size needs to be a Vector3
				if lkey == "width" then width = value end
				if lkey == "height" then height = value end
				if lkey == "rotation" then 	mainPart.Rotation = value end  -- In this case, rotation needs to be a Vector3
				if lkey == "rotateby" then 	mainPart.Orientation = value end  -- In this case, rotation needs to be a Vector3
				if lkey == "text" then 	theText = value end
				if lkey == "fontsize" then 	textSize = value end  -- fontSize is an alias for textSize
				if lkey == "textsize" then 	textSize = value end
				if lkey == "textrotate" then
					if typeof(value) == "number" then
						textRotate = value
					else 
						if typeof(value) == "Vector3" then
							textRotate = value.X
						end
					end
				end
				if lkey == "color" then 
					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
						textColor = Color3.new(red, green, blue)
					end
					if typeof(value) == "Color3" then textColor = value end
				end
				if lkey == "backgroundcolor" then 
					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
						mainPart.Color = Color3.new(red, green, blue)
					end
					if typeof(value) == "Color3" then mainPart.Color = value end
				end
				if lkey == "font" then
					if typeof(value) == "string" then textFont = fontName[value] end
					if typeof(value) == Enum.Font then textFont = value end
				end
			end
		end
		if typeof(arguments[i]) == Enum.Font then textFont = arguments[i] end
		if typeof(arguments[i]) == "number" then
			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
		end
	end
	mainPart.Position = Vector3.new(x, y, z*shapes.zDirection) -- Set the position of the part
	if thickness < 0.1 then thickness = 0.1 end	
	mainPart.Size = Vector3.new(width, height, thickness) -- Set the size of the part
	mainPart.Parent = workspace
	local surfaceGui = Instance.new("SurfaceGui")
	surfaceGui.Parent = mainPart
	surfaceGui.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
	surfaceGui.PixelsPerStud = 20
	local textLabel = Instance.new("TextLabel")
	textLabel.TextScaled = false
	textLabel.Parent = surfaceGui
	textLabel.Size = UDim2.fromOffset(0, 0)
	textLabel.Position = UDim2.new(0.5, 0, 0.5, 0)
	textLabel.Rotation = textRotate
	textLabel.AnchorPoint = Vector2.new(0, 0)
	textLabel.TextColor3 = textColor
	textLabel.BackgroundTransparency = 1
	textLabel.Text = theText
	textLabel.TextSize = textSize
	textLabel.Font = textFont
	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 = defaultReflectance
	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*shapes.zDirection)
	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]*shapes.zDirection)
	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

function shapes.randomColor() 
	return Color3.new(math.random(), math.random(), math.random())
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

--This function creates a pause in the execution of a task
function shapes.sleepMilliseconds(value)
	if typeof(value) == "number" then
		task.wait(value/1000)
	end
end


return shapes