Teleport to another game - script sometimes crashes, need pcall?

  1. What do you want to achieve? I have 100 teleporters that players touch and they are sent to other games. I have one script that handles all this. I want this script to be stable and not to crash every few days.

  2. What is the issue? The teleport script basically works. Players happily use the game as a hub to find and teleport into other games. However, every couple days the script just crashes. All teleports simply stop working. Players just wonder around trying to teleport until I see this happening then I manually reset all servers.

  3. What solutions have you tried so far? I need do do something to stop the script from occasionally breaking. I suspect maybe I need to put a pcall somewhere strategic. Because this is a live game, and I can’t reproduce the error (it takes 1000’s of teleporting players to eventually break it), and I’m a new programmer, I’m afraid of throwing darts and tinkering too much. I am looking for advice on how to stabilize this script.

local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")
local dataStore = DataStoreService:GetOrderedDataStore("Teleports")
local MP = game:GetService('MarketplaceService')

local RS = game:GetService("ReplicatedStorage")
local TS = game:GetService("TeleportService")

local popular = game.Workspace.Stories.NowPlaying
local popularTitle = popular.Frame.Title.SurfaceGui.TextLabel
local popularImage = popular.Decal
local popularAuthor = popular.Frame.Author.SurfaceGui.TextLabel
local popularBannor = game.Workspace.Zones.Popular.UpdateBrick.SurfaceGui.TextLabel



local Stories = workspace.Stories:GetChildren()
local DB = false


for _, Story in pairs(Stories) do
	if Story:IsA("BasePart") then
		Story.Frame.Trigger.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") and DB == false then
				
				DB = true
				
				local character = hit.Parent 
				local player = game.Players:GetPlayerFromCharacter(character)
				
				local id = Story:GetAttribute("ID")  -- Get ID
				
				print(Story.Name, id .. " has been touched by " .. player.Name)
				
				dataStore:IncrementAsync(player.UserId, 1)
				--dataStore:SetAsync(player.UserId, 5) -- Total debug, resets to 5 if I tested alot.
				
				print(player.savedata.LastStory.Value)
				player.savedata.LastStory.Value = id
				print(player.savedata.LastStory.Value .. " Oh yeah!")
				
				
				local success, err = pcall(function()

					local playerUserId = "Player_" .. player.UserId
					
					playerData:SetAsync(playerUserId, player.savedata.LastStory.Value) --Saves player data

				end)
				
				
				local PlayParticle = RS.PlayParticle -- put play particle on Story
				local clonedPlayParticle = PlayParticle:Clone()
				clonedPlayParticle.Parent = Story
				
				character:WaitForChild("Humanoid").Jump = true
				
				wait()
				
				character.HumanoidRootPart.Anchored = true
				
				-----setupNowPlaying-----------------------------

				local Details = MP:GetProductInfo(id)

				local StoryName = Details.Name
				print(StoryName)
				popularTitle.Text = StoryName

				local StoryCreator = Details.Creator.Name
				print(StoryCreator)
				popularAuthor.Text = StoryCreator

				local iconID = Details.IconImageAssetId  --get the image


				if iconID ~= 0 then -- check if there truly is an image
					popularImage.Texture = "rbxthumb://type=Asset&id="..iconID.."&w=150&h=150" --set the image
				end
				
				popularBannor.Text = (player.Name .. " entered " .. StoryName)
				
				popular:SetAttribute("ID", id)
				
				------------------------------------------------------
				
				TS:Teleport(id, player) --Start Telport
				DB = false
				
			end
		end)
	end
end
1 Like

Any errors whenever this occurs? Specifically datastore or marketplace related ones?

The issue could be that you’re making to many datastore calls or :GetProductInfo(id) is returning nil for certain Id’s. This error will stop the execution of the rest of the code causing the debounce to remain true. Since all your teleporters share the SAME debounce, none of them will run since the if statement DB == false will never be met.

You should be wrapping all web calls in pcalls. This includes dataStore:IncrementAsync and MP:GetProductInfo(id). Your debounces apply for every teleporter. You should instead create a local debounce for each teleporter.

E.g:

