Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Attempted to index a nil value?

Asked by 5 years ago

I get the following error when I try to update the display that tells the player how much money they have:

19:15:32.798 - ServerScriptService.DataManager:47: attempt to index field '?' (a nil value)
19:15:32.798 - Stack Begin
19:15:32.799 - Script 'ServerScriptService.DataManager', Line 47
19:15:32.800 - Stack End

Script inside the serverscriptservice:

local DS = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local Run = game:GetService("RunService")

local playerDataStore = DS:GetDataStore("PlayerData")

local PlayerSesStats = {} -----Player data on current session
local LoadedPlayers = {} -----Players whose data has already been loaded

local UpdEve = game.ReplicatedStorage.UpdateCash

local function DefaultStats()
    return {
        Money = 100
    }
end

local function UpdateCash(player, amount)
    UpdEve:FireClient(player, amount)
end

local function GuestCheck(player) -----Checks wether or not the player is a Guest
    return Run:IsStudio() and player.UserId < 1
end

local function OnPlayerAdded(player)

    local userid = player.UserId

    if LoadedPlayers[userid] then -----Checks wether or not the user's data has been loaded on the current server
        player:Kick("An error occured when attempting to fetch your player data. Please wait a few seconds and rejoin.")
        return
    end

    if not GuestCheck(player) then
        local loadSuccess, LoadedData = pcall(function() return playerDataStore:GetAsync(player.UserId) end) ----- Returns the player's datastore and wether or not it succeeded in that.

    if loadSuccess and LoadedData then
        if LoadedData == nil or LoadedData == {} then
            PlayerSesStats[player.UserId] = DefaultStats()
        else 
            PlayerSesStats[player.UserId] = LoadedData
        end     
    end
    end

    UpdateCash(player, PlayerSesStats[player.UserId].Money)
end

local function OnPlayerRemoved(player)
    if not LoadedPlayers[player.UserId] then
        return
    end

    local SaveData = PlayerSesStats[player.UserId]

    pcall(function()
        playerDataStore:SetAsync(player.UserId, SaveData)
    end)
    LoadedPlayers[player.UserId] = nil
end

local function OnServerShutdown()
    local Players = Players:GetPlayers()

    for index = 1, #Players do
        local player = Players[index]
        OnPlayerRemoved(player)
    end
end


Players.PlayerAdded:Connect(OnPlayerAdded)
Players.PlayerRemoving:Connect(OnPlayerRemoved)

game:BindToClose(OnServerShutdown)

The script that updates the player's currency display:

local Display = script.Parent.MainGui.CashBox.Cash
local UpdEve = game.ReplicatedStorage.UpdateCash

UpdEve.OnClientEvent:Connect(function(amount)
    Display.Text = amount
end)

What is causing the error and how do I fix it? And by the way, am I doing datascripts right so far?

0
Guests don’t exist anymore idk why you coded for guests User#19524 175 — 5y

1 answer

Log in to vote
1
Answered by
Avigant 2374 Moderation Voter Community Moderator
5 years ago

The problem is that PlayerSesStats[player.UserId] is nil, and you are attempting to index the Money key in it.

If the player is a guest, or if the DataStore request failed, or if there was no data to be returned, the player's data in PlayerSesStats will never be created in the first place, so attempting to index it will error.

0
yeah but it errors when i test it in studio and im not a guest radusavin366 617 — 5y
1
Right, because there is no loaded data the first time. Avigant 2374 — 5y
0
I don't seem to find a problem? At line 40 it loads the array from line 13 as PlayerSesStats[userid]??? Can you explain more in depth? radusavin366 617 — 5y
1
Yes, but that code is in this if statement "if loadSuccess and LoadedData then". Avigant 2374 — 5y
0
Oh, got it! thanks. radusavin366 617 — 5y
Ad

Answer this question