function Union(this,other) -- Combine two tables
	for index,item in pairs(other) do
		this[index] = item
	end
	return this
end

function Default(this,other)
	for index,item in pairs(other) do
		if not this[index] then this[index] = item end
	end
end

local _string = {["string"] = true}
local _number = {["number"] = true}
local _table = {["table"] = true}
local _boolean = {["boolean"] = true}
local type = type
IsString = function(value) return not not _string[type(value)] end
IsNumber = function(value) return not not _number[type(value)] end
IsTable = function(value) return not not _table[type(value)] end
IsBoolean = function(value) return not not _boolean[type(value)] end

Modules = game.ReplicatedFirst:WaitForChild("Modules")
Storage = game.ReplicatedStorage
Assets = Storage:WaitForChild("Assets")
Sounds = Assets:WaitForChild("Sounds")
Events = game.ReplicatedFirst:WaitForChild("Events")
Remotes = Storage:WaitForChild("Remotes")
Debris = game:GetService("Debris")
Tags = game:GetService("CollectionService")
Tween = game:GetService("TweenService")
Run = game:GetService("RunService")
Input = game:GetService("UserInputService")
Http = game:GetService("HttpService")
IsServer = Run:IsServer()
IsStudio = Run:IsStudio()
IsClient = not IsServer
if IsClient then Player = game.Players.LocalPlayer end

Begin = tick()

if IsServer then
	Data = game:GetService("DataStoreService")
else
	Player = game.Players.LocalPlayer
	UserId = Player.UserId
	Gui = game.Players.LocalPlayer.PlayerGui
end


function Iterate(array)
	local i = 0
	local n = #array
	return function()
		i = i + 1
		if i <= n then return array[i] end
	end
end

function WaitFor(tab,item,timeout)
	local t = 0
	timeout = timeout or 60
	repeat wait() t = t + 1 if t > timeout then error("Timeout for "..item,3) end until tab[item]
	return tab[item]
end

Errors = {}

function Error(stuff)
	local traceback = debug.traceback("\nTraceback:",3)
	table.insert(Errors,tostring(stuff)..traceback)
	warn(stuff,traceback)
end

function Protect(func)
	return function(...)
		local success,result = xpcall(func,function(err)
			Error(err)
		end,...)
		return result
	end
end

function Protected(func,...)
	local success,result = xpcall(func,function(err)
		Error(err)
	end,...)
	if success then return result end
end

String = tostring
Append = table.insert
ClassOf = getmetatable
Percent = function(num)
	if not num then error("Number is nil.",2) end
	local val = math.ceil(num*3)
	local colour = "31"
	if val > 2 then
		colour = "32"
	elseif val > 1 then
		colour = "33"
	end
	local txt = "\27["..colour.."m"..String(math.floor(num*100)).."%".."\27[0m"
	return txt
end

Unimplemented = function()
	error("Method unimplemented",2)
end

Notify = function(...)
	Events.Notification:Fire(...)
end

Class = function(properties)
	local template = {} -- Creates a metatable
	template.templates = {}
	template.Descends = function(other)
		return template.templates[getmetatable(other)]
	end
	template.__index = {}
	if properties.Inherits then -- Combine the template of the superclass
		template.__index = Union({},properties.Inherits.__index or {})
		template.__tostring = properties.Inherits.__tostring
		properties.Inherits.templates[template] = true
		template.super = properties.Inherits
		properties.Inherits = nil
	end
	properties.Class = template
	template.templates[template] = true -- Add this to the table of
	if properties.Construct then
		template.constructor = properties.Construct or function(_,...) end
		properties.Construct = nil
	end
	for index,item in pairs(properties) do -- The remaining items in properties are data
		template.__index[index] = item -- So all constants and methods go here
	end
	template.create = template.create or function(this,...) -- Call template to make this
		local new = {} -- Create a new instance table
		template.constructor(new,...) -- Construct it
		return setmetatable(new,template) -- Return the newly made instance
	end
	setmetatable(template,{
		__call = template.create,
	})
	template.__tostring = properties.String or template.__tostring
	return template
end

Union(_G,getfenv()) -- Combine _G with this module

require(script.Parent.BuildingGlobals)

if IsServer then 
	game.ReplicatedFirst.ReadyServer.Value = true 
else
	game.ReplicatedFirst.ReadyClient.Value = true
end

return _G