Help with revising script to work better

This code stores all data with the xp system. I need to revise it so that it works better. You can either edit the script (the current script) to make it better or revise someone elses revision further. Anything helps! Here is the script:

local DataStore = game:GetService("DataStoreService")
local Level1 = DataStore:GetDataStore("Levels001")
local Beli11 = DataStore:GetDataStore("Beli001")
local Exp1 = DataStore:GetDataStore("Exp001")
local ExpNeed1 = DataStore:GetDataStore("ExpNeed001")
local DefenseP1 = DataStore:GetDataStore("DefenseP001")
local SwordP1 = DataStore:GetDataStore("SwordP001")
local LuckP1 = DataStore:GetDataStore("LuckP001")
local SpecialP1 = DataStore:GetDataStore("Special001")
local Defense1 = DataStore:GetDataStore("Defense001")
local Sword1 = DataStore:GetDataStore("Sword001")
local Luck1 = DataStore:GetDataStore("Luck001")
local Special1 = DataStore:GetDataStore("Special001")
local Points1 = DataStore:GetDataStore("Points001")

game.Players.PlayerAdded:Connect(function(Plr)
	local stats = Instance.new("Folder", Plr)
	stats.Name = "Data"
	--- Level System
	local Levels = Instance.new("IntValue", stats)
	Levels.Name = "Levels"
	Levels.Value = 1
	local Exp = Instance.new("IntValue", stats)
	Exp.Name = "Exp"
	Exp.Value = 0
	local ExpNeed = Instance.new("IntValue", stats)
	ExpNeed.Name = "ExpNeed"
	ExpNeed.Value = 200
	--- Money System
	local Beli = Instance.new("IntValue", stats)
	Beli.Name = "Gold"
	Beli.Value = 0
	--- Stats Text
	local DefenseP = Instance.new("IntValue", stats)
	DefenseP.Name = "DefenseP"
	DefenseP.Value = 1
	local SwordP = Instance.new("IntValue", stats)
	SwordP.Name = "SwordP"
	SwordP.Value = 1
	local LuckP = Instance.new("IntValue", stats)
	LuckP.Name = "LuckP"
	LuckP.Value = 1
	local SpecialP = Instance.new("IntValue", stats)
	SpecialP.Name = "SpecialP"
	SpecialP.Value = 1
	--- Stats System
	local Points = Instance.new("IntValue", stats)
	Points.Name = "Points"
	Points.Value = 0
	local PointsS = Instance.new("IntValue", stats)
	PointsS.Name = "PointsS"
	PointsS.Value = 1
	local Defense = Instance.new("IntValue", stats)
	Defense.Name = "Defense"
	Defense.Value = 0
	local Sword = Instance.new("IntValue", stats)
	Sword.Name = "Sword"
	Sword.Value = 0
	local Luck = Instance.new("IntValue", stats)
	Luck.Name = "Luck"
	Luck.Value = 0
	local Special = Instance.new("IntValue", stats)
	Special.Name = "Special"
	Special.Value = 0
---- Datastore ----
--- Levels
   Levels.Value = Level1:GetAsync(Plr.UserId) or Levels.Value
	   Level1:SetAsync(Plr.UserId, Levels.Value)
      Levels.Changed:connect(function()
	   Level1:SetAsync(Plr.UserId, Levels.Value)
   end)
--- Gold
   Beli.Value = Beli11:GetAsync(Plr.UserId) or Beli.Value
	   Beli11:SetAsync(Plr.UserId, Beli.Value)
      Beli.Changed:connect(function()
	   Beli11:SetAsync(Plr.UserId, Beli.Value)
   end)
--- Exp
   Exp.Value = Exp1:GetAsync(Plr.UserId) or Exp.Value
	   Exp1:SetAsync(Plr.UserId, Exp.Value)
      Exp.Changed:connect(function()
	   Exp1:SetAsync(Plr.UserId, Exp.Value)
   end)
--- ExpNeed
   ExpNeed.Value = ExpNeed1:GetAsync(Plr.UserId) or ExpNeed.Value
	   ExpNeed1:SetAsync(Plr.UserId, ExpNeed.Value)
      ExpNeed.Changed:connect(function()
	   ExpNeed1:SetAsync(Plr.UserId, ExpNeed.Value)
   end)
--- SwordP
   SwordP.Value = SwordP1:GetAsync(Plr.UserId) or SwordP.Value
	   SwordP1:SetAsync(Plr.UserId, SwordP.Value)
      SwordP.Changed:connect(function()
	   SwordP1:SetAsync(Plr.UserId, SwordP.Value)
   end)
--- DefenseP
   DefenseP.Value = DefenseP1:GetAsync(Plr.UserId) or DefenseP.Value
	   DefenseP1:SetAsync(Plr.UserId, DefenseP.Value)
      DefenseP.Changed:connect(function()
	   DefenseP1:SetAsync(Plr.UserId, DefenseP.Value)
   end)
--- LuckP
   ExpNeed.Value = ExpNeed1:GetAsync(Plr.UserId) or ExpNeed.Value
	   ExpNeed1:SetAsync(Plr.UserId, ExpNeed.Value)
      ExpNeed.Changed:connect(function()
	   ExpNeed1:SetAsync(Plr.UserId, ExpNeed.Value)
   end)
--- SpecialP
   ExpNeed.Value = ExpNeed1:GetAsync(Plr.UserId) or ExpNeed.Value
	   ExpNeed1:SetAsync(Plr.UserId, ExpNeed.Value)
      ExpNeed.Changed:connect(function()
	   ExpNeed1:SetAsync(Plr.UserId, ExpNeed.Value)
   end)
--- Sword
   Sword.Value = Sword1:GetAsync(Plr.UserId) or Sword.Value
	   Sword1:SetAsync(Plr.UserId, SwordP.Value)
      Sword.Changed:connect(function()
	   Sword1:SetAsync(Plr.UserId, SwordP.Value)
   end)
--- Defense
   Defense.Value = Defense1:GetAsync(Plr.UserId) or Defense.Value
	   Defense1:SetAsync(Plr.UserId, Defense.Value)
      Defense.Changed:connect(function()
	   Defense1:SetAsync(Plr.UserId, Defense.Value)
   end)
--- Luck
   Luck.Value = Luck1:GetAsync(Plr.UserId) or Luck.Value
	   Luck1:SetAsync(Plr.UserId, Luck.Value)
      Luck.Changed:connect(function()
	   Luck1:SetAsync(Plr.UserId, Luck.Value)
   end)
--- Special
   Special.Value = Special1:GetAsync(Plr.UserId) or Special.Value
	   Special1:SetAsync(Plr.UserId, Special.Value)
      Special.Changed:connect(function()
	   Special1:SetAsync(Plr.UserId, Special.Value)
   end)
--- Points
   Points.Value = Points1:GetAsync(Plr.UserId) or Points.Value
	   Points1:SetAsync(Plr.UserId, Points.Value)
      Points.Changed:connect(function()
	   Points1:SetAsync(Plr.UserId, Points.Value)
   end)
end)

