Script doesn't work in player, works in Studio

My script works just fine when playing in studio testing, but when I play the game from the site or app It always starts off with the UI visible and nonfunctional unless I die. What is going on, again it works without issue in studio?

local RunService = game:GetService("RunService")

local function spinObject(object)
	local function onRenderStepped()
		object.CFrame = object.CFrame * CFrame.Angles(0, 0, 0.05)
	end

	local connection = RunService.RenderStepped:Connect(onRenderStepped)

	object.AncestryChanged:Connect(function(_, parent)
		if not parent then
			connection:Disconnect()
		end
	end)
end

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StartGameEvent = ReplicatedStorage:WaitForChild("StandardRun")
local PracticeModeEvent = ReplicatedStorage:WaitForChild("PracticeMode")
local GameOverEvent = ReplicatedStorage:WaitForChild("GameOver")
local EndGameEvent = ReplicatedStorage:WaitForChild("EndGameEvent")
local ResetGameEvent = ReplicatedStorage:WaitForChild("ResetGame")
local PlayerLoseLifeEvent = game.ReplicatedStorage:WaitForChild("PlayerLoseLife")

local player = game.Players.LocalPlayer
local gui = script.Parent
local TextLabel


local defaultLivesMapping = {
	StandardRun = 10,--for testing purposes as I still need to reset data when you game over
}

local currentGameMode = "StandardRun"

local remainingLives = player:WaitForChild("RemainingLives")

local gameStarted = false

local function updateTextLabel()
	if TextLabel then
		if gameStarted then
			if currentGameMode == "PracticeMode" then
				TextLabel.Parent.Visible = false -- Hide the lives UI in PracticeMode
			else
				TextLabel.Text = remainingLives.Value
				if TextLabel.Parent and TextLabel.Parent.LivesText then
					TextLabel.Parent.LivesText.Text = "Lives"
				end
				TextLabel.Parent.Visible = true
			end
		else
			TextLabel.Text = "X"
			TextLabel.Parent.Visible = false
			TextLabel.Parent.Parent.Reset.TextButton.Visible = false
		end
	end
end

player.PlayerGui.ChildAdded:Connect(function(child)
	if child.Name == "Hud" then
		TextLabel = child.Lives:WaitForChild("LivesValue")
		updateTextLabel()
	end
end)

local function shakeTextLabel()
	if TextLabel and gameStarted then
		local originalPosition = TextLabel.Position
		local originalTextColor = TextLabel.TextColor3
		local duration = 0.4
		local intensity = 7

		local startTime = tick()
		local function updateShake()
			local currentTime = tick() - startTime
			if currentTime <= duration then
				local offsetX = math.random() * intensity * 2 - intensity
				local offsetY = math.random() * intensity * 2 - intensity
				TextLabel.Position = UDim2.new(originalPosition.X.Scale, originalPosition.X.Offset + offsetX, originalPosition.Y.Scale, originalPosition.Y.Offset + offsetY)
				TextLabel.TextColor3 = Color3.new(1, 0.313725, 0.313725)
				TextLabel.Text = "-1"
			else
				TextLabel.Position = originalPosition
				TextLabel.TextColor3 = originalTextColor
				TextLabel.Text = remainingLives.Value
				shakeConnection:Disconnect()
				PlayerLoseLifeEvent:FireServer(remainingLives.Value)
			end
		end
		shakeConnection = game:GetService("RunService").Heartbeat:Connect(updateShake)
	end
end

local function handleLifeCoinInteraction(coin)
	if gameStarted then
		remainingLives.Value = remainingLives.Value + 1
		updateTextLabel()
		coin.Attachment.Sparkle:Stop()
		game.Soundscape:PlayLocalSound(game.Soundscape.LifeUp)
		coin.Transparency, coin.Icon.Transparency, coin.Icon2.Transparency = 0.9, 0.9, 0.9
		coin.Attachment.PointLight.Enabled, coin.Highlight.Enabled = false, false
		coin.Attachment.CollectionParticle.Enabled = true
		wait(0.1)
		coin.Attachment.CollectionParticle.Enabled = false
		PlayerLoseLifeEvent:FireServer(remainingLives.Value)
	end
