Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Still getting the same error: attempt to index nil with number?

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

1 answer

✓ Accepted answer

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.

This discussion is preserved as it was. New answers, comments, and votes are closed.