How to save a string value?

Don’t use the JSONEncode() and JSONDecode() functions - they are unneccessary. Tables consisting of numbers, booleans, or strings will save just fine.
Try adding the BindToClose() function from above.

This is my code:

local DataStoreService = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")

local DataStore = DataStoreService:GetDataStore("ABCDE")

-- Function to load player data
local function loadPlayerData(player)
	local key = "Player_" .. player.UserId

	local success, data = pcall(function()
		return DataStore:GetAsync(key)
	end)

	if success then
		return data
	else
		warn("Failed to load data for player " .. player.Name)
		return nil
	end
end

-- Function to save player data
local function savePlayerData(player, data)
	local key = "Player_" .. player.UserId

	local success, errorMessage = pcall(function()
		DataStore:SetAsync(key, data)
	end)

	if not success then
		warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
	end
end

-- Create leaderstats and set initial values
local function setupLeaderstats(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"

	local forHire = Instance.new("StringValue")
	forHire.Name = "ForHire"
	forHire.Value = "No"
	forHire.Parent = leaderstats

	local hiring = Instance.new("StringValue")
	hiring.Name = "Hiring"
	hiring.Value = "No"
	hiring.Parent = leaderstats

	local posting = Instance.new("StringValue")
	posting.Name = "Posting"
	posting.Value = "No"
	posting.Parent = leaderstats

	local public = Instance.new("StringValue")
	public.Name = "Public"
	public.Value = "No"
	public.Parent = leaderstats

	leaderstats.Parent = player
end

-- Connect the function to player added event
Players.PlayerAdded:Connect(function(player)
	local playerData = HttpService:JSONDecode(loadPlayerData(player))

	if not playerData then
		setupLeaderstats(player)
	else
		if playerData == nil then
			playerData = {
				player:WaitForChild("leaderstats").ForHire.Value == playerData.ForHire;
				player:WaitForChild("leaderstats").Hiring.Value == playerData.Hiring;
				player:WaitForChild("leaderstats").Posting.Value == playerData.Posting;
				player:WaitForChild("leaderstats").Public.Value == playerData.Public;
			}
		end
	end
end)

-- Connect the function to player removing event to save data
Players.PlayerRemoving:Connect(function(player)
	local playerData = {
		ForHire = player:WaitForChild("leaderstats").ForHire.Value,
		Hiring = player:WaitForChild("leaderstats").Hiring.Value,
		Posting = player:WaitForChild("leaderstats").Posting.Value,
		Public = player:WaitForChild("leaderstats").Public.Value
	}

	savePlayerData(player, HttpService:JSONEncode(playerData))
end)

local runService = game:GetService("RunService")
game:BindToClose(function()
	if runService:IsStudio() then task.wait(3) return end
	for _, player in pairs(game.Players:GetPlayers()) do
		savePlayerData(player) --replace with your saving function
	end
	task.wait(3)
end)

I added the bind to close event, nothing shows up still:

Capture

Remove the JSON endoce and decode parts. Then, try resetting your own data server-side and see if it saves.

I also noticed you aren’t sending any player data to save in the BindToClose() function.

ps - `game:GetService(“RunService”) should go at the top of the script, it’s just good etiquette :smiley:

Alright, new updates:

MY LEADERSTATS:

Capture

MY CODE:

local DataStoreService = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local runService = game:GetService("RunService")

local DataStore = DataStoreService:GetDataStore("ABCDE")

-- Function to load player data
local function loadPlayerData(player)
	local key = "Player_" .. player.UserId

	local success, data = pcall(function()
		return DataStore:GetAsync(key)
	end)

	if success then
		return data
	else
		warn("Failed to load data for player " .. player.Name)
		return nil
	end
end

-- Function to save player data
local function savePlayerData(player, data)
	local key = "Player_" .. player.UserId

	local success, errorMessage = pcall(function()
		DataStore:SetAsync(key, data)
	end)

	if not success then
		warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
	end
end

-- Create leaderstats and set initial values
local function setupLeaderstats(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"

	local forHire = Instance.new("StringValue")
	forHire.Name = "ForHire"
	forHire.Value = "No"
	forHire.Parent = leaderstats

	local hiring = Instance.new("StringValue")
	hiring.Name = "Hiring"
	hiring.Value = "No"
	hiring.Parent = leaderstats

	local posting = Instance.new("StringValue")
	posting.Name = "Posting"
	posting.Value = "No"
	posting.Parent = leaderstats

	local public = Instance.new("StringValue")
	public.Name = "Public"
	public.Value = "No"
	public.Parent = leaderstats

	leaderstats.Parent = player
end

-- Connect the function to player added event
Players.PlayerAdded:Connect(function(player)
	local playerData = loadPlayerData(player)

	if not playerData then
		setupLeaderstats(player)
	else
		if playerData == nil then
			playerData = {
				player:WaitForChild("leaderstats").ForHire.Value == playerData.ForHire;
				player:WaitForChild("leaderstats").Hiring.Value == playerData.Hiring;
				player:WaitForChild("leaderstats").Posting.Value == playerData.Posting;
				player:WaitForChild("leaderstats").Public.Value == playerData.Public;
			}
		end
	end
end)

-- Connect the function to player removing event to save data
Players.PlayerRemoving:Connect(function(player)
	local playerData = {
		ForHire = player:WaitForChild("leaderstats").ForHire.Value,
		Hiring = player:WaitForChild("leaderstats").Hiring.Value,
		Posting = player:WaitForChild("leaderstats").Posting.Value,
		Public = player:WaitForChild("leaderstats").Public.Value
	}

	savePlayerData(player)
end)

game:BindToClose(function()
	if runService:IsStudio() then task.wait(3) return end
	for _, player in pairs(game.Players:GetPlayers()) do
		savePlayerData(player) --replace with your saving function
	end
	task.wait(3)
end)

MY PROBLEM:

Still doesn’t save.

It also could be to do with your loading function. The second variable sent to the pcall() holds an error message, if thrown.

--how a pcall() works
local success, errorMessage = pcall(function()
    --code here
end)

if success then --no errors
    print("Yay it worked")
elseif not success and err then
    warn("it didnt work :C")
end

You are returning the second parameter (not the data), which is nil because the data loaded successfully. Instead try:

local data
local success, err = pcall(function()
    data = myDataStore:GetAsync(key)
end)
if success then
    return data
else
    warn(err)
    warn("Couldn't load data")
end

ON JOIN LEADERSTATS:

Capture
Don’t mind the different values, I changed them using another script that toggles it. This is to see if the saveData script worked.

ON JOIN PRINT:

Capture

ON LEAVE PRINT:

ON REJOIN LEADERSTATS:

Capture

ON REJOIN PRINT:

Capture

Line 32 is this:

warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)

Thanks again to all who reply.

Hmm you dont seem to be passing the player’s Data when you call the function, when you call the save function, add you player data parameter, that should fix it :smiley:

can you show me in the code, I don’t know where.

replace your code snippet with this:

Players.PlayerRemoving:Connect(function(player)
	local playerData = {
		ForHire = player:WaitForChild("leaderstats").ForHire.Value,
		Hiring = player:WaitForChild("leaderstats").Hiring.Value,
		Posting = player:WaitForChild("leaderstats").Posting.Value,
		Public = player:WaitForChild("leaderstats").Public.Value
	}

	savePlayerData(player, playerData)
end)

local runService = game:GetService("RunService")
game:BindToClose(function()
	if runService:IsStudio() then task.wait(3) return end
	for _, player in pairs(game.Players:GetPlayers()) do
        local playerData = {
		ForHire = player:WaitForChild("leaderstats").ForHire.Value,
		Hiring = player:WaitForChild("leaderstats").Hiring.Value,
		Posting = player:WaitForChild("leaderstats").Posting.Value,
		Public = player:WaitForChild("leaderstats").Public.Value
	    }

		savePlayerData(player, playerData) --replace with your saving function
	end
	task.wait(3)
end)

didnt save when I rejoined, but progress is being made!

Capture

the output says: Yay it worked!

but it didn’t save.

change your playeradded code to this:

Players.PlayerAdded:Connect(function(player)
	local playerData = loadPlayerData(player)

	if not playerData then
		setupLeaderstats(player)
	else
		player:WaitForChild("leaderstats").ForHire.Value == playerData.ForHire;
		player:WaitForChild("leaderstats").Hiring.Value == playerData.Hiring;
		player:WaitForChild("leaderstats").Posting.Value == playerData.Posting;
		player:WaitForChild("leaderstats").Public.Value == playerData.Public;
	end
end)

Still doesn’t save

Capture

right. you need to print the playerData table for further debugging, that will help locate the error better.

1 Like

Correct me if I’m wrong but I am pretty sure you can save tables and I have a script that does something like that unless I’m reading your comment wrong

game.Players.PlayerAdded:Connect(function(player)
	local inv = Instance.new("Folder")
	inv.Name = "Inventory"
	inv.Parent = player
	
	local strength = Instance.new("IntValue")
	strength.Name = "Strength"
	strength.Value = 0
	strength.Parent = inv
	
	local speed = Instance.new("IntValue")
	speed.Name = "Speed"
	speed.Parent = inv
	
	local data = statstore:GetAsync(player.UserId)
	if data then
		print("data got")
		strength.Value = data["Strength"]
	end
end)

game.Players.PlayerRemoving:Connect(function(plyr)
	print(plyr.Name.. "left")
	local datasave = {
		Strength = plyr.Inventory.Strength.Value,
		Speed = plyr.Inventory.Speed.Value
	}
	local succ,errs = pcall(function()
		statstore:UpdateAsync(plyr.UserId, function(oldvalue)
			local newvalue = datasave or oldvalue
			return newvalue
		end)
	end)
	if succ then
		print("saved")
	else
		print("not save")
	end
end)

:face_exhaling: Still now working! Here is all of the information you should need:

MY ISSUE:

None of my data is saving when I leave the game and rejoin


MY CODE:

local DataStoreService = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local runService = game:GetService("RunService")

local DataStore = DataStoreService:GetDataStore("ABCDEF")

-- Function to load player data
local function loadPlayerData(player)
    local key = "Player_" .. player.UserId

    local success, errorMessage = pcall(function()
        return DataStore:GetAsync(key)
    end)

    if success then --no errors
        print("Player data loaded successfully for", player.Name)
    elseif not success and errorMessage then
        warn("Failed to load data for player " .. player.Name .. ": " .. errorMessage)
    end
end

-- Function to save player data
local function savePlayerData(player, data)
    local key = "Player_" .. player.UserId

    local success, errorMessage = pcall(function()
        DataStore:SetAsync(key, data)
    end)

    if success then
        print("Player data saved successfully for", player.Name)
    else
        warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
    end
end

-- Create leaderstats and set initial values
local function setupLeaderstats(player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"

    local forHire = Instance.new("StringValue")
    forHire.Name = "ForHire"
    forHire.Value = "No"
    forHire.Parent = leaderstats

    local hiring = Instance.new("StringValue")
    hiring.Name = "Hiring"
    hiring.Value = "No"
    hiring.Parent = leaderstats

    local posting = Instance.new("StringValue")
    posting.Name = "Posting"
    posting.Value = "No"
    posting.Parent = leaderstats

    local public = Instance.new("StringValue")
    public.Name = "Public"
    public.Value = "No"
    public.Parent = leaderstats

    leaderstats.Parent = player
end

-- Connect the function to player added event
Players.PlayerAdded:Connect(function(player)
    local playerData = loadPlayerData(player)

    if not playerData then
        setupLeaderstats(player)
    else
        player:WaitForChild("leaderstats").ForHire.Value = playerData.ForHire;
        player:WaitForChild("leaderstats").Hiring.Value = playerData.Hiring;
        player:WaitForChild("leaderstats").Posting.Value = playerData.Posting;
        player:WaitForChild("leaderstats").Public.Value = playerData.Public;
    end
end)

Players.PlayerRemoving:Connect(function(player)
    local playerData = {
        ForHire = player:WaitForChild("leaderstats").ForHire.Value,
        Hiring = player:WaitForChild("leaderstats").Hiring.Value,
        Posting = player:WaitForChild("leaderstats").Posting.Value,
        Public = player:WaitForChild("leaderstats").Public.Value
    }

    savePlayerData(player, playerData)
end)

game:BindToClose(function()
    if runService:IsStudio() then task.wait(3) return end
    for _, player in pairs(game.Players:GetPlayers()) do
        local playerData = {
            ForHire = player:WaitForChild("leaderstats").ForHire.Value,
            Hiring = player:WaitForChild("leaderstats").Hiring.Value,
            Posting = player:WaitForChild("leaderstats").Posting.Value,
            Public = player:WaitForChild("leaderstats").Public.Value
        }

        savePlayerData(player, playerData)
    end
    task.wait(3)
    print("Server shutting down. Player data saved.")
end)


PICTURES
ON JOIN LEADERSTATS

Capture

ON JOIN PRINT STATEMENT

ON LEAVE PRINT STATEMENT

Capture

ON REJOIN LEADERSTATS

Capture

ON REJOIN PRINT STATEMENT


MY VIDEO

https://www.youtube.com/watch?v=VaA-rSvNwhw


Anything else I should know?

Thanks to everyone again for helping me out.

If anybody else has any more information, i’d love to hear it!

Anybody else have anything?? I really need this done.