Hello!
(Please read linked post for more info) Post
This is my first time using DataStore. I’ve added only one value to make it more simple, I will add more once I get the hang of it. My problem is that it wasn’t saving. So I decide to look at the DevHub.
Article
Then I thought I could try to autosave
And so I copied the code and modified it so it would fit what I am trying to do.
Yet while running the code I got this error:
ServerScriptService.SaveData:25: invalid argument #2 (string expected, got nil)
Here’s my autosave code:
I highly reccomend you see my post and read everything to know everything of what’s going on.
local DataStoreService = game:GetService(“DataStoreService”)
local DataStore1 = DataStoreService:GetDataStore(“DataStore1”)
local function saveData(dataStoreKey, value)
local setSuccess, errorMessage = pcall(function()
DataStore1:SetAsync(dataStoreKey, value)
end)
print(value)
if not setSuccess then
warn(errorMessage)
end
end
local function Saving(player)
-- Update data store key
local playerUserID = player.UserId
if DataStore1[playerUserID] then
saveData(playerUserID, DataStore1[playerUserID])
end
end
while true do
wait(5)
local Players = game:GetService("Players")
local Player = Players:GetPlayers()
Saving(Player)
end
If this code is bad/not effective or there’s a better way of doing my inital goal (Autosave Data (all values)) then please tell me.
It means that ‘value’ is being passed as nil, rather than a string. Try printing ‘value’. Also, I’m not sure why you want to autosave, when you can save when the player enters/leaves the game. Seems like a waste of computer power to me.
The reason I am not using that when the player leaves, is as mentionned in the previous post not working. So an autosave every 5-20 seconds would be good. Or even a mannual autosave.
What did ‘value’ print as? .PlayerAdded/.PlayerRemoved not working doesn’t really make sense and is symptomatic of something else going on with your code.
It’s mostly me having problems with PlayerRemoved (as mentionned in previous post). I also tried to use BindToClose since my game is a single player game. I will print everything and comeback quickly.
@PerilousPanther I tried a new script. Here it is. bad news: STILL DOESN’T SAVE.
local DataStoreService = game:GetService("DataStoreService")
local DataStore1 = DataStoreService:GetDataStore("DataStore1")
local success, currentData = pcall(function()
return DataStore1:GetAsync("Player_1234")
end)
if success then
print("Current Data:", currentData)
end
local function saveData(dataStoreKey, value)
local setSuccess, errorMessage = pcall(function()
DataStore1:SetAsync(dataStoreKey, value)
end)
print(value)
if not setSuccess then
warn(errorMessage)
end
end
local function Saving(player, Data)
-- Update data store key
local playerUserID = player.UserId
if Data then
saveData(playerUserID, Data)
print(playerUserID, Data)
end
end
while true do
wait(20)
local Players = game:GetService("Players")
local Player = Players:GetPlayers()
local players = Players:GetPlayers()
for _, player in pairs(players) do
local playerData = {
NickName = player.leaderstats.NickName.Value
}
local userId = player.UserId
local data = playerData[userId]
--print(playerData)
Saving(player, playerData)
end
end
If it could help I can send every scripts. While they are in my previous post it may just save a bit of time.
Ok, so what did it print? I looked at the other post and I’m not sure why you’re using multiple scripts for data loading/saving, or where a potential data leak is coming from. In this kind of situation I think you should start using a datastore module that does a lot of the heavy lifting for you. One of the better ones is ProfileService.
It’s comprehensive, easy to use and enables you to not to worry (generally) about data leaks.
Copied and pasted (I did something in the base script if the value is nil it will be the player’s name)
In order:
18:51:37.717 Current Data: nil - Server - SaveData:9
18:51:37.717 Current Data is: 16Thunderstorm - Server - Data:24
18:51:58.200 ▼ {
[“NickName”] = “16Thunderstorm”
} - Server - SaveData:17
18:51:58.201 484327688 ▼ {
[“NickName”] = “16Thunderstorm”
} - Server - SaveData:28
You’re trying to index a DataStore object with a player id. This is NOT how you use datastores. DataStore:GetAsync() is what you should be using. Also, you shouldn’t be saving the data every 5 seconds, since the maximum rate you can save the same value is every 6 seconds, and you should wait every 60 seconds to autosave. Also, this wont be doing anything regardless since you save the exact same data to the data store.
local DataStoreService = game:GetService("DataStoreService")
local DataStore1 = DataStoreService:GetDataStore("DataStore1")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Name = Instance.new("StringValue")
Name.Name = "NickName"
Name.Parent = leaderstats
local PlayerUserid = "Player_"..player.UserId
local Data
local success, errormessage = pcall(function()
Data = DataStore1:GetAsync(PlayerUserid)
end)
if success then
local leaderstats = player:WaitForChild("leaderstats")
local NickName = leaderstats.NickName
NickName.Value = Data
if Data ~= nil then
Name.Value = Data
print("Current Data is: "..Name.Value)
print("Data: "..Data)
else
Name.Value = Data
print("Data: "..Data)
print(Name.Value)
end
else
print(errormessage)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local PlayerUserid = "Player_"..player.UserId
local Data = player.leaderstats.NickName.Value
local success, errormessage = pcall(function()
DataStore1:SetAsync(PlayerUserid, Data)
end)
if success then
print("Data was saved")
else
print("There was an error")
warn(errormessage)
end
end)
--CHANGE NICKNAME
--CHANGE NICKNAME
--CHANGE NICKNAME
local Event = game.ReplicatedStorage.DumbInfo.NickName -- Put RemoteEvent here
Event.OnServerEvent:Connect(function(Player, Text)
local NickName = Player.leaderstats.NickName
NickName.Value = Text
local success, newName = pcall(function()
return DataStore1:UpdateAsync("Player_1234", Text)
end)
if success then
print("New NickName:", NickName.Value)
end
print("New NickName: "..NickName.Value)
end)
--CHANGE NICKNAME
--CHANGE NICKNAME
--CHANGE NICKNAME
--DEFAULT TEXT
--DEFAULT TEXT
--DEFAULT TEXT
print("TESTING")
game.Players.PlayerAdded:Connect(function(player)
local PlayerUserid = "Player_"..player.UserId
local Data
local success, errormessage = pcall(function()
Data = DataStore1:GetAsync(PlayerUserid)
end)
local GUI = player.PlayerGui:WaitForChild("PlayersCard").Frame.NNFrame
local TextLabel = GUI.Default
local TextBox = GUI.ChangeNickName
print("PLAYER JOINED")
print(player.Name.." is crazy") --I usually write dumb stuff
local leaderstats = player:WaitForChild("leaderstats")
local NickName = leaderstats.NickName
print(NickName.Value, Data)
if Data == "" or nil then
print("There is no text")
TextLabel.Visible = false
else
print("THERE IS TEXT")
TextLabel.Visible = true
TextLabel.Text = NickName.Value
TextBox.Text = NickName.Value
end
end)
-- This part I think a lot of it should be redone.
--DEFAULT TEXT
--DEFAULT TEXT
--DEFAULT TEXT
--SERVER CLOSING
--SERVER CLOSING
--SERVER CLOSING
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
game:BindToClose(function()
-- if the current session is studio, do nothing
if RunService:IsStudio() then
print("YOU'RE IN STUDIO")
return
end
print("saving player data")
-- go through all players, saving their data
local players = Players:GetPlayers()
for _, player in pairs(players) do
local playerData = {
NickName = player.leaderstats.NickName.Value
}
local userId = player.UserId
local data = playerData[userId]
if data then
-- wrap in pcall to handle any errors
local success, result = pcall(function()
-- SetAsync yields so will stall shutdown
DataStore1:SetAsync(userId, data)
end)
if not success then
warn(result)
end
end
end
print("completed saving player data")
end)
--SERVER CLOSING
--SERVER CLOSING
--SERVER CLOSING
--AUTOSAVE
--AUTOSAVE
--AUTOSAVE
local success, currentData = pcall(function()
return DataStore1:GetAsync("Player_1234")
end)
if success then
print("Current Data:", currentData)
end
local function saveData(dataStoreKey, value)
local setSuccess, errorMessage = pcall(function()
DataStore1:SetAsync(dataStoreKey, value)
end)
print(value)
if not setSuccess then
warn(errorMessage)
end
end
local function Saving(player, Data)
-- Update data store key
local playerUserID = player.UserId
if Data then
saveData(playerUserID, Data)
print(playerUserID, Data)
end
end
while true do
wait(20) -- Changed it so it's not so frequent, might make it longer
local Players = game:GetService("Players")
local Player = Players:GetPlayers()
local players = Players:GetPlayers()
for _, player in pairs(players) do
local playerData = {
NickName = player.leaderstats.NickName.Value
}
local userId = player.UserId
local data = playerData[userId]
--print(playerData)
Saving(player, playerData)
end
end
--AUTOSAVE
--AUTOSAVE
--AUTOSAVE
local DataStoreService = game:GetService("DataStoreService")
local DataStore1 = DataStoreService:GetDataStore("DataStore1")
--The basics, we get our DataStore
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Name = Instance.new("StringValue")
Name.Name = "NickName"
Name.Parent = leaderstats
--There will be more
local PlayerUserid = "Player_"..player.UserId
print(PlayerUserid)
--Just for the sake of it.
local Data
local success, errormessage = pcall(function()
Data = DataStore1:GetAsync(PlayerUserid)
end)
if success then
--Getting our leaderstats of the player
local leaderstats = player:WaitForChild("leaderstats")
local NickName = leaderstats.NickName
NickName.Value = Data --Just so the value is changed
if Data ~= nil then --If nothing existed before
Data = player.Name --Default NickNames will be the player’s name.
print("Current Data is: "..Name.Value) --It will be nil
print("Data: "..Data)
else
Name.Value = Data
print("Data: "..Data)
--Nothing needs to be done here
print(Name.Value)
end
else
print(errormessage)
end
end)
I might rewrite this since I will have to add more values.