game.Players.PlayerAdded:Connect(function(plr)
	wait(.1)
	local Exp = plr.Data.Exp
	local Levels = plr.Data.Levels
	local ExpNeed = plr.Data.ExpNeed
	local Points = plr.Data.Points
	
	while wait() do
		if Exp.Value >= (100 * (Levels.Value + 1)) and Levels.Value <= 399 then
			Levels.Value = Levels.Value + 1
			Points.Value = Points.Value + 3
			Exp.Value = Exp.Value - ExpNeed.Value
			ExpNeed.Value = ExpNeed.Value + 100
			game.ReplicatedStorage.LevelSystem.LevelUpGui:FireClient(plr)
		end
	end
end)

game.Players.PlayerRemoving:connect(function(Player)
	Level1:SetAsync(Player.UserId, Player.Data.Levels.Value)
	Beli11:SetAsync(Player.UserId, Player.Data.Beli.Value)
	Exp1:SetAsync(Player.UserId, Player.Data.Exp.Value)
	ExpNeed1:SetAsync(Player.UserId, Player.Data.ExpNeed.Value)
	SwordP1:SetAsync(Player.UserId, Player.Data.SwordP.Value)
	DefenseP1:SetAsync(Player.UserId, Player.Data.DefenseP.Value)
	LuckP1:SetAsync(Player.UserId, Player.Data.LuckP.Value)
	SpecialP1:SetAsync(Player.UserId, Player.Data.SpecialP.Value)
	Sword1:SetAsync(Player.UserId, Player.Data.Sword.Value)
	Defense1:SetAsync(Player.UserId, Player.Data.Defense.Value)
	Luck1:SetAsync(Player.UserId, Player.Data.Luck.Value)
	Special1:SetAsync(Player.UserId, Player.Data.Special.Value)
	Points1:SetAsync(Player.UserId, Player.Data.Points.Value)
end)
2 Likes
local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local Datas = {
	-- Level System --
	{
		Name = "Levels",
		DefaultValue = 1
	}, {
		Name = "Exp",
		DefaultValue = 0
	},
	------------------
	
	-- Money System --
	{
		Name = "Gold",
		DefaultValue = 0
	},
	------------------
	
	-- Stats Text --
	{
		Name = "DefenseP",
		DefaultValue = 1
	}, {
		Name = "SwordP",
		DefaultValue = 1
	}, {
		Name = "LuckP",
		DefaultValue = 1
	}, {
		Name = "SpecialP",
		DefaultValue = 1
	},
	----------------
	
	-- Stats System --
	{
		Name = "Points",
		DefaultValue = 0
	}, {
		Name = "PointsS",
		DefaultValue = 1
	}, {
		Name = "Defense",
		DefaultValue = 0
	}, {
		Name = "Sword",
		DefaultValue = 0
	}, {
		Name = "Luck",
		DefaultValue = 0
	}, {
		Name = "Special",
		DefaultValue = 0
	}
	------------------
}