end

local function connectLifeCoinTouched(coin)
	local touchedConnection

	touchedConnection = coin.Touched:Connect(function(hit)
		local character = hit.Parent
		local humanoid = character:FindFirstChild("Humanoid")

		if humanoid and gameStarted and player == game.Players:GetPlayerFromCharacter(character) then
			if touchedConnection then
				touchedConnection:Disconnect()
			else
				print("Error: touchedConnection is nil")
			end

			handleLifeCoinInteraction(coin)
		end
	end)
end

local function resetLifeCoins()
	if gameStarted then
		for _, coin in pairs(game.Workspace.LifeCoins:GetChildren()) do
			connectLifeCoinTouched(coin)
			spawn(function() spinObject(coin) end)
		end
	end
end

resetLifeCoins()

player.CharacterAdded:Connect(function(character)
	local humanoid = character:WaitForChild("Humanoid")

	humanoid.Died:Connect(function()
		if gameStarted then
			if currentGameMode ~= "PracticeMode" then
				if remainingLives.Value > 1 then
					remainingLives.Value = remainingLives.Value - 1
					game.Soundscape:PlayLocalSound(game.Soundscape.Die)
					shakeTextLabel()
				else
					remainingLives.Value = defaultLivesMapping[currentGameMode]
					if GameOverEvent then
						GameOverEvent:FireServer(player)
					end

					local lifeCoinsFolder = game.Workspace:FindFirstChild("LifeCoins")
					if lifeCoinsFolder then
						lifeCoinsFolder:Destroy()
					end

					if currentGameMode == "StandardRun" then
						game.ReplicatedStorage.LifeCoins:Clone().Parent = game.Workspace
					end

					wait(1)
					resetLifeCoins()
				end
			else
				-- Play "Die" sound when the player dies in practice mode
				game.Soundscape:PlayLocalSound(game.Soundscape.Die)
			end

			updateTextLabel()
		end
	end)
end)

StartGameEvent.OnClientEvent:Connect(function()
	currentGameMode = "StandardRun"
	remainingLives.Value = defaultLivesMapping[currentGameMode]
	gameStarted = true
	TextLabel.Parent.LivesText.Text = "Lives"
	player.PlayerGui.Hud.Reset.TextButton.Visible = true
	updateTextLabel()

	local lifeCoinsFolder = game.Workspace:FindFirstChild("LifeCoins")
	if lifeCoinsFolder then
		lifeCoinsFolder:Destroy()
	end

	game.ReplicatedStorage.LifeCoins:Clone().Parent = game.Workspace
	resetLifeCoins()
end)

PracticeModeEvent.OnClientEvent:Connect(function()
	currentGameMode = "PracticeMode"
	remainingLives.Value = 0 -- No restriction on lives
	gameStarted = true
	TextLabel.Parent.Visible = false -- Hide the Lives UI
	player.PlayerGui.Hud.Reset.TextButton.Visible = true -- Allow resetting the game

	local lifeCoinsFolder = game.Workspace:FindFirstChild("LifeCoins")
	if lifeCoinsFolder then
		lifeCoinsFolder:Destroy()
	end
end)

EndGameEvent.OnClientEvent:Connect(function()
	TextLabel.Parent.Visible = false
	game.Players.LocalPlayer.PlayerGui.Hud.Reset.TextButton.Visible = false
	player.PlayerGui.Hud.Reset.TextButton.Visible = false

	game.Soundscape:PlayLocalSound(game.Soundscape.Goal)

	if currentGameMode == "PracticeMode" then
		gameStarted = false
	end
end)

