How to save a string value?

Hello all scripters. I have not been able to find to work this out myself and there is no tutorials on this, can anyone help me?

ISSUE:

I’m trying to find out how to SAVE STRING VALUES WITH DATA STORES! but I cannot figure it out.

Everything that I’ve tried just doesn’t save or breaks the script when I leave and rejoin.

2 Likes

If someone could provide a forum post or script, I’d be very appreciative!

3 Likes

Can you please provide me the script so I can see what is wrong with your script? And also here is an article how to use DataStore if you don’t know how to use it.

2 Likes

Have you tried:

local ds = game:GetService("DataStoreService")
local myStore = ds:GetDataStore("MyDataStore")

--then, when you need it:
local key = --whatever you use to access the store
local myString = --path to the string here
local success, err = pcall(function()
    myDataStore:SetAsync(key, myString)
end)

If you are trying to save the StringValue instance itself, you can’t. The DataStore accepts strings, numbers, and booleans only. Not the instance version.

To get the string from the instance:

local stringValue = --path to the instance here
local myString = stringValue.Value
2 Likes

He’s trying to save the value of the instance I assume.

2 Likes

this is my script:

it doesn’t save, I think maybe it needs a bind to close event or something.

local DataStoreService = game:GetService("DataStoreService")
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 = loadPlayerData(player)

	if not playerData then
		setupLeaderstats(player)
	else
		-- Set values from loaded data
		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)

-- 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, playerData)
end)

I have it so that the value can change, but the problem is that it simply doesn’t save.

here is a video: Devlog Help 1 - YouTube

here is my first attempt: Devlog Help 1 - Developer Forum

2 Likes

Try to run it in the real game in Roblox to see.

1 Like

Why not using Bool values?They can act as a true and false intermediate and it’s much more easier than string values cause i see that the values are just “No” or i assume “Yes”

1 Like

actually, i don’t know if bool values work with leaderstats since i rarely work with leaderstats so nvm

1 Like

Also, calling the function savePlayerData() when the player leaves isn’t very efficient. I’d say that you should save it whenever the value itself changes in another script.

1 Like

As far as I can tell, you are saving a table right here:

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)

Roblox doesn’t allow saving tables, so this wouldn’t work. Try using HttpService:JSONEncode() and HttpService:JSONDecode(). These functions turn a table into a string and vice versa.

Can you write that in a script? I’ve never used JSON.

Sure. Here you go:

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
		-- Set values from loaded data
		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)

-- 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)

Edit: Oops, made a mistake. Use the above updated script.

:frowning: Now nothing shows up in leaderstats

MY LEADERSTATS:

Capture

MY SCRIPT:

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
		-- Set values from loaded data
		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)

-- 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)

MY OUTPUT:

Capture

which is this line
local playerData = HttpService:JSONDecode(loadPlayerData(player))

QUESTIONS TO MAYBE HELP:

  1. What kind of script is this?

  2. Where should I put this script?

  3. I have API Services and HTTP Requests enabled, does that change anything?

  4. Do I need to rewrite this code?

  5. Will this work in studio?

Thanks for all replies!

1 Like

No, Roblox does allow tables to be saved to the DataStore. However, the table can only include:

  1. Numbers
  2. Booleans
  3. Strings
    JSONEncode() and JSONDecode() are unneccessary.
1 Like
  1. Should be a Server Script.
  2. ServerScriptService.
  3. You need that for it to work anyway.
  4. No, the code should be working.
  5. Yes, it should.
    Have you checked if loadPlayerData(player) actually returns anything? Try putting it in a variable and printing it maybe?
1 Like

Oh. Didn’t know that. Thanks!
ignore this it’s for the limit thingy

1 Like

if that’s true, can you rewrite this code?

Looks like the data is nil. This could be due to one of two things:

  1. No data in the DataStore. Could be fixed by setting default data if no data is found:
if playerData == nil then
    playerData = {
       --default data
    }
end
  1. The game doesn’t have enough time to save data before it closes. This can be fixed:
local runService = game:GetService("RunService")
game:BindToClose(function()
    if runService:IsStudio() then task.wait(3) return end --PlayerRemoving will always fire if you are Studio testing
    for _, player in pairs(game.Players:GetPlayers()) do
        save(player) --replace with your saving function
    end
    task.wait(3)
end)

Same as my last error. Nothing works, and the leaderstats is not even showing up.

Capture

The JSONEncode and JSONDecode things are messing it up.

BTW THANKS FOR ALL OF THE SUPPORT!