Pinkstack/roblox-luau-corpus-text huggingface dataset:
-- RayPlaneIntersection (shortened)
-- http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm


function moduleApiTable:RayPlaneIntersection(ray, planeNormal, pointOnPlane)
	planeNormal = planeNormal.unit
	ray = ray.Unit

	local Vd = planeNormal:Dot(ray.Direction)
	if Vd == 0 then -- parallel, no intersection
		return nil
	end

	local V0 = planeNormal:Dot(pointOnPlane - ray.Origin)
	local t = V0 / Vd
	if t < 0 then --plane is behind ray origin, and thus there is no intersection
		return nil
	end

	return ray.Origin + ray.Direction * t
end

function moduleApiTable:GetEaseLinear()
	return Linear
end
function moduleApiTable:GetEaseOutQuad()
	return EaseOutQuad
end
function moduleApiTable:GetEaseInOutQuad()
	return EaseInOutQuad
end

function moduleApiTable:CreateNewSlider(numOfSteps, startStep, minStep)
	return CreateNewSlider(numOfSteps, startStep, minStep)
end

function moduleApiTable:CreateNewSelector(selectionStringTable, startPosition)
	return CreateSelector(selectionStringTable, startPosition)
end

function moduleApiTable:CreateNewDropDown(dropDownStringTable, startPosition)
	return CreateDropDown(dropDownStringTable, startPosition, nil)
end

function moduleApiTable:AddNewRow(pageToAddTo, rowDisplayName, selectionType, rowValues, rowDefault, extraSpacing)
	return AddNewRow(pageToAddTo, rowDisplayName, selectionType, rowValues, rowDefault, extraSpacing)
end

function moduleApiTable:AddNewRowObject(pageToAddTo, rowDisplayName, rowObject, extraSpacing)
	return AddNewRowObject(pageToAddTo, rowDisplayName, rowObject, extraSpacing)
end

function moduleApiTable:ShowAlert(alertMessage, okButtonText, settingsHub, okPressedFunc, hasBackground)
	ShowAlert(alertMessage, okButtonText, settingsHub, okPressedFunc, hasBackground)
end

function moduleApiTable:IsSmallTouchScreen()
	return isSmallTouchScreen()
end

function moduleApiTable:IsPortrait()
	return isPortrait()
end

function moduleApiTable:MakeStyledButton(name, text, size, clickFunc, pageRef, hubRef)
	return MakeButton(name, text, size, clickFunc, pageRef, hubRef)
end

function moduleApiTable:MakeStyledImageButton(name, image, size, imageSize, clickFunc, pageRef, hubRef)
	return MakeImageButton(name, image, size, imageSize, clickFunc, pageRef, hubRef)
end

function moduleApiTable:AddButtonRow(pageToAddTo, name, text, size, clickFunc, hubRef)
	return AddButtonRow(pageToAddTo, name, text, size, clickFunc, hubRef)
end

function moduleApiTable:CreateSignal()
	return CreateSignal()
end

function  moduleApiTable:UsesSelectedObject()
	return usesSelectedObject()
end

function moduleApiTable:TweenProperty(instance, prop, start, final, duration, easingFunc, cbFunc)
	return PropertyTweener(instance, prop, start, final, duration, easingFunc, cbFunc)
end

function moduleApiTable:OnResized(key, callback)
	return addOnResizedCallback(key, callback)
end

function moduleApiTable:FireOnResized()
	local newSize = getViewportSize()
	local portrait = moduleApiTable:IsPortrait()

	for key, callback in pairs(onResizedCallbacks) do
		callback(newSize, portrait)
	end
end
--Create suggestion labels


local function createSuggestionLabels(props)
	for i = 1,props.maxSuggestions do
		local label = props.rframe.LabelTemplate:Clone()
		label.Name = "Label"..i
		label.Visible = false
		label.Parent = props.rframe
		label.MouseEnter:Connect(function()
			props.suggestionPos = i
		end)
		label.MouseButton1Up:Connect(function()
			props.suggestionPos = i
			selectSuggestion(props)
		end)
	end
end
-- Connects the given collision function to the object's "Touched" event, but only if that object is a Part
-- Otherwise, it tries this function on all of the object's children


local function attachCollisionFunction(item, collisionFunction)

    if item:IsA("BasePart") then
        item.Touched:Connect(collisionFunction)
    else
        for _, child in ipairs(item:GetChildren()) do
            attachCollisionFunction(child, collisionFunction)
        end
    end
