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

Why does this death counter with save not work?

Asked by
21_T 0
7 years ago

I dont know whats wrong, here is the code:

local DataStoreService = game:GetService("DataStoreService")
local playerDeathsStore = DataStoreService:GetDataStore("PlayerDeaths")
local player = game.Players.LocalPlayer
local playername = player.Name

pcall (function()
    playerDeathsStore:SetAsync("PlayerDeaths", _G.died)
end)

if _G.died then
   _G.died = _G.died + 1
else
   _G.died = 0  
end

script.Parent.Text = "You died ".. playerDeathsStore:GetAsync(playername) .." times!"

while true do
   playerDeathsStore:UpdateAsync(playername, _G.died)
end

while wait(1) do
    print(_G.died)
end

3 answers

Log in to vote
1
Answered by
Azarth 3141 Moderation Voter Community Moderator
7 years ago

There are a few problems along with some general logic issues. You can't use DataStoreService in a LocalScript. If you aren't, then you can't get LocalPlayer in a normal script. Since you said your script isn't crashing, I'm going to assume it breaks before that while statement without a wait, else you'd be crashing. You have not set a key for the player, therefore you'd just be saving the same key over and over again to one store 'PlayerDeaths. You shouldn't update _G.died in a while statement since there's a limit. Finally, I recommend using a NumberValue placed in the player V.S. a shared variable since there are restrictions between Local and server scripts.

First, place a Script in ServerScriptService. This script will place the NumberValue in the player and load their deaths to it. We use this to keep track of the deaths and display it in the GUI.

Put a LocalScript in StarterCharacterScripts. Put a Script in the LocalScript. The LocalScript will wait for things to load and the Script will handle everything important, since we don't want exploitation of our value. When FilteringEnabled is on, the client aka you or any player in your game can change things, but it will only be visible by you.

Put your GUI in PlayerGui with a LocalScript in it. The GUI's script will detect a change in the NumberValue. Although this can be exploited, it's not going to do anything but tell you something false if they do. Nothing saves here.

This is a version where it saves every time the player dies. For a large game, this wouldn't be ideal, as there are limits.

This is the code inside the Script in ServerScriptService

local DataStoreService = game:GetService("DataStoreService")
local playerDeathsStore = DataStoreService:GetDataStore("PlayerDeaths")

game.Players.PlayerAdded:Connect(function(player)
    -- Key unique to that player
    local key = string.format("%s_%s", player.Name, player.userId)
    -- Instance the NumberValue into the player who joined
    local deaths = Instance.new("NumberValue", player)
    deaths.Name = "Deaths"

    pcall(function()
        -- loads data or sets it to 0 if there is none yet
        local data = playerDeathsStore:GetAsync(key) or 0
        deaths.Value = data
    end)
end)

This is the code inside the LocalScript in StarterCharacterScripts

-- Put in StarterCharacterScript as a LocalScript

local player = game.Players.LocalPlayer
local character = player.Character 
local humanoid = character:WaitForChild("Humanoid")
local deaths = player:WaitForChild("Deaths")
local RemoteEvent = script:WaitForChild('RemoteEvent')

-- Fire the RemoteEvent when we die.
humanoid.Died:Connect(function()
    RemoteEvent:FireServer(player)
end)

This is the code inside the Script placed in the LocalScript

local DataStoreService = game:GetService("DataStoreService")
local playerDeathsStore = DataStoreService:GetDataStore("PlayerDeaths")
local RemoteEvent = Instance.new("RemoteEvent", script.Parent)

local function save(player, new_value, key)
    if pcall(function()
        playerDeathsStore:UpdateAsync(key, function()
            return new_value
        end)
    end) then
        print(string.format("Saved %s deaths [%s]", player.Name, new_value))
    else
        print(string.format("Couldn't save %s deaths.", player.Name, new_value))
    end
end

RemoteEvent.OnServerEvent:connect(function(player)
    -- We don't want to pass the Deaths value from the LocalScript because
    -- it could have been exploited by a player
    local deaths_val = player:findFirstChild("Deaths")
    local key = string.format("%s_%s", player.Name, player.userId)
    if deaths_val then 
        deaths_val.Value = deaths_val.Value + 1
        save(player, deaths_val.Value, key)
    end
end)
Ad
Log in to vote
0
Answered by 7 years ago
local DataStoreService = game:GetService("DataStoreService")
local playerDeathsStore = DataStoreService:GetDataStore("PlayerDeaths")
local player = game.Players.LocalPlayer
local playername = player.Name

pcall (function()
    playerDeathsStore:SetAsync("PlayerDeaths", _G.died)
end)

if _G.died then
   _G.died = _G.died + 1
else
   _G.died = 0  
end

script.Parent.Text = "You died ".. playerDeathsStore:GetAsync(playername) .." times!"

_G.died.Changed:connect(function()
   playerDeathsStore:UpdateAsync(playername, _G.died)
script.Parent.Text = "You died ".. playerDeathsStore:GetAsync(playername) .." times!" 
--Delete the above line if you don't want it
end)

while wait(1) do
    print(_G.died)
end

So, try if this works. You weren't very specific with what went wrong, but i can guess two things:

the kill counter not updating and nothing printing.

The problem was, you had a while true loop. That loop kept on looping and never allowed the print to run.

I created and event to replace the loop, and put the text updater inside as well.

If you don't want the counter to update though, take it out of the event

Log in to vote
0
Answered by 7 years ago
Edited 7 years ago

A while loops won't finish until it is true. You don't wan't to have to two while loops in one script. Here is how I fixed it by combine codes (The code below is not tested):

local DataStoreService = game:GetService("DataStoreService")
local playerDeathsStore = DataStoreService:GetDataStore("PlayerDeaths")
local player = game.Players.LocalPlayer
local playername = player.Name

pcall (function()
    playerDeathsStore:SetAsync("PlayerDeaths", _G.died)
end)

while true do
    playerDeathsStore:UpdateAsync(playername, _G.died)
    script.Parent.Text = "You died ".. playerDeathsStore:GetAsync(playername) .." times!"

    if _G.died then
        _G.died = _G.died + 1
    else
        _G.died = 0  
    end

    print(_G.died)
end

Yeah... I don't know what I'm doing.

Answer this question