Alright so this is my 3rd time posting this, its more of an update if anything
the full dataStore script
local replicatedStorage = game:GetService("ReplicatedStorage") local saveRemote = replicatedStorage:WaitForChild("Save") local function saveData(plr) -- The functions that saves data local tableToSave = { plr.Data.HasGame.Value, -- First value from the table plr.Data.Hair.Value, plr.Data.Outfit.Value, plr.Data.Accessory.Value, plr.Data.Gender.Value, plr.Data.Blood.Value, plr.Data.Spins.Value, plr.Data.SpinVis.Value } local success, err = pcall(function() DataStore:SetAsync(plr.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save end) if success then print("Data has been saved!") else print("Data hasn't been saved!") warn(err) end end game.Players.PlayerRemoving:Connect(function(plr) -- When a player leaves the game saveData(plr) -- Save the data end) game:BindToClose(function() -- When the server shuts down for _, plr in pairs(game.Players:GetPlayers()) do saveData(plr) -- Save the data end end) --creating data game.Players.PlayerAdded:Connect(function(plr) wait() local folder = Instance.new("Folder", plr) folder.Name = "Data" local HasGame = Instance.new("BoolValue", folder) HasGame.Name = "HasGame" local Hair = Instance.new("StringValue", folder) Hair.Name = "Hair" local Outfit = Instance.new("StringValue", folder) Outfit.Name = "Outfit" local Accessory = Instance.new("StringValue", folder) Accessory.Name = "Accessory" local Gender = Instance.new("StringValue", folder) Gender.Name = "Gender" local Blood = Instance.new("StringValue", folder) Blood.Name = "Blood" local Spins = Instance.new("IntValue", folder) Spins.Name = "Spins" local SpinVis = Instance.new("BoolValue", folder) SpinVis.Name = "SpinVis" --visibiliy of spin button variable ------------------------------------------------------------------------------------------------------------------------SAME HERE local data local success, err = pcall(function() data = DataStore:GetAsync(plr.UserId) end) if success then HasGame.Value = data[1] Hair.Value = data[2] Outfit.Value = data[3] Accessory.Value = data[4] Gender.Value = data[5] Blood.Value = data[6] Spins.Value = data[7] SpinVis.Value = data[8] else print("The player has no data!") -- The default will be set to 0 HasGame.Value = false Hair.Value = "ConfirmedNewSave" Outfit.Value = "ConfirmedOutfitNewSave" Accessory.Value = "ConfirmedHornsNewSave" Gender.Value = "Male" Blood.Value = "Burgundy" Spins.Value = 8 SpinVis.Value = true end end)
like i said before ever since ive added the "SpinVis" variable to the data its all went wrong and the main line where im getting the error of "attempt to index nil with number" is here
if success then HasGame.Value = data[1] Hair.Value = data[2] Outfit.Value = data[3] Accessory.Value = data[4] Gender.Value = data[5] Blood.Value = data[6] Spins.Value = data[7] SpinVis.Value = data[8] else
HasGame.Value = data[1] is where the line of error is but it was working perfectly until SpinVis was added,,
A guy gave me this block of code that made sure I wouldnt get the uhh attempt to index nil with number error, im pretty sure im meant to replace the success part on my original script but im not sure where, you're free to test it all out yourself
local Success, Response = pcall(DataStore.GetAsync, DataStore, Player.UserId) if (Success) then if (Response ~= nil) then -- Load data end else warn(Response) end
Im not sure what he meant by load data as im not even sure which part of my script is the load data part
probably this part here but i might be wrong
local data local success, err = pcall(function() data = DataStore:GetAsync(plr.UserId) end) if success then HasGame.Value = data[1] Hair.Value = data[2] Outfit.Value = data[3] Accessory.Value = data[4] Gender.Value = data[5] Blood.Value = data[6] Spins.Value = data[7] SpinVis.Value = data[8] else
I really dont know what else i could possibly do so yeah
You are on the right track - data
is nil, so you have to make sure
An additional thing: game:BindToClose should not save the player data as that should already be happening in PlayerRemoving. Instead, it needs to wait for the saves to complete. Modified script:
local replicatedStorage = game:GetService("ReplicatedStorage") local saveRemote = replicatedStorage:WaitForChild("Save") local savesInProgress = 0 local function saveData(plr) -- The functions that saves data local tableToSave = { plr.Data.HasGame.Value, -- First value from the table plr.Data.Hair.Value, plr.Data.Outfit.Value, plr.Data.Accessory.Value, plr.Data.Gender.Value, plr.Data.Blood.Value, plr.Data.Spins.Value, plr.Data.SpinVis.Value } savesInProgress += 1 local success, err = pcall(function() DataStore:SetAsync(plr.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save end) savesInProgress -= 1 if success then print("Data has been saved!") else print("Data hasn't been saved!") warn(err) end end game.Players.PlayerRemoving:Connect(function(plr) -- When a player leaves the game saveData(plr) -- Save the data end) game:BindToClose(function() -- When the server shuts down while #game.Players:GetPlayers() > 0 do -- Not sure if this loop is required wait() end while savesInProgress > 0 do -- Wait until all saving completes wait() end end) --creating data game.Players.PlayerAdded:Connect(function(plr) -- wait() -- No need for a wait here local folder = Instance.new("Folder", plr) folder.Name = "Data" local HasGame = Instance.new("BoolValue", folder) HasGame.Name = "HasGame" local Hair = Instance.new("StringValue", folder) Hair.Name = "Hair" local Outfit = Instance.new("StringValue", folder) Outfit.Name = "Outfit" local Accessory = Instance.new("StringValue", folder) Accessory.Name = "Accessory" local Gender = Instance.new("StringValue", folder) Gender.Name = "Gender" local Blood = Instance.new("StringValue", folder) Blood.Name = "Blood" local Spins = Instance.new("IntValue", folder) Spins.Name = "Spins" local SpinVis = Instance.new("BoolValue", folder) SpinVis.Name = "SpinVis" --visibiliy of spin button variable local data local success, err = pcall(function() data = DataStore:GetAsync(plr.UserId) end) if success then -- 'success' is only whether it succeeded or not - you can succeed yet have no information (which is what happens for new players) if data then -- check to see if they have any pre-existing data HasGame.Value = data[1] Hair.Value = data[2] Outfit.Value = data[3] Accessory.Value = data[4] Gender.Value = data[5] Blood.Value = data[6] Spins.Value = data[7] SpinVis.Value = data[8] else print("The player has no data!") -- The default will be set to 0 HasGame.Value = false Hair.Value = "ConfirmedNewSave" Outfit.Value = "ConfirmedOutfitNewSave" Accessory.Value = "ConfirmedHornsNewSave" Gender.Value = "Male" Blood.Value = "Burgundy" Spins.Value = 8 SpinVis.Value = true end else warn("Problem getting player's data:", err) end end)
You might also consider other systems that make sure to save things properly/safely and also use autosaves, such as Datastore2 or ProfileService.