end
--	====================
--	BASIC
--	A basic settings for the gun
--	====================



		Auto = false;
		MuzzleOffset = Vector3.new(0, 0.625, 1.25);
		BaseDamage = 60;
		FireRate = 0.3; --In second
		ReloadTime = 2.5; --In second
		AmmoPerClip = 6; --Put "math.huge" to make this gun has infinite ammo and never reload
		Spread = 1.25; --In degree
		HeadshotEnabled = true; --Enable the gun to do extra damage on headshot
		HeadshotDamageMultiplier = 3;
		MouseIconID = "316279304";
		HitSoundIDs = {186809061,186809249,186809250,186809252};
		IdleAnimationID = 94331086; --Set to "nil" if you don't want to animate
		IdleAnimationSpeed = 1;
		FireAnimationID = 94332152; --Set to "nil" if you don't want to animate
		FireAnimationSpeed = 6;
		ReloadAnimationID = nil; --Set to "nil" if you don't want to animate
		ReloadAnimationSpeed = 1;
-- CONSTANTS



local GuiLib = script.Parent.Parent
local Lazy = require(GuiLib:WaitForChild("LazyLoader"))
local Defaults = GuiLib:WaitForChild("Defaults")

local INCREMENT_BUTTON = Defaults:WaitForChild("IncrementButton")
local DECREMENT_BUTTON = Defaults:WaitForChild("DecrementButton")

local WARN_MSG = "%s is not a valid mask. Defaulting to 'String' mask."

local MASKS = {}
for _, module in pairs(script:GetChildren()) do
	MASKS[module.Name] = require(module)
end
-- Wait for game to load:


if (not game:IsLoaded()) then
	game.Loaded:Wait()
end

local guis = game:GetService("ReplicatedStorage"):FindFirstChild(REP_STORAGE_FOLDER_NAME)
local player = game:GetService("Players").LocalPlayer
local playerGui = player.PlayerGui

if (not guis) then
	warn("UI loader failed to find " .. REP_STORAGE_FOLDER_NAME .. " folder in ReplicatedStorage")
	return
end
-- Libraries


local Roact = require(Vendor:WaitForChild('Roact'))
local new = Roact.createElement

local function ExportDialog(props)
    return new('ScreenGui', {}, {
        Dialog = new('Frame', {
            AnchorPoint = Vector2.new(0.5, 0.5);
            BackgroundColor3 = Color3.fromRGB(31, 31, 31);
            BackgroundTransparency = 0.6;
            BorderSizePixel = 0;
            Position = UDim2.new(0.5, 0, 0.5, 0);
            Size = UDim2.new(0, 200, 0, 0);
        }, {
            Corners = new('UICorner', {
                CornerRadius = UDim.new(0, 4);
            });
            CloseButton = new('TextButton', {
                AnchorPoint = Vector2.new(0, 1);
                BackgroundColor3 = Color3.fromRGB(0, 0, 0);
                BackgroundTransparency = 0.5;
                Modal = true;
                Position = UDim2.new(0, 0, 1, 0);
                Size = UDim2.new(1, 0, 0, 23);
                Text = 'Close';
                Font = Enum.Font.GothamSemibold;
                TextColor3 = Color3.fromRGB(255, 255, 255);
                TextSize = 11;
                [Roact.Event.Activated] = function (rbx)
                    props.OnDismiss()
                end;
            }, {
                Corners = new('UICorner', {
                    CornerRadius = UDim.new(0, 4);
                });
            });
            Text = new('TextLabel', {
                BackgroundTransparency = 1;
                Size = UDim2.new(1, 0, 1, -23);
                Font = Enum.Font.GothamSemibold;
                RichText = true;
                Text = props.Text;
                TextColor3 = Color3.fromRGB(255, 255, 255);
                TextSize = 11;
                TextWrapped = true;
                [Roact.Change.TextBounds] = function (rbx)
                    rbx.Parent.Size = UDim2.new(0, 200, 0, rbx.TextBounds.Y + 23 + 26)
                end;
            }, {
                Padding = new('UIPadding', {
                    PaddingLeft = UDim.new(0, 10);
                    PaddingRight = UDim.new(0, 10);
                });
            });
        });
    })
end

return ExportDialog
-- Called when any relevant values of GameSettings or LocalPlayer change, forcing re-evalulation of
-- current control scheme


function ControlModule:OnComputerMovementModeChange()
	local controlModule, success =  self:SelectComputerMovementModule()
	if success then
		self:SwitchToController(controlModule)
	end
