Hey, I’ve got a Data Store which should be saving the value level, But it’s throwing up the error, “value of type nil cannot be converted to a number - Server - Minutes/Cash:50” This is line 50 - Level.Value = Data.Level
--[ SERVICES ]--
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("TimeStats")
local service = game:GetService("MarketplaceService")
--[ LOCALS ]--
local VIPGamepassId = 853207256 -- VIP GAMEPASS ID
local GamepassId = 853079507 -- GAMEPASS ID
--[ FUNCTIONS ]--
game.Players.PlayerAdded:Connect(function(Player)
--[{ LEADERSTATS }]--
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
Leaderstats.Parent = Player
local Level = Instance.new("IntValue")
Level.Name = "Level" -- changing name here (points, levels, time, etc.)
Level.Value = 0 -- default value
Level.Parent = Leaderstats
local Cash = Instance.new("IntValue")
Cash.Name = "Cash" -- changing name here (points, levels, time, etc.)
Cash.Value = 0 -- default value
Cash.Parent = Player
--[{ DATA STORE }]--
local Data
pcall(function()
Data = DataStore:GetAsync(Player.UserId) -- Get Data
print(Player, "loading data")
end)
if type(Data) ~= "table" then
Data = nil
end
if Data then
Level.Value = Data.Level
Cash.Value = Data.Cash
end
local incrementValue = 1 -- value when adding points
if (service:UserOwnsGamePassAsync(Player.UserId, VIPGamepassId)) then -- 3x gamepass
incrementValue = 3
elseif (service:UserOwnsGamePassAsync(Player.UserId, GamepassId)) then -- 2x gamepass
incrementValue = 2
end
--[{ TIME GIVERS }]--
coroutine.resume(coroutine.create(function() -- gives 1 point every minute
while true do
wait(60) -- every minute
Level.Value = Level.Value + incrementValue -- adds points based off of the incrementValue
end
end))
coroutine.resume(coroutine.create(function() -- gives 1 point every minute
while true do
wait(120) -- every 2 minutes
Cash.Value = Cash.Value + incrementValue -- adds cash
end
end))
end)
game.Players.PlayerRemoving:Connect(function(Player) -- save function here
--[{ DATA STORE SAVING }]--
DataStore:SetAsync(Player.UserId, { -- gets data
Level = Player.leaderstats.Level.Value,
})
end)
--[ SERVICES ]--
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("TimeStats")
local service = game:GetService("MarketplaceService")
--[ LOCALS ]--
local VIPGamepassId = 853207256 -- VIP GAMEPASS ID
local GamepassId = 853079507 -- GAMEPASS ID
--[ FUNCTIONS ]--
game.Players.PlayerAdded:Connect(function(Player)
--[{ LEADERSTATS }]--
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
Leaderstats.Parent = Player
local Level = Instance.new("IntValue")
Level.Name = "Level" -- changing name here (points, levels, time, etc.)
Level.Value = 0 -- default value
Level.Parent = Leaderstats
local Cash = Instance.new("IntValue")
Cash.Name = "Cash" -- changing name here (points, levels, time, etc.)
Cash.Value = 0 -- default value
Cash.Parent = Player
--[{ DATA STORE }]--
local success, Data = pcall(function()
-- Get Data
print(Player, "loading data")
return DataStore:GetAsync(Player.UserId)
end)
if success then
if next(Data) == nil then
Data = nil
end
if Data and (Data.Level and Data.Cash) then
Level.Value = Data.Level
Cash.Value = Data.Cash
end
end
local incrementValue = 1 -- value when adding points
if (service:UserOwnsGamePassAsync(Player.UserId, VIPGamepassId)) then -- 3x gamepass
incrementValue = 3
elseif (service:UserOwnsGamePassAsync(Player.UserId, GamepassId)) then -- 2x gamepass
incrementValue = 2
end
--[{ TIME GIVERS }]--
coroutine.resume(coroutine.create(function() -- gives 1 point every minute
while true do
wait(60) -- every minute
Level.Value = Level.Value + incrementValue -- adds points based off of the incrementValue
end
end))
coroutine.resume(coroutine.create(function() -- gives 1 point every minute
while true do
wait(120) -- every 2 minutes
Cash.Value = Cash.Value + incrementValue -- adds cash
end
end))
end)
game.Players.PlayerRemoving:Connect(function(Player) -- save function here
--[{ DATA STORE SAVING }]--
DataStore:SetAsync(Player.UserId, { -- gets data
Level = Player.leaderstats.Level.Value,
})
end)
This is not a solution to your problem, but I highly recommend using a datastore module such as Suphi’s Datastore Module or ProfileService in order to avoid data loss and other issues that come with Roblox’s default datastore system.
Have a blessed day, however don’t forget to check Data.Level and Data.Cash before setting .Value since if they are nil then you will get this warning: value of type nil cannot be converted to a number.
If you look at Suphi’s youtube video on the module it should be fairly easy to understand and switch your game to work with the module, but if you are a beginner and your game already has players/people with progress I would not recommend doing this as you would need to switch over all their data to work with the module.
Apologies, But I seem to be making short work of this,
I tried, but I am unsure what needs to be changed with this script to update it from the old to new, I’ve watched the video but still abit confused,
--[ SERVICES ]--
local DataStoreModule = require(game.ServerStorage.DataStore2)
local service = game:GetService("MarketplaceService")
--[ LOCALS ]--
local VIPGamepassId = 853207256 -- VIP GAMEPASS ID
local GamepassId = 853079507 -- GAMEPASS ID
--[ FUNCTIONS ]--
game.Players.PlayerAdded:Connect(function(Player)
--[{ LEADERSTATS }]--
local keys = {"Level"}
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
Leaderstats.Parent = Player
local Level = Instance.new("IntValue")
Level.Name = "Level" -- changing name here (points, levels, time, etc.)
Level.Value = 0 -- default value
Level.Parent = Leaderstats
local Cash = Instance.new("IntValue")
Cash.Name = "Cash" -- changing name here (points, levels, time, etc.)
Cash.Value = 0 -- default value
Cash.Parent = Player
--[{ DATA STORE }]--
local success, Data = pcall(function()
-- Get Data
print(Player, "loading data")
return DataStoreModule:GetAsync(Player.UserId)
end)
if success then
if next(Data) == nil then
Data = 0
end
if Data and Data.Level then
Level.Value = Data.Level
Cash.Value = Data.Cash
end
end
local incrementValue = 1 -- value when adding points
if (service:UserOwnsGamePassAsync(Player.UserId, VIPGamepassId)) then -- 3x gamepass
incrementValue = 3
elseif (service:UserOwnsGamePassAsync(Player.UserId, GamepassId)) then -- 2x gamepass
incrementValue = 2
end
--[{ TIME GIVERS }]--
coroutine.resume(coroutine.create(function() -- gives 1 point every minute
while true do
wait(60) -- every minute
Level.Value = Level.Value + incrementValue -- adds points based off of the incrementValue
end
end))
coroutine.resume(coroutine.create(function() -- gives 1 point every minute
while true do
wait(120) -- every 2 minutes
Cash.Value = Cash.Value + incrementValue -- adds cash
end
end))
end)
game.Players.PlayerRemoving:Connect(function(Player) -- save function here
--[{ DATA STORE SAVING }]--
DataStore:SetAsync(Player.UserId, { -- gets data
Level = Player.leaderstats.Level.Value,
})
end)
The way you will write it is pretty different, but at the core it still uses roblox’s datastore system. The module is basically a wrapper that improves upon the functionality of the default roblox datastore system. Also if you are interested in learning WHY exactly using a datastore wrapper is beneficial then I recommend this video: