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

Datastore's SetAsync not working?

The SetAsync in question here is on line 49, the print statement above it fires but the one below does not. I've been cracking away at this for hours, recruiting the help of people on Discord to no avail. If anyone could assist me with this I would be greatly indebted to you.

local Data = game:GetService("DataStoreService"):GetDataStore("Data")

game.Players.PlayerAdded:Connect(function(Player)
	print("Key " .. Player.UserId)
	createCanSave(Player)
	local Success, Result = pcall(getPlayerData, Player)
	if Success then
		print(Result)
		print(Result.Stats.Exp)
		if Result and Result.Stats.Level > 0 then
			print("Got Result")
			setStats(Player, Result.Stats)
			setBackpack(Player, Result.Backpack)
		else
			print("Didnt get Result")
			defaultStats(Player)
			game.ReplicatedStorage.Weapons.StarterSword:Clone().Parent = Player:WaitForChild("Backpack")
		end
	else
		print("Error: " .. Result)
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	print("Key " .. Player.UserId)
	if Player.CanSave.Value then
		print(Player.Name .. " is saving")
		local DataDictionary = {
			Stats = getStats(Player),
			Backpack = getBackpack(Player)
		}
		local Success, Result = pcall(setPlayerData, Player, DataDictionary)
		if Success then
			print("Successfully saved " .. Player.Name)
		else
			print("Error while saving " .. Player.Name .. " Message: " .. Result)
		end
	else
		print(Player.Name .. " can't save")
	end
end)

function getPlayerData(Player)
	return Data:GetAsync(tostring(Player.UserId))
end

function setPlayerData(Player, DataDictionary)
	print("Began SetAsync")
	Data:SetAsync(tostring(Player.UserId), DataDictionary)
	print("Ended SetAsync")
end

function createCanSave(Player)
	local CanSave = Instance.new("BoolValue", Player)
	CanSave.Name = "CanSave"
	CanSave.Value = true
end

--Stats Portion

function setStats(Player, SavedStats)
	local Stats = createStats(Player)
	if SavedStats then
		print("Got SavedStats")
		Stats.Level.Value = SavedStats.Level
		Stats.Exp.Value = SavedStats.Exp
		Stats.Gold.Value = SavedStats.Gold
	end
end

function defaultStats(Player)
	print("Defaulting stats for " .. Player.Name)
	local Stats = createStats(Player)
	Stats.Level.Value = 1
	Stats.Exp.Value = 0
	Stats.Gold.Value = 25
end

function createStats(Player)
	local Stats = Instance.new("Folder", Player)
	Stats.Name = "Stats"
	
	local Level = Instance.new("IntValue", Stats)
	Level.Name = "Level"	
	
	local Exp = Instance.new("IntValue", Stats)
	Exp.Name = "Exp"
	
	local Gold = Instance.new("IntValue", Stats)
	Gold.Name = "Gold"
	
	return Stats
end

function getStats(Player)
	local PlayerStats = {}
	if Player:FindFirstChild("Stats") then
		for _, Stat in pairs(Player.Stats:GetChildren()) do
			print("Saving " .. Player.Name .. "'s " .. Stat.Name .. " = " .. Stat.Value)
			PlayerStats[Stat.Name] = Stat.Value
		end
	end
	print("returning PlayerStats")
	return PlayerStats
end

--Backpack Portion

function setBackpack(Player, SavedWeapons)
	if SavedWeapons then
		print("Got SavedWeapons")
		for _, WeaponName in pairs(SavedWeapons) do
			print("Weapon for loop")
			local Weapon = game.ReplicatedStorage.Weapons:FindFirstChild(WeaponName)
			if Weapon then
				print("Loading " .. Weapon.Name)
				Weapon:Clone().Parent = Player:WaitForChild("Backpack")
				Weapon:Clone().Parent = Player:WaitForChild("StarterGear")
			end
		end
	else
		print("SavedWeapons else fired")
	end	
end

function getBackpack(Player)
	local WeaponsTable = {}
	local EquippedWeapon = getEquippedWeapon(Player)
	if EquippedWeapon then
		print("Saving " .. Player.Name .. "'s " .. EquippedWeapon.Name)
		table.insert(WeaponsTable, EquippedWeapon.Name)
	end
	for _, Weapon in pairs(Player.Backpack:GetChildren()) do
		print("Saving " .. Player.Name .. "'s " .. Weapon.Name)
		table.insert(WeaponsTable, Weapon.Name)
	end
	print("returning WeaponsTable")
	return WeaponsTable
end

function getEquippedWeapon(Player)
	local Character = game.Workspace:FindFirstChild(Player.Name)
	if Character then
		for _, Item in pairs(Character:GetChildren()) do
			if Item:IsA("Tool") then
				return Item
			end
		end	
	end
	return
end

1 answer

✓ Accepted answer

The game closed

When the game is closing, any scripts which yield (Which happens with SetAsync) do not get resumed. As such, you'll need to register a quick yield on close with BindToClose

1 comment

0

Thank you so much, is there a way I can have SetAsync in game.Players.PlayerRemoving and game:BindToClose without throttling?

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