PlayerAdded firing wont work

Hello everyone and i am making data stores using DataStores2. My data sometimes loads and sometimes it doesnt. The reason why it doesnt load is because the player added event wont fire. I do not know why this is. The data store saves great and would load if the event fires. I know this because i put up print commands to test this and it all prints up till the game.Players.PlayerAdded function.

Gyazo link:
https://gyazo.com/e77d46f04346fe5b1fc60cb5a6d9c49a
everything saved that time and it printed everything. After a couple more saving, this happends:

https://gyazo.com/49a8a813a2ecdc36a133d9100c9a0c5f
it only prints up to “DataStores2 Working”. Meaning it doesn’t print the player added.

script

print("ScirptWorking")
local DataStores2 = require(1936396537)

print("Works2")
DataStores2.Combine("Stats","Level","Exp","ExpNeed","Yen","Points","MaxHealth","Stamina","Strength","Quirk","Fame","Faction","GymTime")	
print("DataStores2 Working")


game.Players.PlayerAdded:Connect(function(plr)
	print("PlayerAdded")
	local Ability = nil
	local dataLevel = DataStores2("Level",plr)
	local dataExp = DataStores2("Exp",plr)
	local dataExpNeed = DataStores2("ExpNeed",plr)
	local dataYen = DataStores2("Yen",plr)
	local dataPoints = DataStores2("Points",plr)
	local dataMaxHealth = DataStores2("MaxHealth",plr)
	local dataStamina = DataStores2("Stamina",plr)
	local dataStrength = DataStores2("Strength",plr)
	local dataQuirk = DataStores2("Abillity",plr)
	local dataFame = DataStores2("Fame",plr)
	local dataFaction = DataStores2("Faction",plr)
	local dataGymTime = DataStores2("GymTime",plr)
	
	local stats = Instance.new("Folder", plr)
	stats.Name = "Stats"
	--- Level System
	local Level = Instance.new("NumberValue", stats)
	Level.Name = "Level"
	Level.Value = 1

	local Exp = Instance.new("NumberValue", stats)
	Exp.Name = "Exp"
	Exp.Value = 0

	local ExpNeed = Instance.new("IntValue", stats)
	ExpNeed.Name = "ExpNeed"
	ExpNeed.Value = 100

	--- Money and Spin System
	local Yen = Instance.new("IntValue", stats)
	Yen.Name = "Yen"
	Yen.Value = 100000

	--- Stats System
	local Points = Instance.new("NumberValue", stats)
	Points.Name = "Points"
	Points.Value = 3

	local MaxHealth = Instance.new("IntValue", stats)
	MaxHealth.Name = "MaxHealth"
	MaxHealth.Value = 100

	local Stamina = Instance.new("IntValue", stats)
	Stamina.Name = "Stamina"
	Stamina.Value = 0

	local Quirk = Instance.new("StringValue", stats)
	Quirk.Name = "Abillity"
	Quirk.Value = "Quirkless"

	--- Fame
	local leaderstats = Instance.new("Folder",plr)
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Fame = Instance.new("IntValue")
	Fame.Name = "Fame"
	Fame.Value = 0
	Fame.Parent = leaderstats

	local Faction = Instance.new("StringValue", stats)
	Faction.Name = "Faction"
	Faction.Value = "Civilian"

	local GymTime = Instance.new("IntValue", stats)
	GymTime.Name = "GymTime"
	GymTime.Value = 0

	spawn(function()		

		wait(4)		

		local StaminaBarMax = Instance.new("IntValue",stats)		
		StaminaBarMax.Name = "AbilityStaminaMax"	
		StaminaBarMax.Value =  100 + (plr.Stats.Stamina.Value*5)			

		local StaminaBar = Instance.new("IntValue",stats)	
		StaminaBar.Name = "AbilityStamina"	
		StaminaBar.Value = StaminaBarMax.Value		
	end)

	local Strength = Instance.new("IntValue", stats)
	Strength.Name = "Strength"
	Strength.Value = 0
	
	----LoadData----
	
	if dataLevel:Get() ~= nil then
			Level.Value = dataLevel:Get()
		else
		Level.Value = 0
	end
	
	if dataExp:Get() ~= nil then
		Exp.Value = dataExp:Get()
	else
		Exp.Value = 0
	end
	
	if dataExpNeed:Get() ~= nil then
		ExpNeed.Value = dataExpNeed:Get()
	else
		ExpNeed.Value = 100
	end
	
	if dataYen:Get() ~= nil then
		Yen.Value = dataYen:Get()
	else
		Yen.Value = 100000
	end
	
	if dataPoints:Get() ~= nil then
		Points.Value = dataPoints:Get()
	else
		Points.Value = 3
	end
	
	if dataMaxHealth:Get() ~= nil then
		MaxHealth.Value = dataMaxHealth:Get()
	else
		MaxHealth.Value = 100
	end
	
	if dataStamina:Get() ~= nil then
		Stamina.Value = dataStamina:Get()
	else
		Stamina.Value = 0
	end
	
	if dataQuirk:Get() ~= nil then
		Quirk.Value = dataQuirk:Get()
	else
		Quirk.Value = "Quirkless"
	end
	
	if dataFame:Get() ~= nil then
		Fame.Value = dataFame:Get()
	else
		Fame.Value = 0
	end
	
	if dataFaction:Get() ~= nil then
		Faction.Value = dataFaction:Get()
	else
		Faction.Value = "Civilian"
	end
	
	if dataGymTime:Get() ~= nil then
		GymTime.Value = dataGymTime:Get()
	else
		GymTime.Value = 0
	end
	
	if dataStrength:Get() ~= nil then
		Strength.Value = dataStrength:Get()
	else
		Strength.Value = 0
	end
	
	--// Saving Data Stores
	
game.Players.PlayerRemoving:Connect(function(plr)	
		
		local Fame = plr.leaderstats.Fame
		local stats = plr.Stats
		local quirk = stats.Abillity
		local Stamina = stats.Stamina
		local MaxHealth = stats.MaxHealth
		local Points = stats.Points
		local Yen = stats.Yen
		local ExpNeed = stats.ExpNeed
		local Exp = stats.Exp
		local Level = stats.Level
		local Strength = stats.Strength
		local Faction = stats.Faction
		local GymTime = stats.GymTime
		
		dataLevel:Set(Level.Value)
	
		dataExp:Set(Exp.Value)
	
		dataExpNeed:Set(ExpNeed.Value)
	
		dataPoints:Set(Points.Value)
	
		dataYen:Set(Yen.Value)
	
		dataMaxHealth:Set(MaxHealth.Value)

		dataStamina:Set(Stamina.Value)
	
		dataStrength:Set(Strength.Value)
	
		Ability = Quirk.Value
		dataQuirk:Set(Ability)
	
		dataFame:Set(Fame.Value)
	
		dataFaction:Set(Faction.Value)
	
		dataGymTime:Set(GymTime.Value)
	end)
end)
2 Likes

