So, I’m trying to script a data store and, I keep getting an error saying, ServerScriptService.Script:19: attempt to index nil with ‘UserId’.
Here’s the code:
local DataStoreService =game:GetService("DataStoreService")
local DataStoreName = DataStoreService:GetDataStore("myDataStore")
local player = game.Players.LocalPlayer
game.Players.PlayerAdded:Connect(function(player)
local Level1 = Instance.new("BoolValue")
Level1.Name = "Level1"
Level1.Parent = player
local Level1Part = workspace.Level1
if Level1.Value == true then
Level1Part:Destroy()
end
end)
local data
local success, errormessage = pcall(function()
data = DataStoreName:GetAsync(player.UserId.."-Level")
end)
if success then
print("Levels Loaded")
else
print("Error")
warn(errormessage)
end
game.Players.PlayerRemoving:Connect(function(player)
local success, errormessage = pcall(function()
DataStoreName:SetAsync(player.UserId.."-Level",player.Level1.Value)
end)
if success then
print("Levels have been saved!")
else
warn(errormessage)
end
end)
If the error says “attempting to index UserID with nil” that means the player isn’t defined correctly. You should make sure the player is defined correctly by using print statements and breakpoints.
In your case you need to remove the player variable that equals game.Players.LocalPlayer, keep the one inside the parameters of Players.PlayerAdded as that will work.
local player = game.Players.LocalPlayer
game.Players.PlayerAdded:Connect(function(player)
You can’t have multiple variables/parameters equal the same thing as it won’t work, remove the local player variable as it won’t work in a ServerScript that only works inside a LocalScript
game.Players.PlayerAdded:Connect(function(player)
local Level1 = Instance.new("BoolValue")
Level1.Name = "Level1"
Level1.Parent = player
local Level1Part = workspace.Level1
if Level1.Value == true then
Level1Part:Destroy()
end
end)
You have created this event which gives you the player object when they join. Use this to access your datastore as so:
game.Players.PlayerAdded:Connect(function(player)
local Level1 = Instance.new("BoolValue")
Level1.Name = "Level1"
Level1.Parent = player
local Level1Part = workspace.Level1
if Level1.Value == true then
Level1Part:Destroy()
end
local data = nil
local success, errormessage = pcall(function()
data = DataStoreName:GetAsync(player.UserId.."-Level")
end)
if success then
print("Levels Loaded")
else
print("Error")
warn(errormessage)
end
end)
local DataStoreService = game:GetService("DataStoreService")
local DataStoreName = DataStoreService:GetDataStore("myDataStore")
game.Players.PlayerAdded:Connect(function(player)
local Level1 = Instance.new("BoolValue")
Level1.Name = "Level1"
Level1.Parent = player
local Level1Part = workspace.Level1
if Level1.Value == true then
Level1Part:Destroy()
end
local data = nil
local success, errormessage = pcall(function()
data = DataStoreName:GetAsync(player.UserId.."-Level")
end)
if success then
-- No data found
if not data then
Level1.Value = false
else -- Data found, set level
Level1.Value = data
end
print("Levels Loaded")
else
warn(errormessage)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local success, errormessage = pcall(function()
DataStoreName:SetAsync(player.UserId.."-Level",player.Level1.Value)
end)
if success then
print("Levels have been saved!")
else
warn(errormessage)
end
end)
This should work
One thing to note, if you are planning on saving people level it would be better to use a numberValue and storing the level in there
Ok, 1, still doesn’t work, 2, What I’m trying to make is a part that blocks off a level. And I want to make it so, when your boolvalue changes to true, the part goes away. And I want to save it to the data store.
Ok, I see the issue.
1: Remove the “player” variable that you defined since this is a server script you made and you can’t access local player in the script. Another reason you have to remove this is because you named the player parameter in the player added event the same thing as your variable “player” so the game has gotten confused.
Summary: “player” variable is attempting to access the client from the server, and the getasync function of the datastore was put outside of the playeradded function.
Down below is code I fixed.
local DataStoreName = DataStoreService:GetDataStore("myDataStore")
game.Players.PlayerAdded:Connect(function(player)
local Level1 = Instance.new("BoolValue")
Level1.Name = "Level1"
Level1.Parent = player
local Level1Part = workspace.Level1
if Level1.Value == true then
Level1Part:Destroy()
end
local data -- You put all the get async stuff after the playeradded function code which is why it didn't work, you put it all after the "end)" of the player added event.
local success, errormessage = pcall(function()
data = DataStoreName:GetAsync(player.UserId.."-Level")
end)
if success then
print("Levels Loaded")
else
print("Error")
warn(errormessage)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local success, errormessage = pcall(function()
DataStoreName:SetAsync(player.UserId.."-Level",player.Level1.Value)
end)
if success then
print("Levels have been saved!")
else
warn(errormessage)
end
end)
Ok, did you enable access to datastores in game settings? And are you testing outside of studio? Datastores can’t be tested inside studio. Go to game settings then security then enable access to api services.