ResetGameEvent.OnClientEvent:Connect(function()
	remainingLives.Value = defaultLivesMapping[currentGameMode]
	gameStarted = false
	TextLabel.Parent.Visible = false
	player.PlayerGui.Hud.Reset.TextButton.Visible = false

	-- Handle LifeCoins reset
	local lifeCoinsFolder = game.Workspace:FindFirstChild("LifeCoins")
	if lifeCoinsFolder then
		lifeCoinsFolder:Destroy()
	end

	if currentGameMode == "StandardRun" then
		game.ReplicatedStorage.LifeCoins:Clone().Parent = game.Workspace
	end

	resetLifeCoins()

	-- Update the text label
	updateTextLabel()
end)

GameOverEvent.OnClientEvent:Connect(function()
	gameStarted = false
	TextLabel.Parent.Visible = false
	player.PlayerGui.Hud.Reset.TextButton.Visible = false

	-- Handle tools reset
	for _, tool in ipairs(player.Backpack:GetChildren()) do
		if tool:IsA("Tool") then
			tool:Destroy()
		end
	end
	if player.Character:FindFirstChildOfClass("Tool") then
		player.Character:FindFirstChildOfClass("Tool"):Destroy()
	end
end)


-- Assuming the rest of your client-side script is already set up as provided

PlayerLoseLifeEvent.OnClientEvent:Connect(function(loadedRemainingLives)
	-- Update UI or game state with remainingLives
	print("Remaining Lives received on client:", loadedRemainingLives)

	-- Update the UI text label with the loaded remaining lives
	if TextLabel and gameStarted then
		if currentGameMode == "PracticeMode" then
			TextLabel.Parent.Visible = false -- Hide the lives UI in PracticeMode
		else
			TextLabel.Text = loadedRemainingLives
			TextLabel.Parent.LivesText.Text = "Lives"
			TextLabel.Parent.Visible = true
		end
	end
end)

-- Connect to the CheckPointReached event from ReplicatedStorage
local CheckPointReachedEvent = ReplicatedStorage:WaitForChild("CheckPointReached")
CheckPointReachedEvent.OnClientEvent:Connect(function()
	-- Print remainingLives value
	print("Reached checkpoint! Remaining Lives:", remainingLives.Value)

	-- Fire PlayerLoseLifeEvent with remainingLives value
	PlayerLoseLifeEvent:FireServer(remainingLives.Value)
end)
2 Likes

Check if you published to Roblox, which enables any new updates you made since your last update. To publish to Roblox, simply click Alt + P at the same time.

1 Like

I have a habit of publishing obsessively. Despite being published it doesn’t seem to matter

Could we try add a task.wait(1) at the start of the script?

This is just to check to see if the script is running to quickly before your character loads in.

1 Like

I tried that already it didn’t work

Could I ask what the script is meant to do?

It’s meant to set up a lives system and handle a few gamemodes that change how the lives work. Also transfers that data tothe server to save them between sessions and load them

If I’m reading this correctly, this only works when your character dies right?

Could it be an issue in the .CharacterAdded event?

Since your functions are never really called unless your character dies.

1 Like

The thing I’m perplexed about is that it works as intended in studio. It just doesn’t work when playing elsewhere so it obviously just works in general but something is up specifically when I’m doing it from the game’s page. I wouldnt even know this was happening if i didnt think of trying that

I see.

Generally the reason for this is because the script runs faster than the character can load. I would ask what you’ve done to troubleshoot the issue but I’ll assume it might be a long list that will waste your time.

So if it’s okay with you, I’ll reply with questions just to better understand the issue.

Where is this script located?

In Starterplayer > StarterPlayerScripts

Okay, I’m only wondering because you have:

local gui = script.Parent
2 Likes

It would likely be tedious, but you could add a ton of print statements (like checking each if statement) and see where the script stops working in game. Wherever the print statements stop, then you can be more granular to see what the specific issue is.

1 Like

That’s left over from when I had the script inside of the Lives textlabel I think it isn’t used anywhere else

That’s true I could do that if it really came down to it I suppose

1 Like

Update I forgot about the ingame console and I get this error there

1 Like

What does that line look like?

I removed it because it was just doing something I had already done in the editor. Don’t get an error at all now thogh

TextLabel.Parent.LivesText.Text = "Lives"

I already did thys myself
image

2 Likes