Value of type nil cannot be converted to a number

Hi, I have script for data storing and I am running into an issue where I added a new value to the data store script and now im getting “value of type nil cannot be converted to a number”. Can someone help me please?

image

local dataStoreService = game:GetService("DataStoreService")
local amountCollected = dataStoreService:GetDataStore("collected")
local CoinsCollected = dataStoreService:GetDataStore("coins")
local RebirthsCollected = dataStoreService:GetDataStore("Rebirths")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder",player)
	leaderstats.Name = "leaderstats"
	
	local collected = Instance.new("IntValue",leaderstats)
	collected.Name = "Flags"
	collected.Value = 0
	
	local coins = Instance.new("IntValue",leaderstats)
	coins.Name = "Geo-Coins"
	coins.Value = 0
	
	local Rebirths = Instance.new("IntValue",leaderstats)
	Rebirths.Name = "Rebirths"
	Rebirths.Value = 0
	
	local playerUserId = "player_"..player.UserId
	
	local amountcollectedData
	local coinsData
	local rebirthsData
	local success, errormessage = pcall(function()
		amountcollectedData = amountCollected:GetAsync(playerUserId)
		coinsData = CoinsCollected:GetAsync(playerUserId)
		rebirthsData = RebirthsCollected:GetAsync(playerUserId)
	end)
	
	if success then
		coins.Value = coinsData
		collected.Value = amountcollectedData
		Rebirths.Value = rebirthsData
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local playerUserId = "player_"..player.UserId
	local collectedValue = player.leaderstats.Flags.Value
	local coinsValue = player.leaderstats["Geo-Coins"].Value
	local rebirthsValue = player.leaderstats.Rebirths.Value
	
	local success, errormessage = pcall(function()
		amountCollected:SetAsync(playerUserId,collectedValue)
		CoinsCollected:SetAsync(playerUserId,coinsValue)
		rebirthsValue:SetAsync(playerUserId,rebirthsValue)
	end)
end)

game:BindToClose(function()
	for _, player in pairs(game.Players:GetPlayers()) do
		local playerUserId = "player_"..player.UserId
		local collectedValue = player.leaderstats.Flags.Value
		local coinsValue = player.leaderstats["Geo-Coins"].Value
		local rebirthsValue = player.leaderstats.Rebirths.Value

		local success, errormessage = pcall(function()
			amountCollected:SetAsync(playerUserId,collectedValue)
			CoinsCollected:SetAsync(playerUserId,coinsValue)
			RebirthsCollected:SetAsync(playerUserId,rebirthsValue)
		end)
	end
end)
1 Like

does it mention what line the error is?

line 36 where it says

		Rebirths.Value = rebirthsData

so the current problem is rebirths is not saving?

I don’t know if its just because im in studio but yeah it isn’t saving, Im going to test on a test place right now

Yeah no, the rebirths dont save

can you print out rebirthsValue in the if statement

also why are you using a seperate datastore for every single element :sob:

Because i DO NOT understand datastores, and i didnt code it in the first place :sob:

image

then who did, why are you tampering with code that you don’t know what the sigma?!


tbh, i suggest just doing UpdateAsync instead of setting some intvalues, and then use GetAsync whenever the player joins and THEN set the intvalues

while i cannot convert the given code for you, i think you should be fine by just looking at my (quite readable) code (saving data only):

function SaveData()
	for userId, data in pairs(playerDataTable) do
		local success, result = pcall(function()
			local key = tostring(userId)
			
			-- These 2 values here are for serializing the color data
			-- because you can't store color3 values in datastores
			local vitalsGuiColor = data.Settings["Vitals GUI Color"]
			local weaponGuiColor = data.Settings["Weapon GUI Color"]
			
			local vitalsGuiColorSerialized = Serialize(vitalsGuiColor)
			local weaponGuiColorSerialized = Serialize(weaponGuiColor)

			playerDataStorage:UpdateAsync(key, function(oldData)
				oldData = oldData or {} -- No current data will instead initialize an empty table :^)

				local newData = {
					TotalKills = data.TotalKills,
					TotalDeaths = data.TotalDeaths,
					TotalCurrencyEarned = data.TotalCurrencyEarned,
					TotalXpEarned = data.TotalXpEarned,
					CurrentLevel = data.CurrentLevel,
					CurrentWhisper = data.CurrentWhisper,
					Settings = data.Settings
				}
				
				newData.Settings["Vitals GUI Color"] = Serialize(newData.Settings["Vitals GUI Color"])
				newData.Settings["Weapon GUI Color"] = Serialize(newData.Settings["Weapon GUI Color"])

				return newData
			end)
		end)

		if not success then
			warn("Failed to save " .. userId .. "'s data!")
			warn("Error information: ")
			warn(result)
			continue -- Skips to the next iteration so that print 
			-- below doesn't run 
		end

		print("Successfully saved data for " .. userId)
	end