end

function ControlModule:OnTouchMovementModeChange()
	local touchModule, success = self:SelectTouchModule()
	if success then
		while not self.touchControlFrame do
			wait()
		end
		self:SwitchToController(touchModule)
	end
end

function ControlModule:CreateTouchGuiContainer()
	if self.touchGui then self.touchGui:Destroy() end

	-- Container for all touch device guis
	self.touchGui = Instance.new('ScreenGui')
	self.touchGui.Name = "TouchGui"
	self.touchGui.ResetOnSpawn = false

	self.touchControlFrame = Instance.new("Frame")
	self.touchControlFrame.Name = "TouchControlFrame"
	self.touchControlFrame.Size = UDim2.new(1, 0, 1, 0)
	self.touchControlFrame.BackgroundTransparency = 1
	self.touchControlFrame.Parent = self.touchGui

	self.touchGui.Parent = self.playerGui
end

return ControlModule.new()
-- << Functions >> --




function lerp(a, b, c)
	return a + (b - a) * c
end

bobbing = game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	if script.Parent.Humanoid.MoveDirection.Magnitude > 0 then
		deltaTime = deltaTime * (script.Parent.Humanoid.WalkSpeed * 3.75)	
	else
		deltaTime = deltaTime * 60
	end
	print(deltaTime)
	if Humanoid.Health <= 0 then
		bobbing:Disconnect()
		return
	end
	local rootMagnitude = Humanoid.RootPart and Vector3.new(Humanoid.RootPart.Velocity.X, 0, Humanoid.RootPart.Velocity.Z).Magnitude or 0
	local calcRootMagnitude = math.min(rootMagnitude, 50)
	if deltaTime > 3 then
		func1 = 0
		func2 = 0
	else
		func1 = lerp(func1, math.cos(tick() * 0.5 * math.random(10, 15)) * (math.random(5, 20) / 200) * deltaTime, 0.05 * deltaTime)
		func2 = lerp(func2, math.cos(tick() * 0.5 * math.random(5, 10)) * (math.random(2, 10) / 200) * deltaTime, 0.05 * deltaTime)
	end
	Camera.CFrame = Camera.CFrame * (CFrame.fromEulerAnglesXYZ(0, 0, math.rad(func3)) * CFrame.fromEulerAnglesXYZ(math.rad(func4 * deltaTime), math.rad(val * deltaTime), val2) * CFrame.Angles(0, 0, math.rad(func4 * deltaTime * (calcRootMagnitude / 5))) * CFrame.fromEulerAnglesXYZ(math.rad(func1), math.rad(func2), math.rad(func2 * 10)))
	val2 = math.clamp(lerp(val2, -Camera.CFrame:VectorToObjectSpace((Humanoid.RootPart and Humanoid.RootPart.Velocity or Vector3.new()) / math.max(Humanoid.WalkSpeed, 0.01)).X * 0.08, 0.1 * deltaTime), -0.35, 0.2)
	func3 = lerp(func3, math.clamp(UserInputService:GetMouseDelta().X, -5, 5), 0.25 * deltaTime)
	func4 = lerp(func4, math.sin(tick() * int) / 5 * math.min(1, int2 / 10), 0.25 * deltaTime)
	if rootMagnitude > 1 then
		val = lerp(val, math.cos(tick() * 0.5 * math.floor(int)) * (int / 200), 0.25 * deltaTime)
	else
		val = lerp(val, 0, 0.05 * deltaTime)
	end
	if rootMagnitude > 12 then
		int = 20
		int2 = 18
	elseif rootMagnitude > 0.1 then
		int = 12
		int2 = 14
	else
		int2 = 0
	end
	vect3 = lerp(vect3, Camera.CFrame.LookVector, 0.125 * deltaTime)
end)
-- Returns module (possibly nil) and success code to differentiate returning nil due to error vs Scriptable