local LevelCap = 400

local function checkNextLevel(Exp, CurrentLevel)
	local ExpNeed = (CurrentLevel + 1) * 100
	
	if CurrentLevel >= LevelCap then return CurrentLevel, Exp end
	
	if Exp >= ExpNeed then 
		CurrentLevel += 1
		Exp -= ExpNeed
		
		return checkNextLevel(Exp, CurrentLevel)
	end
	
	return CurrentLevel, Exp
end

local function expCheck(stats, inst, plr)
	inst:GetPropertyChangedSignal("Value"):Connect(function()
		local Exp = inst
		local Levels = stats.Levels

		if Levels.Value >= LevelCap then
			if Exp.Value ~= 0 then Exp.Value = 0 end
			if Levels.Value > LevelCap then Levels.Value = LevelCap end

			return
		end
		
		local NewLevel, NewExp = checkNextLevel(Exp.Value, Levels.Value)
		
		if NewLevel > Levels.Value then
			local oldLevel = Levels.Value
			local Points = stats.Points
			
			Levels.Value = NewLevel
			Points.Value = (NewLevel-oldLevel)*3
			Exp.Value = NewExp
			
			game.ReplicatedStorage.LevelSystem.LevelUpGui:FireClient(plr)
		end
	end)
end

game.Players.PlayerAdded:Connect(function(plr)
	local stats = Instance.new("Folder", plr)
	stats.Name = "Data"
	
	for _,data in pairs(Datas) do
		local inst = Instance.new("IntValue")
		inst.Name = data.Name
		inst.Value = data.DefaultValue
		print(data.DefaultValue, inst.Value)
		
		local DataStore = DataStoreService:GetDataStore(data.Name)
		local getAsync
		local success, err = pcall(function()
			getAsync = DataStore:GetAsync(plr.UserId)
		end)
		
		if success then
			inst.Value = getAsync
		end
		
		inst.Parent = stats
		
		if data.Name == "Exp" then expCheck(stats, inst, plr) end
	end
end)

local function playerRemoving(plr)
	local stats = plr.Data

	for _,data in pairs(Datas) do
		coroutine.resume(coroutine.create(function()
			local DataStore = DataStoreService:GetDataStore(data.Name)
			local success, err
			local attempt = 1

			repeat
				success, err = pcall(function()
					DataStore:SetAsync(plr.UserId, stats[data.Name].Value)
				end)

				attempt += 1
				if not success then
					warn(err)
					task.wait(1)
				end
			until success or attempt > 4
		end))
	end
end

game.Players.PlayerRemoving:connect(playerRemoving)

game:BindToClose(function()
	for _, plr in pairs(Players:GetPlayers()) do
		playerRemoving(plr)
	end
	
	if RunService:IsStudio() then
		task.wait(1)
	end
end)

Should work just by copying and pasting

I forgot to remove the print() on line 114, you can remove that line

2 Likes