So I’ve been working on an RPG system. The player’s MaxHealth is increased each time he/she levels up. When the player dies and respawns, it resets the MaxHealth to 100 (the default).
Health Formula:
function info.GetHealth(level)
if level < 10 then
return 100 + (5 * (level - 1))
else
return 150 + (10 * (level - 1))
end
end
Server Script (messy):
local DataStoreService = game:GetService("DataStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerBase = DataStoreService:GetDataStore("PlayerBase" .. 6)
local weaponsFolder = ReplicatedStorage:WaitForChild("Weapons")
local armorsFolder = ReplicatedStorage:WaitForChild("Armors")
local infoModule = require(ReplicatedStorage:WaitForChild("Info"))
local function playerAdded(player)
local billboard
print(player.Name, "has joined the game!")
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData = pcall(function()
return PlayerBase:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(playerData)
task.wait()
end
until success or attempt == 3
if success then
print("Successfully retreived data for", player.Name)
if not playerData then
print("Giving new data to", player.Name)
playerData = {
["Gold"] = 0,
["Level"] = 1,
["XP"] = 0,
["SelectedWeapon"] = "Wooden Sword",
["SelectedArmor"] = "Wooden Armor",
["Weapons"] = {},
["Armors"] = {},
}
for i, v in pairs(weaponsFolder:GetChildren()) do
if v:FindFirstChild("StarterTool") then
playerData.Weapons[v.Name] = true
else
playerData.Weapons[v.Name] = false
end
end
for i, v in pairs(armorsFolder:GetChildren()) do
if v:FindFirstChild("StarterArmor") then
playerData.Armors[v.Name] = true
else
playerData.Armors[v.Name] = false
end
end
end
local character = player.Character or player.CharacterAdded:Wait()
for i, v in pairs(character:GetDescendants()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Players"
end
end
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
local gold = Instance.new("NumberValue", leaderstats)
gold.Name = "Gold"
gold.Value = tonumber(playerData.Gold) or 0
local level = Instance.new("NumberValue", leaderstats)
level.Name = "Level"
level.Value = tonumber(playerData.Level) or 1
local xp = Instance.new("NumberValue", leaderstats)
xp.Name = "XP"
xp.Value = tonumber(playerData.XP) or 0
local weapon = Instance.new("StringValue", player)
weapon.Name = "SelectedWeapon"
local armor = Instance.new("StringValue", player)
armor.Name = "SelectedArmor"
weapon:GetPropertyChangedSignal("Value"):Connect(function()
for i, v in pairs(weaponsFolder:GetChildren()) do
if player.Backpack:FindFirstChild(v.Name) then
player.Backpack:FindFirstChild(v.Name):Destroy()
end
if character:FindFirstChild(v.Name) then
character:FindFirstChild(v.Name):Destroy()
end
end
local tool = weaponsFolder:FindFirstChild(weapon.Value).Tool:Clone()
tool.Name = weapon.Value
tool.Parent = player.Backpack
end)
armor:GetPropertyChangedSignal("Value"):Connect(function()
if billboard then
billboard.Holder.CharacterDefense.Text = "Defense: " .. armorsFolder:FindFirstChild(armor.Value).Defense.Value
end
end)
local healthMod = infoModule.GetHealth(level.Value)
character.Humanoid.MaxHealth = healthMod
player.Backpack.ChildAdded:Connect(function(child)
if child:IsA("Tool") then
local healthMod = infoModule.GetHealth(level.Value)
character.Humanoid.MaxHealth = healthMod
end
end)
player.CharacterAdded:Connect(function()
local healthMod = infoModule.GetHealth(level.Value)
character.Humanoid.MaxHealth = healthMod
character.Humanoid.Health = healthMod
billboard = workspace.Billboards.CharacterBillboard:Clone()
billboard.Parent = character:WaitForChild("Head")
billboard.Holder.CharacterLevel.Text = "[" .. tostring(level.Value) .. "]"
billboard.Holder.CharacterName.Text = player.DisplayName
billboard.Holder.CharacterDefense.Text = "Defense: " .. armorsFolder:FindFirstChild(armor.Value).Defense.Value
billboard.PlayerToHideFrom = player
for i, v in pairs(weaponsFolder:GetChildren()) do
if player.Backpack:FindFirstChild(v.Name) then
player.Backpack:FindFirstChild(v.Name):Destroy()
end
if character:FindFirstChild(v.Name) then
character:FindFirstChild(v.Name):Destroy()
end
end
local tool = weaponsFolder:FindFirstChild(weapon.Value).Tool:Clone()
tool.Name = weapon.Value
tool.Parent = player.Backpack
end)
weapon.Value = playerData.SelectedWeapon or "Wooden Sword"
armor.Value = playerData.SelectedArmor or "Wooden Armor"
local weapons = Instance.new("Folder", player)
weapons.Name = "Weapons"
local armors = Instance.new("Folder", player)
armors.Name = "Armors"
for i, v in pairs(weaponsFolder:GetChildren()) do
local weaponOBJ = Instance.new("BoolValue", weapons)
weaponOBJ.Name = v.Name
if v:FindFirstChild("StarterWeapon") then
weaponOBJ.Value = playerData.Weapons[v.Name] or true
else
weaponOBJ.Value = playerData.Weapons[v.Name] or false
end
end
for i, v in pairs(armorsFolder:GetChildren()) do
local armorOBJ = Instance.new("BoolValue", armors)
armorOBJ.Name = v.Name
if v:FindFirstChild("StarterArmor") then
armorOBJ.Value = playerData.Armors[v.Name] or true
else
armorOBJ.Value = playerData.Armors[v.Name] or false
end
end
xp:GetPropertyChangedSignal("Value"):Connect(function()
local nextEXP = infoModule.GetNextExp(level.Value)
if xp.Value >= nextEXP then
xp.Value -= nextEXP
level.Value += 1
end
end)
level:GetPropertyChangedSignal("Value"):Connect(function()
local healthMod = infoModule.GetHealth(level.Value)
character.Humanoid.Health = healthMod
if billboard then
billboard.Holder.CharacterLevel.Text = "[" .. tostring(level.Value) .. "]"
end
end)
character.Humanoid.HealthChanged:Connect(function(newHealth)
if character then
if billboard then
billboard.Holder.Health.Health.Text = math.floor(newHealth) .. "/" .. tostring(character.Humanoid.MaxHealth)
billboard.Holder.Health.Current.Size = UDim2.new(newHealth / character.Humanoid.MaxHealth, 0, 1, 0)
end
end
end)
else
player:Kick("Our Server failed to save your data. Please try again!")
end
end
local function playerRemoved(player)
print(player.Name, "has left the game!")
local success = nil
local playerData = nil
local attempt = 1
local saveTable = {
["Gold"] = player.leaderstats.Gold.Value,
["Level"] = player.leaderstats.Level.Value,
["XP"] = player.leaderstats.XP.Value,
["SelectedWeapon"] = player.SelectedWeapon.Value,
["SelectedArmor"] = player.SelectedArmor.Value,
["Weapons"] = {},
["Armors"] = {},
}
for i, v in pairs(player.Weapons:GetChildren()) do
if v:FindFirstChild("StarterTool") then
saveTable.Weapons[v.Name] = true
else
saveTable.Weapons[v.Name] = v.Value
end
end
for i, v in pairs(player.Armors:GetChildren()) do
if v:FindFirstChild("StarterArmor") then
saveTable.Armors[v.Name] = true
else
saveTable.Armors[v.Name] = v.Value
end
end
repeat
success, playerData = pcall(function()
return PlayerBase:UpdateAsync(player.UserId, function()
return saveTable
end)
end)
attempt += 1
if not success then
warn(playerData)
task.wait()
end
until success or attempt == 3
end
game.Players.PlayerAdded:Connect(playerAdded)
game.Players.PlayerRemoving:Connect(playerRemoved)
game:BindToClose(function()
for i, player in pairs(game.Players:GetPlayers()) do
task.spawn(function()
playerRemoved(player)
end)
end
end)
ReplicatedStorage:WaitForChild("Events"):WaitForChild("SetWeapon").OnServerEvent:Connect(function(player, weaponName)
player.SelectedWeapon.Value = weaponName
end)
ReplicatedStorage:WaitForChild("Events"):WaitForChild("SetArmor").OnServerEvent:Connect(function(player, weaponName)
player.SelectedArmor.Value = weaponName
end)
ReplicatedStorage:WaitForChild("Events"):WaitForChild("WeaponPurchased").OnServerEvent:Connect(function(player, weaponName, cost)
player.leaderstats.Gold.Value -= cost
player.Weapons:FindFirstChild(weaponName).Value = true
end)
ReplicatedStorage:WaitForChild("Events"):WaitForChild("ArmorPurchased").OnServerEvent:Connect(function(player, armorName, cost)
player.leaderstats.Gold.Value -= cost
player.Armors:FindFirstChild(armorName).Value = true
end)