-- Rock Module
return function( ... )
	
	-- Tables
	local Parameters = ...
	local PartsModel = Instance.new("Model")
	
	-- Properties
	local Origin = Parameters.Origin or error('No origin set!')
	local Radius = Parameters.Radius or 20
	local Size = Parameters.Size or Vector3.new(2, 2, 2)
	local Filter = Parameters.Filter or { Parent, Player.Character }
	local Amount = Parameters.Amount or 30
	local Lifetime = Parameters.Lifetime or 3
	
	-- Angles
	local Angle = 30
	local OtherAngle = 360 / Amount
	
	-- Raycast Parameters
	local RaycastParameters = RaycastParams.new()
	RaycastParameters.FilterType = Enum.RaycastFilterType.Blacklist
	RaycastParameters.FilterDescendantsInstances = Filter
	
	-- Main function for rocks
	for _ = 1, Amount do
		local Time = Random:NextNumber(1.35, 1.75)
		local Info = TweenInfo.new(Time, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
		
		local CF = Origin
		local NewCFOuter = CF * CFrame.fromEulerAnglesXYZ(0, math.rad(Angle), 0) * CFrame.new(Radius / 2 + Radius / 2.7, 10, 0)
		local NewCFInner = CF * CFrame.fromEulerAnglesXYZ(0, math.rad(Angle), 0) * CFrame.new(Radius / 2 + Radius / 10, 10, 0)

		local OuterRaycast = workspace:Raycast(NewCFOuter.Position, Offset, RaycastParameters)
		local InnerRaycast = workspace:Raycast(NewCFInner.Position, Offset, RaycastParameters)
		
		if OuterRaycast then
			-- Outer Rocks
			local Part = Instance.new('Part')
			Part.Anchored = true
			Part.CanCollide = false
			Part.CanTouch = false
			Part.Material = OuterRaycast.Material
			Part.Color = OuterRaycast.Instance.Color
			
			if OuterRaycast.Instance and OuterRaycast.Instance:IsA("BasePart") then
				Part.Transparency = OuterRaycast.Instance.Transparency
				
				for _, s in pairs({"TopSurface", "BottomSurface", "FrontSurface", "BackSurface", "RightSurface", "LeftSurface"}) do
					Part[s] = OuterRaycast.Instance[s]
				end
			end
			
			Part.Size = Vector3.new(Size.X * 1.3, Size.Y/1.4, Size.Z * 1.3) * Random:NextNumber(1, 1.5)
			Part.CFrame = CFrame.lookAt(OuterRaycast.Position - Vector3.new(0, 0.5 + (Part.Size.Y + 1.5), 0), Origin.Position) * CFrame.fromEulerAnglesXYZ(Random:NextNumber(-0.25, 0.5), Random:NextNumber(-0.25, 0.25), Random:NextNumber(-0.25, 0.25))
			
			Part.Parent = Parent
			
			local Hoof = Part:Clone()
			Hoof.Size = Vector3.new(Part.Size.X * 1.01, Part.Size.Y * 0.25, Part.Size.Z * 1.01)
			Hoof.CFrame = Part.CFrame * CFrame.new(0, Part.Size.Y / 2 - Hoof.Size.Y / 2.1, 0)
			Hoof.Parent = Parent
			
			-- Inner Rocks
			local InnerPart = Part:Clone()
			InnerPart.CFrame = CFrame.lookAt(InnerRaycast.Position - Vector3.new(0, Size.Y * 0.4  + (Part.Size.Y + 1.5), 0), Origin.Position) * CFrame.fromEulerAnglesXYZ(Random:NextNumber(-1 ,-0.3), Random:NextNumber(-0.15, 0.15), Random:NextNumber(-0.15, 0.15))
			InnerPart.Parent = Parent
			
			local InnerHoof = Hoof:Clone()
			InnerHoof.CFrame = InnerPart.CFrame * CFrame.new(0, InnerPart.Size.Y / 2 - InnerHoof.Size.Y / 2.1, 0)
			InnerHoof.Parent = Parent
			
			Part.Parent = PartsModel
			Hoof.Parent = PartsModel
			InnerPart.Parent = PartsModel
			InnerHoof.Parent = PartsModel
			
			-- Remove the rocks when their lifetime is up.
			task.spawn(function()	
				for _, p in pairs(PartsModel:GetChildren()) do
					--local r = p.CFrame - p.Position
					--p.CFrame = CFrame.new(p.Position.X, p.Position.Y, p.Position.Z) * CFrame.new(0, -(p.Size.Y + 2), 0) * r
					--p.Position = p.Position - Vector3.new(0, ( p.Size.Y + 2), 0)
					local Time = Random:NextNumber(0.2, 0.4)
					local Info = TweenInfo.new(Time, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
					TweenService:Create(p, Info, {Position = p.CFrame.Position + Vector3.new(0, ( p.Size.Y + 2 ), 0), Transparency = 0}):Play()
				end
				
				task.wait(Lifetime)

				for _, p in pairs(PartsModel:GetChildren()) do
					TweenService:Create(p, Info, {Position = p.CFrame.Position - Vector3.new(0, ( p.Size.Y + 2 ), 0), Transparency = 1}):Play()
				end
				
				task.wait(Time)

				PartsModel:Destroy() 
			end)
		end
		
		Angle += OtherAngle
	end
	
	PartsModel.Parent = Parent
end