function ControlModule:SelectComputerMovementModule(): ({}?, boolean)
	if not (UserInputService.KeyboardEnabled or UserInputService.GamepadEnabled) then
		return nil, false
	end

	local computerModule
	local DevMovementMode = Players.LocalPlayer.DevComputerMovementMode

	if DevMovementMode == Enum.DevComputerMovementMode.UserChoice then
		computerModule = computerInputTypeToModuleMap[lastInputType]
		if UserGameSettings.ComputerMovementMode == Enum.ComputerMovementMode.ClickToMove and computerModule == Keyboard then
			-- User has ClickToMove set in Settings, prefer ClickToMove controller for keyboard and mouse lastInputTypes
			computerModule = ClickToMove
		end
	else
		-- Developer has selected a mode that must be used.
		computerModule = movementEnumToModuleMap[DevMovementMode]

		-- computerModule is expected to be nil here only when developer has selected Scriptable
		if (not computerModule) and DevMovementMode ~= Enum.DevComputerMovementMode.Scriptable then
			warn("No character control module is associated with DevComputerMovementMode ", DevMovementMode)
		end
	end

	if computerModule then
		return computerModule, true
	elseif DevMovementMode == Enum.DevComputerMovementMode.Scriptable then
		-- Special case where nil is returned and we actually want to set self.activeController to nil for Scriptable
		return nil, true
	else
		-- This case is for when computerModule is nil because of an error and no suitable control module could
		-- be found.
		return nil, false
	end
