Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Why does my studio crash when running this script and how do I prevent it?

Each time I run this script my studio crashes, basically when the tool touches the door it cframe moved and if touched again it returns. However after a simple fix to make the door return whenever the tool touches the door the door moves to the appropriate place then my studio crashes.

x = 0
d = true
e = true
r = 0
door2 = script.Parent.Union

function Touch(hit)
	local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
	if plr ~= nil and plr.Character:FindFirstChild("KeyName") and d == true then
		d = false
		while true do
			if x < 30 then
			door2.CFrame = door2.CFrame + (door2.CFrame.lookVector * 1)
			x = x + 1
			wait(.06)
			elseif x >= 50 then
			door2.CFrame = door2.CFrame - (door2.CFrame.lookVector * 1)
			r = r + 1
			wait(.06)
			if r >= 30 then
			r = 0
			e = true
			d = true
			x = 0
			break
				end
			end
		end
	end
end

script.Parent.Union.Touched:connect(Touch)
wait(.06)

2 comments

0

As far as I can tell, this should not cause studio to crash. Try disabling the script. If studio still crashes then something else is causing it.

0

It becomes an infinite loop so it does.

2 answers

Tab your code correctly. Also, use good variable names. I could more easily suggest how to clean up your code, but first I have to figure out what r, x, e, or d are supposed to mean.

I'm not sure you'll remember in two months, either.


while loops try again the moment their body finishes. If you don't use wait(), working on this loop this will consume all of ROBLOX's time and lead to a crash.

Your while loop starting line 11 does not always wait(). It wait()s in two conditions:

  • x < 30
  • x >= 50

This leaves open the range where x is between 30 and 50.

When you have a loop like this, it's good hygiene to do the wait() at the very beginning or end of the loop, to avoid this problem, and to avoid repeating wait() all over the place.

Cleanup

I see a lot of ways to clean this up.


First, name your variables better. d seems to be used in a debounce pattern. canOpen is a much more descriptive name for it.

plr is a silly way to write player. This is not the 70's, you don't need to save a few bytes. Writing out the English word means you save the time of deciphering and remembering which shortening you used (playr, plyr, plr, player?). Save your time by just using the proper spelling.

When you find yourself repeating yourself so much you need to shorten words, that's usually the sign that something else is wrong.

e is not used.


You have a variable door2, but later use script.Parent.Union. Use your variables!


Using == true on a boolean, or ~= nil on anything else is redundant.


All of the logic in the if r >= 30 then statement should be moved after the while true do loop. It saves indentation and makes the flow of your code clearer.

	if player and player.Character:FindFirstChild("KeyName") and canOpen then
		canOpen = false
		while true do
			wait(.06)
			if x < 30 then
				door2.CFrame = door2.CFrame + (door2.CFrame.lookVector * 1)
				x = x + 1
			elseif x >= 50 then
				door2.CFrame = door2.CFrame - (door2.CFrame.lookVector * 1)
				r = r + 1
				if r >= 30 then
					break
				end
			end
		end
		r = 0
		canOpen = true
		x = 0
	end
--

Notice how you know have something that looks like

while true do
	-- do stuff

	if stopcondition then
		break
	end
end

Since we know that that stopcondition can never be true at the beginning of the loop, that means you should probably just write this as

while not stopcondition do
	-- do stuff
end

Cleaned up

All in all, you get

x = 0
canOpen = true
r = 0
door2 = script.Parent.Union

function Touch(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player and player.Character:FindFirstChild("KeyName") and canOpen then
		canOpen = false
		while r < 30 do
			wait(.06)
			if x < 30 then
				door2.CFrame = door2.CFrame + (door2.CFrame.lookVector * 1)
				x = x + 1
			elseif x >= 50 then
				door2.CFrame = door2.CFrame - (door2.CFrame.lookVector * 1)
				r = r + 1
			end
		end
		r = 0
		x = 0
		canOpen = true
	end
end

door2.Touched:connect(Touch)

This code doesn't quite add up to me.

You only increase x by 1 while it's less than 30. That means x >= 50 is never going to happen.

1 comment

0

The 50 was there to make the door return to its old position and it was working at the time. Thanks for all the detail and info however the door doesnt return to its old position when touched again.

It keeps on crashing your studio because in your 3rd if statement you forgot to put a wait time in there... The best and most efficient way I can tell you to work with these while true do loops is by putting a condition inside the loop to wait()and then do... Something like this:

x = 0
d = true
e = true
r = 0
door2 = script.Parent.Union

function Touch(hit)
    local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
    if plr ~= nil and plr.Character:FindFirstChild("KeyName") and d == true then
        d = false
        while wait(.6) do
            if x < 30 then
            door2.CFrame = door2.CFrame + (door2.CFrame.lookVector * 1)
            x = x + 1
            elseif x >= 50 then
            door2.CFrame = door2.CFrame - (door2.CFrame.lookVector * 1)
            r = r + 1
            if r >= 30 then
            r = 0
            e = true
            d = true
            x = 0
            break
                end
            end
        end
    end
end
 
script.Parent.Union.Touched:connect(Touch)

As you can see above I have changed the while true do statement to something that has a condition of wait inside of it. Rather then putting so many wait(.6) in the script I just made it while wait(.6) do so now it will wait .6 no matter which condition it goes by.

Thank you for reading this question and I hope I helped! If you have any questions then please don't be afraid to post them in the comments below.

~~ KingLoneCat

This discussion is preserved as it was. New answers, comments, and votes are closed.