#something tells me this wont work...

72 messages · Page 1 of 1 (latest)

dreamy crow
#

Since UIS is a client only service, meaning this is hopefully in a localscript, use Players.LocalPlayer to get the player

#

Other than a more elegant way to get the player, and maybe even replacing the 'leaderboard.clicks.Value = leaderboard.clicks.Value + 1' to 'leaderboard.clicks.Value += 1' I don't really see anything else that's wrong with it

#

Oh wait

#

You're calling an object in 'ServerScriptService' from the client
Objects on the server aren't accessible to the client

#

Plus you're incrementing the value for the client, so it never actually increments on the server

#

Put the leaderboard somewhere like ReplicatedStorage and use a RemoteEvent to increment the leaderboard on the server

#

Yes, have the input script in a LocalScript and have it fire a RemoteEvent so the server can update the leaderboard value

#

That way all players see the change and you can do stuff like DataStoring with it

#

Exactly

#

Sounds good

#

Feel free to DM

#

I recommend separating the PlayerAdded and PlayerRemoving events that way you don't make a new lambda function everytime a new player joins

#

And it's defining 'player' as 2 arguments in the same scope which is bad practice

#

Make this its own function

#

No problem

dreamy crow
#

Yes that could work

steep urchinBOT
#

studio** You are now Level 10! **studio

dreamy crow
#

Usually, though, when you deal with Asynchronous methods, you want to wrap them in a pcall so any errors don't break your script

dreamy crow
#
local DataStoreService = game:GetService('DataStoreService')
local DataStore = DataStoreService:GetDataStore('DataStore')

local dataPrototype = {
    ['Clicks'] = 0,
    ['Cash'] = 0
}
dataPrototype.__index = dataPrototype

local data = {
    
}

function GetData(player)
    local leaderstats = Instance.new('Folder')
    leaderstats.Name = 'leaderstats'
    leaderstats.Parent = player
    -------------------------------------------
    local clicks = Instance.new('IntValue')
    clicks.Name = 'Clicks'
    clicks.Parent = leaderstats
    -------------------------------------------
    local cash = Instance.new('IntValue')
    cash.Name = 'Cash'
    cash.Parent = leaderstats

    local isSuccess, errorMsg = pcall(function()
        data = DataStore:GetAsync(player.UserId) or {}
    end)

    setmetatable(data,dataPrototype)
    
    clicks.Value = data.Clicks
    cash.Value = data.Cash

    if not isSuccess then warn(errorMsg) end
end

function SaveData(player)
    local leaderstats = player.leaderstats
    local clicks = leaderstats.Clicks
    local cash = leaderstats.Cash
    data.Clicks = clicks.Value
    data.Cash = cash.Value

    local isSuccess, errorMsg = pcall(function()
        DataStore:SetAsync(player.UserId,data)
    end)

    if not isSuccess then warn(errorMsg) end
end

function OnServerShutdown()
    for i, player in pairs(game.Players:GetPlayers()) do
        coroutine.wrap(SaveData)(player)
    end
end

game.Players.PlayerAdded:Connect(GetData)
game.Players.PlayerRemoving:Connect(SaveData)

game:BindToClose(OnServerShutdown)
dreamy crow
#

The first version of it didn't work
This one, I tested and it works

steep urchinBOT
#

studio** You are now Level 7! **studio

dreamy crow
#

It saved the data for me

#

Are you sure you're changing the data from the server?
When you playtest it

#

Can I see how you're incrementing the clicks?

#

That's why

#

You're incrementing the data on the client, meaning the server can't see the changes, and thus can't save any data

#

No, you can use RemoteEvents for that

#

It's alright, I struggled with the same thing

#

Not really
So let me guide you through it

#

Here we have a localscript on the client which sends data to the server.
The remote event is somewhere the client and server can access (usually ReplicatedStorage)

#

Kind of

#

You can think of it this way

#