end
--[=[
	Manages the cleaning of events and other things. Useful for
	encapsulating state and make deconstructors easy.

	See the [Five Powerful Code Patterns talk](https://developer.roblox.com/en-us/videos/5-powerful-code-patterns-behind-top-roblox-games)
	for a more in-depth look at Maids in top games.

	```lua
	local maid = Maid.new()

	maid:GiveTask(function()
		print("Cleaning up")
	end)

	maid:GiveTask(workspace.ChildAdded:Connect(print))

	-- Disconnects all events, and executes all functions
	maid:DoCleaning()
	```

	@class Maid
]=]
-- luacheck: pop



local Maid = {}
Maid.ClassName = "Maid"
--	


	script.Parent.Handle3.Hinge1.Transparency = 1
	script.Parent.Handle3.Interactive1.Transparency = 1
	script.Parent.Handle3.Part1.Transparency = 1
	wait(0.06)
	script.Parent.Handle1.Hinge1.Transparency = 1
	script.Parent.Handle1.Interactive1.Transparency = 1
	script.Parent.Handle1.Part1.Transparency = 1
-- ScreenSpace -> WorldSpace. Raw function taking a screen position and a depth and 
-- converting it into a world position.


function ScreenSpace.ScreenToWorld(x, y, depth)
	local aspectRatio = ScreenSpace.AspectRatio()
	local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
	local wfactor = aspectRatio*hfactor
	--
	local xf, yf = x/ScreenSpace.ViewSizeX()*2 - 1, y/ScreenSpace.ViewSizeY()*2 - 1
	local xpos = xf * -wfactor * depth
	local ypos = yf *  hfactor * depth
	--
	return Vector3.new(xpos, ypos, depth)
end
-- Volume Functions --



function VolumeUp()
	volumeValue.Value = volumeValue.Value + 0.1
end

TV.VButtonUp.ClickDetector.MouseClick:Connect(VolumeUp)

function VolumeDown()
	volumeValue.Value = volumeValue.Value - 0.1
end

TV.VButtonDown.ClickDetector.MouseClick:Connect(VolumeDown)

function VolumeChanged()
	if volumeValue.Value < 0 then
		volumeValue.Value = 0
	elseif volumeValue.Value > 1.2 then
		volumeValue.Value = 1.2 -- I don't recommend any value higher than 1, it's annoying.
	else
		music.Volume = volumeValue.Value
	end
end

volumeValue.Changed:Connect(VolumeChanged)
-- ROBLOX FIXME: Can we define ClientChatModules statically in the project config


pcall(function() ChatLocalization = require((game:GetService("Chat") :: any).ClientChatModules.ChatLocalization :: any) end)
ChatLocalization = ChatLocalization or {}

if not ChatLocalization.FormatMessageToSend or not ChatLocalization.LocalizeFormattedMessage then
	function ChatLocalization:FormatMessageToSend(key,default) return default end
end

local function allSpaces(inputString)
	local testString = string.gsub(inputString, " ", "")
	return string.len(testString) == 0
end
--[[Transmission]]


	Tune.TransModes		={"Auto"}												--[[
	[Modes]
		"Auto"		: Automatic shifting
		"Semi"		: Clutchless manual shifting, dual clutch transmission
		"Manual"	: Manual shifting with clutch
		
		>Include within brackets
			eg: {"Semi"} or {"Auto", "Manual"}								
		>First mode is default mode													]]
	
	--Automatic Settings
	Tune.AutoShiftMode	= "RPM"												--[[
	[Modes]
		"Speed"		: Shifts based on wheel speed
		"RPM"		: Shifts based on RPM											]]	
	Tune.AutoUpThresh	= -200		--Automatic upshift point 	(relative to peak RPM, positive = Over-rev)
	Tune.AutoDownThresh = 1400		--Automatic downshift point (relative to peak RPM, positive = Under-rev)
	
	--Gear Ratios
	Tune.FinalDrive		= 3.20			-- Gearing determines top speed and wheel torque
	Tune.Ratios			= {				-- Higher ratio = more torque, Lower ratio = higher top speed
		--[[Reverse]]	3.42		,	-- Copy and paste a ratio to add a gear
		--[[Neutral]]	0			,	-- Ratios can also be deleted
		--[[ 1 ]]		3.75		,	-- Reverse, Neutral, and 1st gear are required
		--[[ 2 ]]		2.38		,
		--[[ 3 ]]		1.72		,
		--[[ 4 ]]		1.34		,
		--[[ 5 ]]		1.11		,
		--[[ 6 ]]		.78			,
	}
	Tune.FDMult			= 1			-- Ratio multiplier (Change this value instead of FinalDrive if car is struggling with torque ; Default = 1)
--// Handling Settings		


	Firerate = 60 / 200; -- 60 = 1 Minute, 700 = Rounds per that 60 seconds. DO NOT TOUCH THE 60!
	
	FireMode = 5; -- 1 = Semi, 2 = Auto, 3 = Burst, 4 = Bolt Action, 5 = Shot, 6 = Explosive
--[=[
	@private

	@param onFulfilled function?
	@param onRejected function?
	@param promise2 Promise<T>? -- May be nil. If it is, then we have the option to return self
	@return Promise
]=]


function Promise:_executeThen(onFulfilled, onRejected, promise2)
	if self._fulfilled then
		if type(onFulfilled) == "function" then
			-- If either onFulfilled or onRejected returns a value x, run
			-- the Promise Resolution Procedure [[Resolve]](promise2, x).
			if promise2 then
				promise2:Resolve(onFulfilled(unpack(self._fulfilled, 1, self._valuesLength)))
				return promise2
			else
				local results = table.pack(onFulfilled(unpack(self._fulfilled, 1, self._valuesLength)))
				if results.n == 0 then
					return _emptyFulfilledPromise
				elseif results.n == 1 and Promise.isPromise(results[1]) then
					return results[1]
				else
					local promise = Promise.new()
					-- Technically undefined behavior from A+, but we'll resolve to nil like ES6 promises
					promise:Resolve(table.unpack(results, 1, results.n))
					return promise
				end
			end
		else
			-- If onFulfilled is not a function, it must be ignored.
			-- If onFulfilled is not a function and promise1 is fulfilled,
			-- promise2 must be fulfilled with the same value as promise1.
			if promise2 then
				promise2:_fulfill(self._fulfilled, self._valuesLength)
				return promise2
			else
				return self
			end
		end
	elseif self._rejected then
		if type(onRejected) == "function" then
			-- If either onFulfilled or onRejected returns a value x, run
			-- the Promise Resolution Procedure [[Resolve]](promise2, x).
			if promise2 then
				promise2:Resolve(onRejected(unpack(self._rejected, 1, self._valuesLength)))
				return promise2
			else
				local results = table.pack(onRejected(unpack(self._rejected, 1, self._valuesLength)))
				if results.n == 0 then
					return _emptyFulfilledPromise
				elseif results.n == 1 and Promise.isPromise(results[1]) then
					return results[1]
				else
					local promise = Promise.new()
					-- Technically undefined behavior from A+, but we'll resolve to nil like ES6 promises
					promise:Resolve(table.unpack(results, 1, results.n))
					return promise
				end
			end
		else
			-- If onRejected is not a function, it must be ignored.
			-- If onRejected is not a function and promise1 is rejected, promise2 must be
			-- rejected with the same reason as promise1.
			if promise2 then
				promise2:_reject(self._rejected, self._valuesLength)

				return promise2
			else
				return self
			end
		end
	else
		error("Internal error: still pending")
	end
end
----------------------------------------------------------------------------------------------------
-----------------=[ RECOIL & PRECISAO ]=------------------------------------------------------------
----------------------------------------------------------------------------------------------------


	,VRecoil = {0.5,0.7}				--- Vertical Recoil
	,HRecoil = {0.5,0.7}				--- Horizontal Recoil
	,AimRecover = .95			---- Between 0 & 1

	,RecoilPunch = .1
	,VPunchBase = 1					--- Vertical Punch
	,HPunchBase = 1					--- Horizontal Punch
	,DPunchBase = 1 				--- Tilt Punch | useless

	,AimRecoilReduction = 1 		--- Recoil Reduction Factor While Aiming (Do not set to 0)
	,PunchRecover = 0.03
	,MinRecoilPower = 1
	,MaxRecoilPower = 2
	,RecoilPowerStepAmount = .15

	,MinSpread = 4					--- Min bullet spread value | Studs
	,MaxSpread = 40					--- Max bullet spread value | Studs
	,AimInaccuracyStepAmount = 2.5
	,WalkMultiplier = 0				--- Bullet spread based on player speed

	,SwayBase = 0.01				--- Weapon Base Sway | Studs
	,MaxSway =	1					--- Max sway value based on player stamina | Studs
-- Create component


local Component = Cheer.CreateComponent('BTNotificationsManager', View);

function Component.Start(Core)

	-- Display update notification if tool is outdated
	if Core.IsVersionOutdated() then
		if Core.Mode == 'Plugin' then
			Cheer(View.PluginUpdateNotification).Start(Component.AdjustLayout);
		elseif Core.Mode == 'Tool' then
			Cheer(View.ToolUpdateNotification).Start(Component.AdjustLayout);
		end;
	end;

	-- Display HttpEnabled warning if HttpService is disabled
	if not Core.SyncAPI:Invoke('IsHttpServiceEnabled') then
		Cheer(View.HttpDisabledWarning).Start(Component.AdjustLayout);
	end;

	-- Adjust layout
	View.UIListLayout:ApplyLayout();

	-- Animate opening
	View.Position = UDim2.new(0.5, 0, 1.5, 0);
	View.Visible = true;
	View:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), nil, nil, 0.2);

	-- Destroy notifications container on tool unequip
	spawn(function ()
		Core.Disabling:Wait();
		View:Destroy();
	end);

	-- Return component for chaining
	return Component;

