The level and experience system is one of the most popular game mechanics that motivates players to develop and spend more time in the game. In this article, we will analyze how to create a basic but functional leveling system in Roblox Studio.

What are we going to create?
We will make a system where:
The player gains experience (XP) for various actions
When you accumulate a certain amount of experience, the level increases
Progress is saved between game sessions
The screen displays the current level and progress
Step 1: Creating a data structure
First, we need to decide what data we will store for each player. Let's create a script in ServerScriptService with the name LevelSystem:
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerLevels")
-- Настройки системы уровней
local DEFAULT_LEVEL = 1
local DEFAULT_XP = 0
local XP_PER_LEVEL = 100 -- Базовое количество опыта для первого уровня
local XP_MULTIPLIER = 1.5 -- Множитель сложности каждого уровня
Here we have defined the basic parameters of our system. XP_MULTIPLIER means that each next level requires 1.5 times more experience.
Step 2: Function for calculating the required experience
Let's create a function that calculates how much experience is needed to reach the next level:
local function getXPForLevel(level)
-- Формула: базовый_опыт * (множитель ^ (уровень - 1))
return math.floor(
XP_PER_LEVEL * (XP_MULTIPLIER ^ (level - 1))
)
endThis formula makes the game more balanced — with each level, more and more experience is required, which creates a progression of complexity.
Step 3: Initializing Player Data
When a player logs into the server, we need to load their data or create new ones:
local function setupPlayerData(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local level = Instance.new("IntValue")
level.Name = "Level"
level.Parent = leaderstats
local xp = Instance.new("IntValue")
xp.Name = "XP"
xp.Parent = leaderstats
-- Загружаем сохранённые данные
local success, data = pcall(function()
return playerData:GetAsync(player.UserId)
end)
if success and data then
level.Value = data.Level or DEFAULT_LEVEL
xp.Value = data.XP or DEFAULT_XP
else
level.Value = DEFAULT_LEVEL
xp.Value = DEFAULT_XP
end
end
game.Players.PlayerAdded:Connect(setupPlayerData)
The leaderstats folder is automatically displayed in the list of players in Roblox, which is convenient for debugging.
Step 4: Add Experience Function
Now let's create the main function — adding experience to the player:
local function addXP(player, amount)
local level = player.leaderstats.Level
local xp = player.leaderstats.XP
-- Добавляем опыт
xp.Value = xp.Value + amount
-- Проверяем, достаточно ли опыта для повышения уровня
local xpNeeded = getXPForLevel(level.Value)
while xp.Value >= xpNeeded do
-- Повышаем уровень
xp.Value = xp.Value - xpNeeded
level.Value = level.Value + 1
-- Уведомляем игрока
local message = Instance.new("Message")
message.Text = "Congratulations! You have reached " .. level.Value .. " level!"
message.Parent = player.PlayerGui
wait(3)
message:Destroy()
-- Обновляем требование для следующего уровня
xpNeeded = getXPForLevel(level.Value)
end
endPay attention to the while cycle — it is needed in case the player has gained a lot of experience at once and can jump over several levels.
Step 5: Saving your progress
It is important to save the player's data when they exit the game:
local function savePlayerData(player)
local success, err = pcall(function()
playerData:SetAsync(player.UserId, {
Level = player.leaderstats.Level.Value,
XP = player.leaderstats.XP.Value,
})
end)
if not success then
warn("Failed to save player data: " .. err)
end
end
game.Players.PlayerRemoving:Connect(savePlayerData)
-- Автосохранение каждые 5 минут
while true do
wait(300) -- 5 минут
for _, player in pairs(game.Players:GetPlayers()) do
savePlayerData(player)
end
endStep 6: Examples of use
Now we can give experience for various actions. For example, for defeating an enemy:
-- В скрипте врага
local function onDeath()
-- Логика определения игрока, убившего врага
local killer = nil
if killer then
addXP(killer, 25) -- Даём 25 опыта
end
endOr for collecting coins:
-- В скрипте коллекционного предмета
local function onTouch(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
addXP(player, 10)
script.Parent:Destroy()
end
end
script.Parent.Touched:Connect(onTouch)Step 7: Creating a UI to display progress
Let's add a nice display of level and experience. Create ScreenGui in StarterGui with the name LevelUI, and inside it Frame for the panel:
-- LocalScript в StarterGui
local player = game.Players.LocalPlayer
local gui = script.Parent
-- Создаём элементы интерфейса
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, 300, 0, 80)
frame.Position = UDim2.new(0, 10, 0, 10)
frame.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
frame.Parent = gui
local levelLabel = Instance.new("TextLabel")
levelLabel.Size = UDim2.new(1, 0, 0.4, 0)
levelLabel.Position = UDim2.new(0, 0, 0, 0)
levelLabel.BackgroundTransparency = 1
levelLabel.TextColor3 = Color3.new(1, 1, 1)
levelLabel.TextScaled = true
levelLabel.Parent = frame
local progressBar = Instance.new("Frame")
progressBar.Size = UDim2.new(0.9, 0, 0.2, 0)
progressBar.Position = UDim2.new(0.05, 0, 0.6, 0)
progressBar.BackgroundColor3 = Color3.fromRGB(100, 100, 100)
progressBar.Parent = frame
local progressFill = Instance.new("Frame")
progressFill.Size = UDim2.new(0, 0, 1, 0)
progressFill.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
progressFill.Parent = progressBar
-- Функция обновления UI
local function updateUI()
local level = player.leaderstats.Level.Value
local xp = player.leaderstats.XP.Value
local xpNeeded =
-- вызов функции расчёта (через RemoteFunction)
levelLabel.Text =
"Level " .. level .. " | " .. xp .. "/" .. xpNeeded .. " XP"
progressFill.Size = UDim2.new(xp / xpNeeded, 0, 1, 0)
end
-- Обновляем при изменении значений
player.leaderstats.Level.Changed:Connect(updateUI)
player.leaderstats.XP.Changed:Connect(updateUI)
updateUI()Additional improvements
Here are some ideas on how to expand this system:
1. Level rewards
local LEVEL_REWARDS = { [5] = {Coins = 100}, [10] = {Coins = 250, Item = "SpecialSword"}, [20] = {Coins = 500} }2. Different sources of experience
addXP(player, 50, "Quest") addXP(player, 10, "Killing the enemy") addXP(player, 5, "Research")3. Experience boosts
local function addXP(player, amount, hasBoost) if hasBoost then amount = amount * 2 -- Удвоенный опыт end -- остальной кодendConclusion
We have created a full-fledged system of levels and leveling for the game in Roblox! This system includes:
Accumulation of experience
Increasing levels with progressive complexity
Saving data
Visual display of progress
This and much more can be learned in the Codex!
We analyze interesting topics in detail, step by step, with clear explanations and practical tasks. You will not just read the theory, but also consolidate your knowledge in practice, creating real projects.
And if you need support - we already have a large team of like-minded people in active Telegram channel. Ask questions, share your projects and get help from experienced developers! 🚀