ServerScriptService is like the main lobby
StarterPlayerScripts is a bunch of rooms (They can't see into each others rooms or the lobby)
ReplicatedStorage is like a letterbox on each room's door where the lobby and room can communicate

Each room's door has a one way mirror where the lobby can see into it but the room can't see out of it

#

A remote event is kind of like a letter that gets sent from the Client to the Server or vice versa

#

So in your localscript you'd have something like this

local event = game.ReplicatedStorage.RemoteEvent

function IncrementData()
    -- User Input Detection
    event:FireServer()
end
#

No, you can keep the uid as it is

#

Just replace the player.leaderstats.value += 1 to [RemoteEvent]:FireServer()

#

In the local script

#

Basically, everytime the localscript detects the player clicking, it fires the event

#

Then you need to catch that event in ServerScriptService with something like this

local event = game.ReplicatedStorage.RemoteEvent

event.OnServerEvent:Connect(function(player)
    player.leaderstats.Value += 1
end)
dreamy crow
#

Sry I'm back

#

Let me put it into studio and check it

#

Might be because you need to wait for it to be created

#

Try this

game.Players.PlayerAdded:Connect(function(player)
  local leaderstats:Folder = player:WaitForChild('leaderstats')
  leaderstats.Power:GetPropertyChangedSignal('Value'):Connect(function()
    checkLevelUp(player)
  end)
end)
#

Idk it might work

#

If not I'll do a re-code

#

Does it work then?

dreamy crow
#

Nice

#

So few things

#

I made a bit of a simpler recode for the server

#

Here's the setup
(Usually when a script servers more than 1 thing, it's bad practice)

#

You really don't have to

#

But here's the datastore (Made it simpler)

local DataStoreService = game:GetService('DataStoreService')
local DataStore = DataStoreService:GetDataStore('DataStore')

--local event = game.ReplicatedStorage.ClickIncrement

local leaderstatsName = 'leaderstats'
local dataClass = {
    ['Power'] = 0,
    ['Level'] = 0
}

function OnPlayerAdd(player:Player)
    local leaderStats = Instance.new('Folder')
    leaderStats.Name = leaderstatsName
    leaderStats.Parent = player
    
    local data
    
    local success, msg = pcall(function()
        data = DataStore:GetAsync(player.UserId) or {}
    end)
    
    if msg then warn(msg) end
    
    for k, v in dataClass do
        local value = Instance.new('IntValue')
        value.Name = k
        value.Parent = leaderStats
        value.Value = data[k] or v
    end
end

function SaveData(player:Player)
    local leaderstats:Folder = player[leaderstatsName]
    
    local data = {}
    for i, value:IntValue in leaderstats:GetChildren() do
        data[value.Name] = value.Value
    end
    
    local success, msg = pcall(function()
        DataStore:SetAsync(player.UserId,data)
    end)
end

function OnServerShutdown()
    for i, player in game.Players:GetPlayers() do
        coroutine.wrap(SaveData)(player)
    end
end

game.Players.PlayerAdded:Connect(OnPlayerAdd)
game.Players.PlayerRemoving:Connect(SaveData)
game:BindToClose(OnServerShutdown)
#

And the CheckLvlUp is pretty much the same, just more condensed

local event = game.ReplicatedStorage.ClickIncrement -- Your Directory

local lvlThresh = {
    [1] = 25,
    [2] = 50,
    [3] = 100,
    [4] = 200,
    [5] = 400,
    [6] = 800,
    [7] = 1600,
    [8] = 3200,
    [9] = 6400,
    [10] = 12800,
    [11] = 25600,
    [12] = 51200,
    [13] = 102400,
    [14] = 204800,
    [15] = 409600
}

function checkLevelUp(player:Player,leaderstats:Folder)
    local power:IntValue = leaderstats.Power
    local level:IntValue = leaderstats.Level

    for lvl, powerreq in pairs(lvlThresh) do
        if power.Value >= powerreq and level.Value < lvl then
            level.Value = lvl
        end
    end
end

game.Players.PlayerAdded:Connect(function(player)
    local leaderstats:Folder = player:WaitForChild('leaderstats')
    local power:IntValue = leaderstats:WaitForChild('Power')
    power:GetPropertyChangedSignal("Value"):Connect(function()
        checkLevelUp(player,leaderstats)
    end)
end)

event.OnServerEvent:Connect(function(player)
    local lvl = player.leaderstats.Level.Value
    local pwr = player.leaderstats.Power
    if lvl < 10 then
        pwr.Value += 1
    elseif  lvl >= 10 and lvl < 15 then
        pwr.Value += 2
    elseif  lvl >= 15 and lvl < 20 then
        pwr.Value += 3
    elseif  lvl >= 20 and lvl < 25 then
        pwr.Value += 4
    end
end)
#

No, you can remove it

#

I forgot to remove that mb

#

It doesn't do anything in that script

#

And I did test this

#

It works

#

It's just not safe from autoclickers lol

#

Yeah that works

#

Assuming this is the result you want

#

You could do something like this

local startValue = 25
local numElements = 10

function genLvlValues()
    local lvlvalues= {}
    local value = startValue

    for i = 1, numElements do
        lvlvalues[i] = value
        value = value * 2
    end

    return lvlvalues
end

function checkLevelUp(player:Player,leaderstats:Folder)
    local power:IntValue = leaderstats.Power
    local level:IntValue = leaderstats.Level

    local lvlThresh = genLvlValues()

    for lvl, powerreq in pairs(lvlThresh) do
        if power.Value >= powerreq and level.Value < lvl then
            level.Value = lvl
        end
    end
end
#

Then adjust the variables if you need to change anything

#

lvlValues is never defined in 'checkLevelUp()'

#

You'd probably want to add

local lvlValues = getLvlValues(x,y) -- Startvalue and numElements

Above the for loop

#

Works better as well if you predefine startValue and numElements at the top so you can always change them if neccessary

#

I see

#

What is the console showing

#

Alr

#

What broke about it?

steep urchinBOT
#

studio** You are now Level 8! **studio