Search code examples
user-interfaceluarobloxlevels

I am struggling with getting the reward system I built for Roblox to work with the levelling bar I also built for the same game


I have been working on a Roblox game for about three weeks, and have created something that I am proud of, but I have one pretty significant error that I can't seem to work around. I want to make the game something that I can add to in the future, so I made a program to reward players with gold and exp points for killing NPC's. I also made a GUI bar to show the player their progress towards the next level. The problem I have is the gold will show up, but the xp will not. I have been banging my head against a brick wall as I have tried over seventy fixes, and the xp still will not show up on the bar and the player can't level.

My xp bar program looks like this:

--Player related variables--
local player = game.Players.LocalPlayer
local level = player:WaitForChild("Level")
local current = level:WaitForChild("Current")
local max = level:WaitForChild("Max")

--UI related variables--
local gui = script.Parent
local exterior = gui:WaitForChild("Exterior")
local label = exterior:WaitForChild("Label")
local exp = exterior:WaitForChild("Exp")
local bar = exterior:WaitForChild("Bar")

--Change stats upon join--
label.Text = "Level "..level.Value
exp.Text = current.Value.."/"..max.Value.." Exp"
bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)

level.Changed:Connect(function(val, level)
    label.Text = "Level "..level.Value
    exp.Text = current.Value.."/"..max.Value.." Exp"
    bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
    wait(1)
end)

current.Changed:Connect(function(val)
    exp.Text = current.Value.."/"..max.Value.." Exp"
    bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
    wait(1)
end)

and my reward program looks like this:

        
local Humanoid = script.Parent.Humanoid
local Experience = 10
function Dead()
    local tag = Humanoid:FindFirstChild("creator")
    if tag ~= nil then
        if tag.Value ~= nil then
            local leaderstats = tag.Value:FindFirstChild("leaderstats")
            if leaderstats ~= nil then
                leaderstats.Cash.Value = leaderstats.Cash.Value +50
                
                workspace.ServerScriptService.leaderstats.Current:Connect(function(Experience)
                    if leaderstats.Current.Value ~= nil then
                        leaderstats.Current.Value = leaderstats.Current.Value + Experience
                        else leaderstats.Current.Value = 10
                        end
                end)
                
                wait(0.1)
                script:Remove()
                
            end
        end
    end
end

Humanoid.Died:Connect(Dead)

I also have a leaderstats code that looks like this:


        
local DataStore = game:GetService("DataStoreService"):GetDataStore("butthole")



game.Players.PlayerAdded:Connect(function(player)
    
    
    local folder = Instance.new("Folder")
    folder.Name = "leaderstats"
    folder.Parent = player
    
    local cash = Instance.new("IntValue")
    cash.Name = "Cash"
    cash.Value = 900
    cash.Parent = folder
--start
local level = Instance.new("IntValue", player)
    level.Name = "Level"
    level.Value = 1
    
    
local   exp = Instance.new("IntValue", level)
    exp.Name = "Current"
    exp.Value = 0
    
    
    
local    maxExp = Instance.new("IntValue", level)
    maxExp.Name = "Max"
    maxExp.Value = 100

exp.Changed:Connect(function(val)
    if exp.Value >= maxExp.Value then
        level.Value = level.Value + 1
        exp.Value = 0
        maxExp.Value = maxExp.Value * 2.5
        
        end

Something isn't talking to something else correctly, but I can't figure out where that might be. I'm not a pro developer, I'm just a guy trying to make a game.


Solution

  • Scroll to the bottom if you want to skip explanation

    Errors in Current Code:

    The main problem is this snippet from your reward program:

    workspace.ServerScriptService.leaderstats.Current:Connect(function(Experience)
        if leaderstats.Current.Value ~= nil then
            leaderstats.Current.Value = leaderstats.Current.Value + Experience
        else leaderstats.Current.Value = 10
        end
    end)
    

    1: ServerScriptService is not inside workspace

    To access ServerScriptService, use game.ServerScriptService

    2: "leaderstats.Current" is not an event...

    leaderstats.Current is not an event, so event:Connect(func) will not work. Something like Current.Changed would be considered an event

    3: "Current" is not inside "leaderstats"

    According to your leaderstats code, Current is not inside leaderstats, but rather inside level: player.Level.Current

    Although I pointed these things out, we won't be fixing 1 & 2 because they are unneccessary

    4: Extra parameter "level" causes conflict

    The last error occurs in the xp bar script:

    level.Changed:Connect(function(val, level)
        label.Text = "Level "..level.Value
        exp.Text = current.Value.."/"..max.Value.." Exp"
        bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
    end)
    

    The problem is the first line of the snippet: the 2nd parameter, "level", does not exist.
    The Changed event only has 1 parameter which is the new value after the change (in this context, is the new level). This means that val is the numerical value of your level.

    Simply removing "level" from the parameters would fix this part

    Solution:

    Reward Script:

    local Humanoid = script.Parent.Humanoid
    local Experience = 10
    
    function Dead()
        local tag = Humanoid:FindFirstChild("creator")
        if tag ~= nil then
            local player = tag.Value -- making variable makes it easier to understand
            
            if player then
                local leaderstats = player:FindFirstChild("leaderstats")
                local level = player:FindFirstChild("Level") -- "Current" is inside Level
                
                if leaderstats and level then
                    leaderstats.Cash.Value = leaderstats.Cash.Value +50
                    level.Current.Value = level.Current.Value +Experience --Simply add the EXP
                    script:Remove()
                end
            end
        end
    end
    
    Humanoid.Died:Connect(Dead)
    

    XP Bar Script:

    --Player related variables--
    local player = game.Players.LocalPlayer
    local level = player:WaitForChild("Level")
    local current = level:WaitForChild("Current")
    local max = level:WaitForChild("Max")
    
    --UI related variables--
    local gui = script.Parent
    local exterior = gui:WaitForChild("Exterior")
    local label = exterior:WaitForChild("Label")
    local exp = exterior:WaitForChild("Exp")
    local bar = exterior:WaitForChild("Bar")
    
    --Change stats upon join--
    label.Text = "Level "..level.Value
    exp.Text = current.Value.."/"..max.Value.." Exp"
    bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
    
    level.Changed:Connect(function(val)
        label.Text = "Level "..level.Value
        exp.Text = current.Value.."/"..max.Value.." Exp"
        bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
    end)
    
    current.Changed:Connect(function(val)
        exp.Text = current.Value.."/"..max.Value.." Exp"
        bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
    end)
    

    Additional Notes

    1: Handling Extra XP

    When a person gains enough XP to level up, the XP is set to 0 and the level goes up by 1. However, that means all the extra XP went nowhere. I've changed the functionality to account for excess XP.

    leaderstats script (replace your current exp.Changed function):

    exp.Changed:Connect(function(val)
        if exp.Value >= maxExp.Value then
            local newLevel = level.Value
            local newXP = exp.Value
            local newMax = maxExp.Value
            
            while newXP > newMax do
                newLevel = newLevel + 1
                newXP = newXP - newMax
                newMax = newMax * 2.5
            end
            
            maxExp.Value = newMax
            exp.Value = newXP
            level.Value = newLevel
        end
    end)
    

    2: Functions (Not Neccessary, but Recommended)

    Creating one function to update the UI makes it easier for later changes

    XP Bar Script (2nd half):

    --Change stats upon join--
    function updateUI()
        label.Text = "Level ".. level.Value
        exp.Text = current.Value.."/"..max.Value.." Exp"
        bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
    end
    updateUI()
    
    level.Changed:Connect(updateUI)
    current.Changed:Connect(updateUI)