plr,Name

Is that what i put n the connect function?

First of all the way you’re getting the data isnt efficient, data:Get() gets the data and if it is nil it has a parameter that you can set as an amount for example data:Get(0) this will set the value as 0 If theres no data saved and you can just set it in the creation of the instance instead of doing it after, Now the reason your playeradded isnt functioning right is because you’re closing it after playerremoving and it shouldnt be that way, make sure to put the end) before you do the playerremoving

Ah okay thank you. And so what your saying is that data:Get() can allow me to create a new data if their is not any found more efficiently instead of doing it after?

Also please do not Set the data on playerremoving that isnt recommended, just use DataStore2:Increment(Amount) and it will automatically put it in the data, do not Set on PlayerRemoving, you can also use Set whenever the value changes if you want

1 Like

Oh okay i was thinking on setting when ever the value changes but i thought it would fill up the key requests

no, data is just the word I used to show you what I mean it would be dataStamina:Get(AmountiIfNoData) for you ( for example )

1 Like

Hmm it still seems to not fire the player event, is their anything else i did wrong?

It only fires it sometimes still

https://gyazo.com/08c48ca9d13d1d2b0394c3572db4123f

For one, you are loading DataStore2 first. This means that the player may join before DataStore2 is loaded.

local function PlayerAdded(Player)
-- code
end

-- fire for already joined players
for _,Player in pairs(game.Players:GetPlayers()) do
coroutine.wrap(function() PlayerAdded(Player) end)() -- wrapped in spawn so it doesnt yield the rest of the code
end

game.Players.PlayerAdded:connect(PlayerAdded) -- add an event for all new players

It’s good practice do always do this method, just in case the player loads in before your event connects.

Secondly, Line 7 in your provided code does not align with the “stats is not a valid member” error you’re getting, so if you want help with that we will need additional context.

4 Likes

Alright and the stats is not a valid member of player error is because later down in the code i Instance a new folder called stats to store the values in. And since sometimes my playerAdded fires before data stores 2 is loaded, it does not get a chance to Instance. The errors are from my scripts that test for the players stats

Also do i load the DataStores2 above the PlayerAdded function you made or inside of it

You would do it above it. All that you need to change is moving your function inside of “game.Players.PlayerAdded:Connect()” to a variable i.e a “PlayerAdded” function in my example.

The only difference is that before connecting to PlayerAdded, we use :GetPlayers() to get any already added players, and run it for them first. This way, even if the player loads before your code connects to the event, the PlayerAdded function is still called.

1 Like

Also, the spawn() within the loop is very important - your code yields by loading DataStore stuff, so if you don’t use spawn() then the event wont connect until pre-joined players data is loaded. That would mean any players between :GetPlayers() and the event eventually connecting would be missed.

Does that make sense?

1 Like

I’d recommend using coroutine.wrap instead of spawn, spawn can still yield since it waits for a thread to be freed.

2 Likes

I agree, old habits die hard :wink:

I still use the old way of creating a BindableEvent, connecting it, and firing it, and deleting it all in the same cycle (which fires it immediately), however I didn’t want to confuse any beginner folks with odd bindable thread management lol

2 Likes

Quarantined wrap? oh i read that wrong. i always used spawn how do i corountine.wrap. It sounds hard

Just create a courotine and call it

local function Hi()
    print("Hi")
end

coroutine.wrap(Hi)()

If it’s really confusing, stay with spawn for now and, move onto coroutines later.

1 Like