Issues with datastore

Hello, i’m making an rpg game with many stats and skills, so to store them i have to use datastore service so the player won’t lose his progress but it won’t work, i think the main reason is that there are too many values to store so i would like a solution for this problem.

Thanks

The script:

local players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("MyDataStore")

local function saveData(player)
	local tableToSave = {
		player:WaitForChild("Skills"):WaitForChild("Mining").Value;
		player:WaitForChild("Skills"):WaitForChild("Fists").Value;
		player:WaitForChild("Skills"):WaitForChild("Spears").Value;
		player:WaitForChild("Skills"):WaitForChild("Logging").Value;
		player:WaitForChild("Skills"):WaitForChild("Swords").Value;
		player:WaitForChild("Skills"):WaitForChild("Axes").Value;
		player:WaitForChild("Skills"):WaitForChild("Stealth").Value;
		player:WaitForChild("Skills"):WaitForChild("Agility").Value;
		player:WaitForChild("Skills"):WaitForChild("Speech").Value;
		player:WaitForChild("Skills"):WaitForChild("Block").Value;
		
		player:WaitForChild("Skills"):WaitForChild("Mining"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Fists"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Spears"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Logging"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Swords"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Axes"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Stealth"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Agility"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Speech"):WaitForChild("Experience").Value;
		player:WaitForChild("Skills"):WaitForChild("Block"):WaitForChild("Experience").Value;
		
		player:WaitForChild("Speed").Value;
		player:WaitForChild("Jump").Value;
		player:WaitForChild("Energy").Value;
	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave) 
	end)

	if success then 
		print("Data has been saved!")
	else 
		print("Data hasn't been saved!")
		warn(err)		
	end
end

players.PlayerAdded:Connect(function(player)
	local skills = Instance.new("Folder", player)
	skills.Name = "Skills"
	
	local swords = Instance.new("IntValue", skills)
	swords.Name = "Swords"
	local axes = Instance.new("IntValue", skills)
	axes.Name = "Axes"
	local spears = Instance.new("IntValue", skills)
	spears.Name = "Spears"
	local agility = Instance.new("IntValue", skills)
	agility.Name = "Agility"
	local fists = Instance.new("IntValue", skills)
	fists.Name = "Fists"
	local block = Instance.new("IntValue", skills)
	block.Name = "Block"
	local speech = Instance.new("IntValue", skills)
	speech.Name = "Speech"
	local stealth = Instance.new("IntValue", skills)
	stealth.Name = "Stealth"
	local logging = Instance.new("IntValue", skills)
	logging.Name = "Logging"
	local mining = Instance.new("IntValue", skills)
	mining.Name = "Mining"
	
	local swordsExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Swords"))
	swordsExp.Name = "Experience"
	local axesExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Axes"))
	axesExp.Name = "Experience"
	local spearsExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Spears"))
	spearsExp.Name = "Experience"
	local agilityExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Agility"))
	agilityExp.Name = "Experience"
	local fistsExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Fists"))
	fistsExp.Name = "Experience"
	local blockExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Block"))
	blockExp.Name = "Experience"
	local speechExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Speech"))
	speechExp.Name = "Experience"
	local stealthExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Stealth"))
	stealthExp.Name = "Experience"
	local loggingExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Logging"))
	loggingExp.Name = "Experience"
	local miningExp = Instance.new("IntValue", player:WaitForChild("Skills"):WaitForChild("Mining"))
	miningExp.Name = "Experience"
	
	local Jump = Instance.new("NumberValue")
	Jump.Name = "Jump"
	Jump.Parent = player

	local Speed = Instance.new("NumberValue")
	Speed.Name = "Speed"
	Speed.Parent = player

	local Energy = Instance.new("NumberValue")
	Energy.Name = "Energy"
	Energy.Parent = player
	
	for i, skill in pairs(skills:GetChildren()) do
		local multiplier = Instance.new("IntValue", skill)
		multiplier.Name = "Multiplier"
		local importance = Instance.new("IntValue", skill)
		importance.Name = "Importance"
	end
	
	local data
	local success, err = pcall(function()
		data = dataStore:GetAsync(player.UserId) 
	end)

	if success and data then
		mining.Value = data[1]
		fists.Value = data[2]
		block.Value = data[3]
		spears.Value = data[4]
		agility.Value = data[5]
		speech.Value = data[6]
		stealth.Value = data[7]
		axes.Value = data[8]
		swords.Value = data[9]
		logging.Value = data[10]
		
		miningExp.Value = data[11]
		fistsExp.Value = data[12]
		blockExp.Value = data[13]
		spearsExp.Value = data[14]
		agilityExp.Value = data[15]
		speechExp.Value = data[16]
		stealthExp.Value = data[17]
		axesExp.Value = data[18]
		swordsExp.Value = data[19]
		loggingExp.Value = data[20]
		
		Speed.Value = data[21]
		Jump.Value = data[22]
		Energy.Value = data[23]
	else 
		print("The player has no data!") 
		mining.Value = 0
		fists.Value = 0
		block.Value = 0
		spears.Value = 0
		agility.Value = 0
		speech.Value = 0
		stealth.Value = 0
		axes.Value = 0
		swords.Value = 0
		logging.Value = 0
		
		miningExp.Value = 0
		fistsExp.Value = 0
		blockExp.Value = 0
		spearsExp.Value = 0
		agilityExp.Value = 0
		speechExp.Value =0
		stealthExp.Value = 0
		axesExp.Value = 0
		swordsExp.Value = 0
		loggingExp.Value = 0
		
		Speed.Value = 12
		Jump.Value = 12
		Energy.Value = 100
	end
end)