for _, Story in pairs(Stories) do
	if Story:IsA("BasePart") then -- You want to make sure its a story before creating the debounce variable
        local DB = false -- This debounce is now local to this teleporter.

		Story.Frame.Trigger.Touched:Connect(function(hit)

Hello Ze_tsu, Thank you, very, very much for your response!

I do not know how to detect any errors when this occurs. This is because this happens when the game is live, not in studio. Sometimes when I visit, I just find the game broken.

Maybe I am making too many datastore calls? My guess is there are about 20 players in game at a time. There are about 20 teleports per minute which makes 20 datastore calls total per minute. These numbers are approximate. The datastore is just to keep track of how many times each player has teleported.

I do not think certain id are causing problems because I’ve run through all the teleporters. None of the players have reported problems with specific games. Also, when the game freezes, I can see the last game run, and it is always different. I can later teleport to that game when I restart the servers.

Thank you for helping me with make the de-bounce local. This is great because maybe the entre script will no longer break if there is a single problem. I have updated in my script, see below, but I have not published yet.

I have also added pcalls to dataStore:IncrementAsync and MP:GetProductInfo(id). Are there any other places I should put a pcall? Does it look like I did the pcall correctly?

Thank you again, please see my code updates below. The only way to really test this is to publish, so please give any final advice before I try it.

Thank you so much again!!


for _, Story in pairs(Stories) do
	if Story:IsA("BasePart") then -- You want to make sure its a story before creating the debounce variable
		local DB = false -- This debounce is now local to this teleporter.
		
		Story.Frame.Trigger.Touched:Connect(function(hit)
			
			
			if hit.Parent:FindFirstChild("Humanoid") and DB == false then
				
				DB = true
				
				local character = hit.Parent 
				local player = game.Players:GetPlayerFromCharacter(character)
				
				local id = Story:GetAttribute("ID")  -- Get ID
				
				print(Story.Name, id .. " has been touched by " .. player.Name)
				
				local success, err = pcall(function()
				
					dataStore:IncrementAsync(player.UserId, 1) --Add pcall
					--dataStore:SetAsync(player.UserId, 5) -- Total debug, resets to 5 if I tested alot.
					
				end)
					
				print(player.savedata.LastStory.Value)
				player.savedata.LastStory.Value = id
				print(player.savedata.LastStory.Value .. " Oh yeah!")
				
				
				local success, err = pcall(function()

					local playerUserId = "Player_" .. player.UserId
					playerData:SetAsync(playerUserId, player.savedata.LastStory.Value) --Saves player data

				end)
				
				
				local PlayParticle = RS.PlayParticle -- put play particle on Story
				local clonedPlayParticle = PlayParticle:Clone()
				clonedPlayParticle.Parent = Story
				
				character:WaitForChild("Humanoid").Jump = true
				
				wait()
				
				character.HumanoidRootPart.Anchored = true
				
				-----setupNowPlaying-----------------------------
				
				
				local success, err = pcall(function()
					
					local Details = MP:GetProductInfo(id) --Add pcall here

					local StoryName = Details.Name
					print(StoryName)
					popularTitle.Text = StoryName

					local StoryCreator = Details.Creator.Name
					print(StoryCreator)
					popularAuthor.Text = StoryCreator

					local iconID = Details.IconImageAssetId  --get the image


					if iconID ~= 0 then -- check if there truly is an image
						popularImage.Texture = "rbxthumb://type=Asset&id="..iconID.."&w=150&h=150" --set the image
					end
					
					popularBannor.Text = (player.Name .. " entered " .. StoryName)
				
					popular:SetAttribute("ID", id)
					
				end)
				
				------------------------------------------------------
				
				TS:Teleport(id, player) --Start Telport
				DB = false
				
			end
		end)
	end
end

Update: I ran the above script in studio. No errors. I now made the script live and tested. Things are working fine. So now I need to wait and see if the script breaks in the next day or so (like previously). I am new to using pcalls, please let me know if it looks like I did them correctly, or if there are any obvious mistakes in my code. Thank you again!!

1 Like

I think your current code is fine for what you’re doing. Usually with pcalls you would want to actually utilize the success value (which is the first value pcall returns) for error handling. Basically if success is false then we want our script to do plan b or attempt to repeat the call, etc. But since you aren’t too familiar with pcalls you don’t need to do it. Its not a must, just recommended so the script knows what to do if it encounters an error.

Also change wait() to task.wait() as wait() is deprecated.

P.S you should be able to check errors in game by opening up the dev console. I believe the keybind is f9. You then want to navigate to logs (should automatically default to that page) → and select server so you can see server sided errors.

Hi Ze_tsu,
Thank you, you have helped me learn so much!!

I looked up success and fail with pcalls, and added them in my script to give error messages.

I changed to task.wait() Thank you for letting me know.

I didn’t know how to open the dev console. THANK YOU! This is so helpful, it has opened up a new world of debugging for me.

I added a pcall on Teleport at the end of the script. I found conflicting information on if teleport need a pcall.

The script is running good. Hopefully the occasional breaking will stop now. Thank you so much again! Any final thoughts or observations are always appreciated. Thank you!!


local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")
local dataStore = DataStoreService:GetOrderedDataStore("Teleports")
local MP = game:GetService('MarketplaceService')

local RS = game:GetService("ReplicatedStorage")
local TS = game:GetService("TeleportService")

local popular = game.Workspace.Stories.NowPlaying
local popularTitle = popular.Frame.Title.SurfaceGui.TextLabel
local popularImage = popular.Decal
local popularAuthor = popular.Frame.Author.SurfaceGui.TextLabel
local popularBannor = game.Workspace.Zones.Popular.UpdateBrick.SurfaceGui.TextLabel



local Stories = workspace.Stories:GetChildren()
local DB = false


for _, Story in pairs(Stories) do
	if Story:IsA("BasePart") then -- You want to make sure its a story before creating the debounce variable
		local DB = false -- This debounce is now local to this teleporter.
		
		Story.Frame.Trigger.Touched:Connect(function(hit)
			
			
			if hit.Parent:FindFirstChild("Humanoid") and DB == false then
				
				DB = true
				
				local character = hit.Parent 
				local player = game.Players:GetPlayerFromCharacter(character)
				
				local id = Story:GetAttribute("ID")  -- Get ID
				
				print(player.Name.. " " ..id.. " " ..Story.Name.. " Touched!")
				
				local success, err = pcall(function()
				
					dataStore:IncrementAsync(player.UserId, 1)
					
				end)
				
				if success then
					print(player.Name.. " " ..id.. " " ..Story.Name.. " Count SUCCESS!")
				else
					print(player.Name.. " " ..id.. " " ..Story.Name.. " ****<<ERROR>>**** Count FAIL!!")
				end
				
					

				player.savedata.LastStory.Value = id

				
				
				local success, err = pcall(function()

					local playerUserId = "Player_" .. player.UserId
					playerData:SetAsync(playerUserId, player.savedata.LastStory.Value) --Saves player data

				end)
				
				if success then
					print(player.Name.. " " ..id.. " " ..Story.Name.. " LastStory SUCCESS!")
				else
					print(player.Name.. " " ..id.. " " ..Story.Name.. " ****<<ERROR>>**** LastStory FAIL!!")
				end
				
				
				local PlayParticle = RS.PlayParticle -- put particle effect on Story
				local clonedPlayParticle = PlayParticle:Clone()
				clonedPlayParticle.Parent = Story
				
				character:WaitForChild("Humanoid").Jump = true
				
				task.wait()
				
				character.HumanoidRootPart.Anchored = true
				
				-----setupNowPlaying-----------------------------
				
				
				local success, err = pcall(function()
					
					local Details = MP:GetProductInfo(id) --Add pcall here

					local StoryName = Details.Name
					popularTitle.Text = StoryName

					local StoryCreator = Details.Creator.Name
					popularAuthor.Text = StoryCreator
					
					print (player.Name.. " " ..id.. " " ..Story.Name, StoryName.. " by " ..StoryCreator)
					
					local iconID = Details.IconImageAssetId  --get the image


					if iconID ~= 0 then -- check if there truly is an image
						popularImage.Texture = "rbxthumb://type=Asset&id="..iconID.."&w=150&h=150" --set the image
					end
					
					popularBannor.Text = (player.Name .. " entered " .. StoryName)
				
					popular:SetAttribute("ID", id)
					
				end)
				
				if success then
					print(player.Name.. " " ..id.. " " ..Story.Name.. " Now Playing SUCCESS!")
				else
					print(player.Name.. " " ..id.. " " ..Story.Name.. " ****<<ERROR>>**** Now Playing FAIL!!")
				end
				
				
				------------------------------------------------------
				local success, err = pcall(function()
					
					TS:Teleport(id, player) --Start Telport
				end)
					
				if success then
					print(player.Name.. " " ..id.. " " ..Story.Name.. " Teleport SUCCESS!")
				else
					print(player.Name.. " " ..id.. " " ..Story.Name.. " ****<<ERROR>>**** Teleport FAIL!!")
				end

				
				DB = false
				
			end
		end)
	end
end