Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How to Properly Use DataStoreService for my Leveling System?

Asked by 1 year ago

Hello. I asked this question before but it went unanswered. I have attempted to try and solve the issue myself but still cannot seem to find a way to make it work. I have a gui that display's the players xp and level, but when testing my game the xp and level do not show up, the only thing that shows up is the two blank text labels. Also, the leaderstats do not show up either, it's just a leaderboard that states my username. Whenever I play test I get this message in my output: leaderstats is not a valid member of Player "Players.AROBLOXUSER12344" (AROBLOXUSER12344 is my username)

Here is my leaderstats and leveling script (in workspace):

local DataStoreService = game:GetService("DataStoreService")
local levelDataStore = DataStoreService:GetDataStore("levelDataStore")
local xpDataStore = DataStoreService:GetDataStore("xpDataStore")

function onXPChanged(player, XP, level)
    if XP.Value>=level.Value * 10 then 
        XP.Value = 0 
        level.Value = level.Value + 1 
    end
end

function onLevelUp(player, XP, level)
    local m = Instance.new("Hint")
    m.Parent = game.Workspace
    m.Text = player.Name .. " has leveled up!"
    wait(3)
    m.Parent = nil
   player.Humanoid.Health = 0
end


function onPlayerRespawned(player)
    wait(5)

    player.Character.Humanoid.Health = player.Character.Humanoid.Health + player.leaderstats.Level * 10

    player.Character.Humanoid.MaxHealth = player.Character.Humanoid.MaxHealth + player.leaderstats.Level * 10

end

function onPlayerEntered(player)

    local stats = Instance.new("IntValue")
    stats.Name = "leaderstats"
    local stats2 = Instance.new("IntValue")
    stats2.Name = "Tycoon"

   local kills = Instance.new("IntValue")
    kills.Name = "Kills"
    kills.Value = 0

    local deaths = Instance.new("IntValue")
    deaths.Name = "Deaths"
    deaths.Value = 0

   local level = Instance.new("IntValue")
   level.Name = "Level" -- The Name of LV
    level.Value = levelDataStore:GetAsync("Player_"..player.UserId) or 1
    local data
    local success, errormessage = pcall(function()
        data = levelDataStore:GetAsync(player.UserId.."-xp")
        data = xpDataStore:GetAsync(player.UserId.."-level")
    end)
    if success then
        level.Value = data
    else
        print("There was an error getting your data.")
        warn(errormessage)
    end

   local xp = Instance.new("IntValue")
   xp.Name = "XP" -- The Name of XP
    xp.Value = xpDataStore:GetAsync("Player_"..player.UserId) or 0
    local data
    local success, errormessage = pcall(function()
        data = levelDataStore:GetAsync(player.UserId.."-xp")
        data = xpDataStore:GetAsync(player.UserId.."-level")
    end)
    if success then
        xp.Value = data
    else
        print("There was a problem loading your data.")
        warn(errormessage)
    end

    game.Players.PlayerRemoving:Connect(function(player)
        local s, e = pcall(function()
            levelDataStore:SetAsync(player.UserId.."-level", player.leaderstats.Level.Value)
            xpDataStore:SetAsync(player.UserId.."-xp", player.leaderstats.Xp.Value)
        end)
        if s then
            print("Successfully saved data!")
        else
            print("There was an error when saving data.")
            warn(e)
        end
    end)

    stats2.Parent = player
    stats.Parent = player
    kills.Parent = stats
    deaths.Parent = stats
   level.Parent = stats
   xp.Parent = stats

    xp.Changed:connect(function() onXPChanged(player, xp, level) end)
    level.Changed:connect(function() onLevelUp(player, xp, level) end)

    while true do
        if player.Character ~= nil then break end
        wait(5)
    end

    local humanoid = player.Character.Humanoid

    humanoid.Died:connect(function() onHumanoidDied(humanoid, player) end )


    player.Changed:connect(function(property) onPlayerRespawn(property, player) end )


    stats.Parent = player

end

function Send_DB_Event_Died(victim, killer)

    local killername = "unknown"
    if killer ~= nil then killername = killer.Name end
    print(victim.Name, " was killed by ", killername)

    if shared["deaths"] ~= nil then 
        shared["deaths"](victim, killer)
        print("Death event sent.")
    end
end

function Send_DB_Event_Kill(killer, victim)
    print(killer.Name, " killed ", victim.Name)
    if shared["kills"] ~= nil then 
        shared["kills"](killer, victim)
        print("Kill event sent.")
    end
end



function onHumanoidDied(humanoid, player)
    local stats = player:findFirstChild("leaderstats")
    if stats ~= nil then
        local deaths = stats:findFirstChild("Deaths")
        deaths.Value = deaths.Value + 1


        local killer = getKillerOfHumanoidIfStillInGame(humanoid)


        Send_DB_Event_Died(player, killer)
        handleKillCount(humanoid, player)
    end
end

function onPlayerRespawn(property, player)


    if property == "Character" and player.Character ~= nil then
        local humanoid = player.Character.Humanoid
            local p = player
            local h = humanoid
            humanoid.Died:connect(function() onHumanoidDied(h, p) end )
    end
end

function getKillerOfHumanoidIfStillInGame(humanoid)

    local tag = humanoid:findFirstChild("creator")


    if tag ~= nil then

        local killer = tag.Value
        if killer.Parent ~= nil then 
            return killer
        end
    end

    return nil
end

function handleKillCount(humanoid, player)
    local killer = getKillerOfHumanoidIfStillInGame(humanoid)
    if killer ~= nil then
        local stats = killer:findFirstChild("leaderstats")
        if stats ~= nil then
            local kills = stats:findFirstChild("Kills")
         local xp = stats:findFirstChild("XP")
            if killer ~= player then
                kills.Value = kills.Value + 1
            xp.Value = xp.Value + 3

            else
                kills.Value = kills.Value - 0

            end
            Send_DB_Event_Kill(killer, player)
        end
    end
end

game.Players.ChildAdded:connect(onPlayerEntered)

Here is my gui text label script that is supposed to show the players current rank:

repeat 
wait()
until script.Parent.Parent.Parent.Parent.Parent.leaderstats:findFirstChild("Level")

while true do

if script.Parent.Parent.Parent.Parent.Parent.leaderstats.Level.Value == 1 then
wait(0.1)
script.Parent.Text = "Private I (Lvl 1)"
elseif script.Parent.Parent.Parent.Parent.Parent.leaderstats.Level.Value == 2 then
wait(0.1)
script.Parent.Text = "Private II (Lvl 2)"
elseif script.Parent.Parent.Parent.Parent.Parent.leaderstats.Level.Value == 3 then
wait(0.1)
script.Parent.Text = "Private lll (Lvl 3)"
end 
end 

And finally here is my other text label script that is supposed to show the xp the player has:

while true do
script.Parent.Text = "XP: " ..script.Parent.Parent.Parent.Parent.Parent.leaderstats.XP.Value
wait(0)
end

My concern is only the leveling and xp script not the other two text label scripts but I thought It was necessary if I included them both just in case. My screenshot below shows my error in my output: https://snipboard.io/wl6Rqj.jpg I've been stuck on this for so long and would love some help. Thank you!

1 answer

Log in to vote
0
Answered by 1 year ago
Edited 1 year ago

I haven't read this entire script yet, but I would use :WaitForChild() instead of just getting it immediately. I would also use a variable instead of just repeating script.Parent.Parent.Parent, etc.

Ad

Answer this question