How to avoid changing Data Key whenever i add a new "Stat" to a Data Table?

So while adding a new Stat to my Data Table i was receiving an error on the output:

image

And i had no clue how to fix this till i changed my Key to something else, then the script recognized the new Stat and worked.

The problem is, i don’t want to change my Key whenever i have to add a new Stat to it for obvious reasons.

So here is how my scripts are Working.

  • First we have the DataStore script, it creates the stats where everything we’ll be stored normally:

image

  • And then we have the Part.Touched script which is the one having issues to recognize new Stats (Unless if i change the Data Key).
local DataStore2 = require(game:GetService("ServerScriptService").DataStore2)
local checkerFlag = script.Parent.CheckerFlag
local winnerPart = script.Parent.WinnerPart
local secondPart = script.Parent.SecondPart
local thirdPart = script.Parent.ThirdPart
local fourPart = script.Parent.FourPart
local fivePart = script.Parent.FivePart
local sixPart = script.Parent.SixPart
local sevenPart = script.Parent.SevenPart
local eightPart = script.Parent.EightPart
local ninePart = script.Parent.NinePart
local tenPart = script.Parent.TenPart
local elevenPart = script.Parent.ElevenPart
local twelvePart = script.Parent.TwelvePart

script.Parent.Parent:GetPropertyChangedSignal("Parent"):Connect(function()
	if script.Parent.Parent.Parent == game.Workspace then
		game.Workspace.GameScripts.Main["Chosen Map"].Value = script.Parent.Parent.Name
	end
end)

local ingameQuantity = #game.Workspace.Ingame:GetChildren()
print("Number of players in this match is: ".. ingameQuantity)

