#something tells me this wont work...
72 messages · Page 1 of 1 (latest)
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
Yes that could work
** You are now Level 10! **
Usually, though, when you deal with Asynchronous methods, you want to wrap them in a pcall so any errors don't break your script
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)
The first version of it didn't work
This one, I tested and it works
** You are now Level 7! **
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)
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?
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?
** You are now Level 8! **