end

Im tampering with it because there was no rebirths and now we need to add rebirths :sob: I’ll try my best to follow along your code

i’ll be playing lost judgment so i’ll probably take a while to reply :grimacing:

1 Like

From what I can see, it’s because you’re trying to use the SetAsync method on rebirthsValue (an integer).

Do this instead:

RebirthsCollected:SetAsync(playerUserId, rebirthsValue)

And do:

if not success then
    warn(errormessage)
end

What exactly am i supposed to change? sorry im a little slow

game.Players.PlayerRemoving:Connect(function(player)
	local playerUserId = "player_"..player.UserId
	local collectedValue = player.leaderstats.Flags.Value
	local coinsValue = player.leaderstats["Geo-Coins"].Value
	local rebirthsValue = player.leaderstats.Rebirths.Value
	
	local success, errormessage = pcall(function()
		amountCollected:SetAsync(playerUserId,collectedValue)
		CoinsCollected:SetAsync(playerUserId,coinsValue)
		RebirthsCollected:SetAsync(playerUserId,rebirthsValue) -- changed
	end)
	
	if not success then -- changed
		warn(errormessage)
	end
end)

Also, I suggest saving player data in one single datastore, with this structure:

type PlayerData = {
	coins : number,
	rebirths : number
	collected : number
}
1 Like

if i store it in one data type, i’d assume i will lose the data?

No, you can store tables in datastores.
For example:

local playerData = {
	coins = player.leaderstats["Geo-Coins"].Value,
	rebirths = player.leaderstats.Rebirths.Value,
	collected = player.leaderstats.Flags.Value
}
PlayerDataStore:SetAsync(playerUserId, playerData)

and then

local playerData = PlayerDataStore:GetAsync(playerUserId)
local coins, rebirths, collected = playerData.coins, playerData.rebirths, playerData.collected

Or, alternatively, if it’s a very large project, you could use buffers, but they’re very complicated and I would only suggest using them if memory use is a big issue.

Okay, I will consider this, thank you so much!

1 Like

No problem. Also, for the type thing, it’s just a way of clarifying to other programmers and to yourself how you structured your data (or if you’re using --!strict mode).
Here’s a link if you want to learn more about it:

I just find it helps me write nicer code that’s easier to understand, and it works very with roblox’s autocomplete, especially with modules that have classes (object orientation).
An example from a project of mine where I made a radio system:

export type user = {
	player : Player,
	radio : radiohandle,
	connection : RBXScriptConnection
}

export type frequency = {
	activeUsers: {user}, -- table containing objects of the user class
	freq: number,
	Close: () -> (), -- function with no arguments, with no return value
	transmitter: ObjectValue,
	Connect: (self : frequency, player : Player, radio : radiohandle) -> RBXScriptConnection, -- method taking a player and radiohandle value and returning a RBXScriptConnection so that it can be disconnected.
	Disconnect: (self : frequency, player : Player, radio : radiohandle, connection : RBXScriptConnection) -> (),
	Transmit: (self : frequency, sourceInstance : AudioListener?) -> boolean, -- method taking the frequency itself as a parameter (common in object oriented programming), and a sourceInstance (the microphone of the transmitting device), and returning a boolean indicating whether the transmission was successful or not
	EndTransmit: (self : frequency) -> ()
}

export type radiohandle = {
	AudioEmitter: AudioEmitter,
	AudioListener: AudioListener,
	Events: Folder,
	Wire: Wire,
	Script: Script
}

local frequencies : {frequency} = {} -- this means that frequencies is a table that contains objects of the "frequency" type defined above