end;

function Component.AdjustLayout()
	View.UIListLayout:ApplyLayout();
end;

return Component;
--bp.Position = shelly.PrimaryPart.Position


if not shellyGood then bp.Parent,bg.Parent= nil,nil return end
bp.Parent = nil
wait(math.random(3,8))
end


local soundBank = game.ServerStorage.Sounds.NPC.Shelly:GetChildren()

shelly.Health.Changed:connect(function()
if shellyGood then
bp.Parent,bg.Parent= nil,nil
shelly.PrimaryPart.Transparency =1
shelly.PrimaryPart.CanCollide = false
shelly.Shell.Transparency = 1
shelly.HitShell.Transparency = 0
shelly.HitShell.CanCollide = true
shellyGood = false
ostrich = tick()
shelly:SetPrimaryPartCFrame(shelly.PrimaryPart.CFrame*CFrame.new(0,2,0))
local hitSound = soundBank[math.random(1,#soundBank)]:Clone()
hitSound.PlayOnRemove = true
hitSound.Parent = shelly.PrimaryPart
wait()
hitSound:Destroy()

repeat wait() until tick()-ostrich > 10
shelly.PrimaryPart.Transparency = 0
shelly.PrimaryPart.CanCollide = true
shelly.Shell.Transparency = 0
shelly.HitShell.Transparency = 1
shelly.HitShell.CanCollide = false
bp.Parent,bg.Parent = shelly.PrimaryPart,shelly.PrimaryPart
shellyGood = true
end
end)


while true do
if shellyGood then
MoveShelly()
else
wait(1)
end 
end
----- Private Variables -----



local ActiveProfileStores = ProfileService._active_profile_stores
local AutoSaveList = ProfileService._auto_save_list
local IssueQueue = ProfileService._issue_queue

local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")

local PlaceId = game.PlaceId
local JobId = game.JobId

local AutoSaveIndex = 1 -- Next profile to auto save
local LastAutoSave = os.clock()

local LoadIndex = 0

local ActiveProfileLoadJobs = 0 -- Number of active threads that are loading in profiles
local ActiveProfileSaveJobs = 0 -- Number of active threads that are saving profiles

local CriticalStateStart = 0 -- os.clock()

local IsStudio = RunService:IsStudio()
local IsLiveCheckActive = false

local UseMockDataStore = false
local MockDataStore = ProfileService._mock_data_store -- Mock data store used when API access is disabled

local UserMockDataStore = ProfileService._user_mock_data_store -- Separate mock data store accessed via ProfileStore.Mock
local UseMockTag = {}