Second function not firing (look at this dialog to laugh at my dumbness)

Hey developers!

I made this script, but inside of the .PlayerAdded function, there are two other functions. The .Changed function doesn’t fire even though the value is changing (yes, on the server). Any help would be appreciated! I really don’t know anything else about it so here is the script:

local coins = game:GetService('Workspace').CoinsCollected
local level = game:GetService('Workspace').LevelAchieved
local lives = game:GetService('Workspace').LivesLeft
local restart = game:GetService('ReplicatedStorage').Restart
local winner = game:GetService('ReplicatedStorage').Winner
local datastore = game:GetService('DataStoreService'):GetDataStore('Highscores')

game:GetService('Players').PlayerAdded:Connect(function(player)
	player.RespawnLocation = game:GetService('Workspace')['1'].Base.Spawn

	player.CharacterAdded:Connect(function(character)
		character:WaitForChild('Humanoid').Died:Connect(function()
			if lives.Value == 1 then
				lives.Value -= 1
				player.Character:Destroy()
				
				if datastore:GetAsync(player.UserId)['Level'] < level.Value then
					datastore:SetAsync(player.UserId, {Level = level.Value, Coins = datastore:GetAsync(player.UserId)['Coins']})
				end
				
				if datastore:GetAsync(player.UserId)['Coins'] < coins.Value then
					datastore:SetAsync(player.UserId, {Level = datastore:GetAsync(player.UserId)['Level'], Coins = coins.Value})
				end
				
				restart:FireClient(player, {Level = datastore:GetAsync(player.UserId)['Level'], Coins = datastore:GetAsync(player.UserId)['Coins']})
			else
				lives.Value -= 1
			end
		end)
	end)
	
	lives.Changed:Connect(function()
		if lives.Value == 6 then
			player.Character:Destroy()

			if datastore:GetAsync(player.UserId)['Level'] < level.Value then
				datastore:SetAsync(player.UserId, {Level = level.Value, Coins = datastore:GetAsync(player.UserId)['Coins']})
			end

			if datastore:GetAsync(player.UserId)['Coins'] < coins.Value then
				datastore:SetAsync(player.UserId, {Level = datastore:GetAsync(player.UserId)['Level'], Coins = coins.Value})
			end

			winner:FireClient(player, {Level = datastore:GetAsync(player.UserId)['Level'], Coins = datastore:GetAsync(player.UserId)['Coins']})
		end
	end)
	
	if not datastore:GetAsync(player.UserId) then
		datastore:SetAsync(player.UserId, {Level = 0, Coins = 0})
	end
end)

restart.OnServerEvent:Connect(function(player)
	coins.Value = 0
	level.Value = 1
	lives.Value = 3
	
	player.RespawnLocation = game:GetService('Workspace')['1'].Base.Spawn
	
	player:LoadCharacter()
end)

Have a great day, iamajust

Hi, so just to clarify workspace.LivesLeft is a value is it?

1 Like

Yes!

List of variables and the type of instance they are:
coins = IntValue
level = IntValue
lives = IntValue
restart = RemoteEvent
winner = RemoteEvent
datastore = a datastore (not an instance lol, is it? so confused rn but it probably isn’t or it’s an instance in like the core part of Roblox. whatever)

Found the problem, the fact that the changed function is in the playeradded function means it won’t run as that function can’t sync like that. You will need to take the changed function out of the playeradded function.

Well, it’s a single-player game so I guess I can just :FireAllClients()?
(Because in that case I can’t use the player variable.)

Well, you could change the function instead to something like:
lives.Changed:Wait()

? It runs multiple times so that would be hard.
And by the way is there any documentation or explanation on this syncing thing inside of functions. I think it could help to know more about it.

How can it run multiple times if it’s a single player game?

You can restart and then win again.

Basically, your function is a playeradded. That means it will run once when that occurs and then stop. Your changed function is kept within this so it can never be reached.

But the .Died function does work correctly. Sorry if I’m dumb.

Does the .Died run after the player joins?

Yeah. It fires whenever the character dies.

That’s strange, it shouldn’t be able to from there.

After some testing, it seems that functions will run from within the playeradded function although it’s still bad practice to do so as it’s a past function.

Have you checked that the changed event is being reached by putting a print statement below it?

It is being reached only when affected by dying, it’s so weird to me. It won’t print when set in any other case while it’s still being changed?

lives.Changed:Connect(function()
    print(lives.Value)
	if lives.Value == 6 then
		player.Character:Destroy()

		if datastore:GetAsync(player.UserId)['Level'] < level.Value then
			datastore:SetAsync(player.UserId, {Level = level.Value, Coins = datastore:GetAsync(player.UserId)['Coins']})
		end

		if datastore:GetAsync(player.UserId)['Coins'] < coins.Value then
			datastore:SetAsync(player.UserId, {Level = datastore:GetAsync(player.UserId)['Level'], Coins = coins.Value})
		end

		winner:FireClient(player, {Level = datastore:GetAsync(player.UserId)['Level'], Coins = datastore:GetAsync(player.UserId)['Coins']})
	end
end)

Can you run your print like this and tell me what it outputs

1 Like

I just realised I’m the dumbest person alive :joy: I don’t understand what all just happened, but it was supposed to be level instead of lives. I’m so sorry for wasting your time.

What do you do in this case? Delete the topic? Mark this comment as the solution?

1 Like

Doesn’t really matter, mark as solution will give me a cool checkmark so :stuck_out_tongue:

1 Like