winnerPart.Touched:Connect(function(hit)
	local vals = game.ReplicatedStorage.vals
	local Part = secondPart
	local h = hit.Parent:FindFirstChild("Humanoid")
	local BaseXP = 17
	local BaseRushies = 15
	local GainXP = BaseXP * ingameQuantity
	local GainRushies = BaseRushies * ingameQuantity
	if (h~=nil) then
		if vals.Winner.Value == "" and hit.Parent.Name ~= vals.Winner.Value and vals.Two.Value and vals.Three.Value and vals.Four.Value and vals.Five.Value and vals.Six.Value and vals.Seven.Value and vals.Eight.Value and vals.Nine.Value and vals.Ten.Value and vals.Eleven.Value and vals.Twelve.Value then
		game.ReplicatedStorage.vals.Winner.Value = hit.Parent.Name
		local plr = game.Players[vals.Winner.Value]
		local plrChar = game.Players:GetPlayerFromCharacter(hit.Parent)
		local plrID = plrChar.UserId
		local plrStats = DataStore2("Stats", plrChar):GetAsync()
		plrStats.AllExp = plrStats.AllExp + GainXP
		plrStats.Gold = plrStats.Gold + 1
		plrStats.Exp = plrStats.Exp + GainXP
		plrStats.Rushies = plrStats.Rushies + GainRushies
                plrStats.TestData = plrStats.TestData + 1 -- THIS IS WHERE IT BREAKS
		local plrStats = DataStore2("Stats", plrChar):GetAsync()
		DataStore2("Stats", plrChar):Set(plrStats)

What is the best way to avoid these things or how to do it?

2 Likes

Im slightly confused by your question can you explain your problem a bit better? The error you are getting is because you are attempting to add to a nil number. Check to make sure then things you are adding are actually not nil.

The value that is being called “nil” by the script actually exists, but it doesn’t recognize it unless i change the Data Key to something else

Example:

I created this DataTest “Stat” after the Part.Touched script was already set, so it somehow doesn’t detect the Stat Value and return nil, but if i changed this:

image

To Test4, Test5, or anything else, it will recognize the Stat and stop returning nil

My entire DataStore script:

local DataStore2 = require(game:GetService("ServerScriptService").DataStore2) -- Require the DataStore Module using the name
local MainKey = "Test3"

DataStore2.Combine(MainKey, "Stats")

local function CreateDataTable()
	local PlayerData = {
		Stats = {
        ["Gold"] = 0;
		["Silver"] = 0;
		["Bronze"] = 0;
		["Rushies"] = 0;
		["Level"] = 1;
		["Exp"] = 0;
		["MaxExp"] = 100;
		["ExtraExp"] = 0;
		["AllExp"] = 0;
		["TestData"] = 0;
	};
}
return PlayerData
end

game:GetService("Players").PlayerAdded:Connect(function(plr) -- WHEN PLAYER JOINS --
	local PlayerData = DataStore2(MainKey, plr):GetTable(CreateDataTable()) -- GetPlayersDataTable
	
	local Folder = Instance.new("Folder") -- CURRENT STATS --
	Folder.Name = "PlayerStats"
	
	local Gold = Instance.new("IntValue")
	Gold.Name = "Gold"
	local Silver = Instance.new("IntValue")
	Silver.Name = "Silver"
	local Bronze = Instance.new("IntValue")
	Bronze.Name = "Bronze"
	local Rushies = Instance.new("IntValue")
	Rushies.Name = "Rushies"
	local Level = Instance.new("IntValue")
	Level.Name = "Level"
	local Exp = Instance.new("IntValue")
	Exp.Name = "Exp"
	local MaxExp = Instance.new("IntValue")
	MaxExp.Name = "MaxExp"
	local ExtraExp = Instance.new("IntValue")
	ExtraExp.Name = "ExtraExp"
	local AllExp = Instance.new("IntValue")
	AllExp.Name = "AllExp"
	local TestData = Instance.new("IntValue")
	TestData.Name = "TestData"
	
	local Leaderboard = Instance.new("Folder") -- LEADERSTATS STUFF --
	Leaderboard.Name = "leaderstats"
	
	local LeaderboardWins = Instance.new("IntValue")
	LeaderboardWins.Name = "Wins"
	LeaderboardWins.Value = Gold.Value
	local LeaderboardLv = Instance.new("IntValue")
	LeaderboardLv.Name = "Lv"
	LeaderboardLv.Value = Level.Value


	local StatsData = DataStore2("Stats", plr)
	
	local function UpdateAllStats(UpdatedStats)
		local StatsTable = DataStore2(MainKey, plr):GetTable(UpdatedStats)["Stats"] -- Sets value you've made to correspond with data table
	Gold.Value = StatsTable.Gold
	Silver.Value = StatsTable.Silver
	Bronze.Value = StatsTable.Bronze
	Rushies.Value = StatsTable.Rushies
	Level.Value = StatsTable.Level
	Exp.Value = StatsTable.Exp
	MaxExp.Value = StatsTable.MaxExp
	ExtraExp.Value = StatsTable.ExtraExp
	AllExp.Value = StatsTable.AllExp
	TestData.Value = StatsTable.TestData
	LeaderboardWins.Value = Gold.Value
	LeaderboardLv.Value = Level.Value
	end
	
	UpdateAllStats(PlayerData.Stats) -- Calls the function and updates player data to appropriate values
    DataStore2(MainKey, plr):OnUpdate(UpdateAllStats) -- Calls when updated

    Folder.Parent = plr
    Gold.Parent = Folder
    Silver.Parent = Folder
    Bronze.Parent = Folder 
    Rushies.Parent = Folder
    Level.Parent = Folder
	Exp.Parent = Folder
	MaxExp.Parent = Folder
    ExtraExp.Parent = Folder
    AllExp.Parent = Folder
    TestData.Parent = Folder
	Leaderboard.Parent = plr 
	LeaderboardWins.Parent = Leaderboard
	LeaderboardLv.Parent = Leaderboard
	
	local function UpdateLeaderstats()
		LeaderboardWins.Value = Gold.Value
		LeaderboardLv.Value = Level.Value
	end
	
	Level.Changed:Connect(UpdateLeaderstats)
    Gold.Changed:Connect(UpdateLeaderstats)

	
	Exp:GetPropertyChangedSignal("Value"):Connect(function()
		local plrStats = DataStore2("Stats", plr):Get()
		if plrStats.Exp >= plrStats.MaxExp then
		plrStats.ExtraExp = plrStats.Exp - plrStats.MaxExp
		plrStats.Rushies = plrStats.Rushies
		plrStats.Level = plrStats.Level + 1
		plrStats.Exp = plrStats.ExtraExp
		plrStats.MaxExp = plrStats.MaxExp + 50
		plrStats.ExtraExp = 0
	    DataStore2("Stats", plr):Set(plrStats)
		end
	end)
end)

1 Like

I did some testing and you can fix the problem pretty easily.

		local plrStats = DataStore2("Stats", plrChar):GetAsync()

Does not reference plrStats.Stats and thus everything is nil. Try using

	plrStats.Stats

Or just remove stats all together.

You mean doing this?:

plrStats.Stats.TestData = plrStats.Stats.TestData + 1

It still doesn’t work:

image

I believe your problem comes with using GetAsync() . GetAsync returns a promise and your not doing anything with it use Get() or set it up properly with roblox-lua-promise | roblox-lua-promise
`

I changed it to Get() and now it’s erroring on the new Stat (as it should be)

image

plrStats.DataTest = plrStats.DataTest + 1

I don’t know if this will make any difference but i am using DataStore2 not the default one

Now do PlrStats.Stats.Datatest

Hmm, nope?

image

plrStats.Stats.TestData = plrStats.Stats.TestData + 1 

(It was TestData not DataTest, but it doesn’t work still xD)

Mine works fine are you sure variable names are correct?

Pretty much, as i said before, if i change the Data Key to "Test4, “Test5” or anything else, the DataTest will start working :thinking:

In my data module I make a default data table and compare the index values and ensure there’s nothing missing. I can send you an example of this if you are confused. (On mobile at the moment)

local data = {}
local defaultData = {coins = 0}

local function checkForEmpty()
for i, v in next, defaultData do
if not data[i] then
data[i] = v
end
end
end
checkForEmpty()

Haven’t been able to test this however this should give you an idea.

1 Like

I would appreciate that, please do it :slight_smile:

The problem i am trying to solve right now is:

Whenever i add a new Stat to the image below, it won’t work unless i change the Data Key to something else(Example: TestData), and that’s what i am trying to figure out how to fix:

image

1 Like

You are not using GetTable() Pretty sure you should be using that?

			local plrStats = DataStore2("Stats", plrChar):GetTable(default_table) -- Default table being the default values of everything
		   print(plrStats.Stats.new_value) -- Assuming new_value is a new value added to the table.

But where exactly? i don’t get it

This is the solution if anyone in the future comes across this.

3 Likes