game.Players.PlayerRemoving:Connect(function(player) 
	local success, err  = pcall(function()
		saveData(player) 
	end)

	if success then
		print("Data has been saved")
	else
		print("Data has not been saved!")
	end
end)
 
game:BindToClose(function() 
	for _, player in pairs(game.Players:GetPlayers()) do 
		local success, err  = pcall(function()
			saveData(player) 
		end)

		if success then
			print("Data has been saved")
		else
			print("Data has not been saved!")
		end
	end
end)



Each datastore has a limit of 4 megabytes. Each character taking one byte. By the looks of it, you are storing number values. You probably don’t need to worry about ever reaching the data limit unless you are storing an entire book or somthing.

As I am reading your script, you have error handling. So does your pcall return anything in output? Any error? Any warning?

The optimized script uses loops to create and save data, which reduces code redundancy. The createSkill function is used to create each skill and its experience sub-value to further reduce code duplication.

local players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("MyDataStore")

local function saveData(player)
    local skills = player:WaitForChild("Skills")
    local tableToSave = {}

    for i, skill in ipairs(skills:GetChildren()) do
        tableToSave[i] = skill.Value
        tableToSave[i + 10] = skill:WaitForChild("Experience").Value
    end

    tableToSave[21] = player:WaitForChild("Speed").Value
    tableToSave[22] = player:WaitForChild("Jump").Value
    tableToSave[23] = player:WaitForChild("Energy").Value

    local success, err = pcall(function()
        dataStore:SetAsync(player.UserId, tableToSave)
    end)

    if success then
        print("Data has been saved!")
    else
        print("Data hasn't been saved!")
        warn(err)
    end
end

local function createSkill(parent, name)
    local skill = Instance.new("IntValue", parent)
    skill.Name = name

    local exp = Instance.new("IntValue", skill)
    exp.Name = "Experience"

    return skill
end

players.PlayerAdded:Connect(function(player)
    local skills = Instance.new("Folder", player)
    skills.Name = "Skills"

    local skillNames = {
        "Swords", "Axes", "Spears", "Agility", "Fists", "Block", "Speech", "Stealth", "Logging", "Mining"
    }

    for _, name in ipairs(skillNames) do
        createSkill(skills, name)
    end

    local Jump = Instance.new("NumberValue")
    Jump.Name = "Jump"
    Jump.Parent = player

    local Speed = Instance.new("NumberValue")
    Speed.Name = "Speed"
    Speed.Parent = player

    local Energy = Instance.new("NumberValue")
    Energy.Name = "Energy"
    Energy.Parent = player

    local data
    local success, err = pcall(function()
        data = dataStore:GetAsync(player.UserId)
    end)

    if success and data then
        for i, skill in ipairs(skills:GetChildren()) do
            skill.Value = data[i]
            skill:WaitForChild("Experience").Value = data[i + 10]
        end

        Speed.Value = data[21]
        Jump.Value = data[22]
        Energy.Value = data[23]
    else
        print("The player has no data!")

        for _, skill in ipairs(skills:GetChildren()) do
            skill.Value = 0
            skill:WaitForChild("Experience").Value = 0
        end

        Speed.Value = 12
        Jump.Value = 12
        Energy.Value = 100
    end
end)

local function saveAndPrintStatus(player)
    local success, err = pcall(function()
        saveData(player)
    end)

    if success then
        print("Data has been saved")
    else
        print("Data has not been saved!")
    end
end

players.PlayerRemoving:Connect(saveAndPrintStatus)

game:BindToClose(function()
    for _, player in pairs(players:GetPlayers()) do
        saveAndPrintStatus(player)
    end
end)