I am not sure if this is possible, or if it is something that I will have to manually add to code, but here it is.
I am making an obby type game that has barriers that the player has to unlock to advance through levels. I have the datastore working so that it saves the Stage that player is on, so that they can rejoin the game and be back at that stage.
However, when they rejoin and are on stage 5 for example, all of the previous barriers that they unlocked are still in place.
Is there a way for me to save that the barrier were destroyed so that they do not come back when the player leaves the game and rejoins?
You can just destroy the barriers based on the player’s stage when they join the game. Do this in a local script though, because if a high level player were to join the game all the barriers would be removed for all players if it were in a server script.
Right that is what I was planning to do if there was no other way.
Would the script go in StarterPlayerScripts then?
I have on in there now that is checking for stage, and I am not sure if I did the code right, but it does not seem to be working. This is the code:
Summary
local player = game.Players.LocalPlayer
local leaderstats = player:WaitForChild("leaderstats")
local Stage = leaderstats.Stage.Value
player.CharacterAdded:Connect(function(character)
print(Stage)
if Stage == 10 then
print('oooohapa')
else
print(Stage)
end
end)
The check for Stage 10 does not work.
As you can see the print under the Stage 10 check does not play.
On another note, if I am on Stage 10, it will sometimes Print Stage 1 instead. I am assuming that this script sometimes loads faster than the leaderstats?
You could simply put all the barriers in a folder and name then accordingly ex: Barrier:1, Barrier:2
then you could save the stage where the player is at when he leaves and when he joins simply use string.split() and compare the numbers if its smaller then destroy that barrier
ex:
local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("Name Here")
local Barriers = game:GetService("ReplicatedStorage").Barriers -- Getting the barrier folder
local function Load(player)
local data
local success, errormessage = pcall(function()
-- using a pcall function so errors wont stop the code
data = DS:GetAsync("key here")
end)
if data then
local stage = data
for i,v in ipairs(Barriers:GetChildren()) do
local number = string.split(v.Name, ":")[2] -- getting the barrier number (if you followed the Barrier:1 format)
if stage >= tonumber(number) then -- if the stage number is bigger then destroy the barrier
v:Destroy()
end
end
end
end
-- check if the player joins then fire the function
Hope this helped, if you have any question reply to this and ill try my best to answer them.
So I just want to say that I very new to DataStore and have been learning it over the past few days.
This is currently how my barriers are set up, in a folder already:
Summary
So for example, I would have to rename “Barrier1” to “Barrier:1”?
I would also need this to be on a local script so that it does not destroy the barriers for all players in the lobby, where would I put this local script?
You could put it in starter player scripts, which run for every player when they open the game. It’s basically the client-version of a PlayerAdded event. Just make sure to use WaitForChild() to make sure the parts are loaded before you try to delete them or else the script may error.
You could make a RemoteEvent and when the stage data finishes loading for a player, send the player the stage number. And then in a LocalScript make a RemoteEvent.OnClientEvent connection which would listen for the stage number the server sent to the player, and then you could do a for loop to iterate all the barriers and destroy all which are labeled less than the stage sent from the server
My bad, I completely forgot that it needs to be local sided only, to fix that you could simply fire a remote event using :FireClient(playerinstance, barrierinstance) then destroying that said barrier, FireClient can not be accessed from the client so its safe to use it. (Also you can ignore the string.split and check as you please that was merely a suggestion)
Sever:
local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("Name Here")
local Barriers = game:GetService("ReplicatedStorage").Barriers -- Getting the barrier folder
local function Load(player)
local data
local success, errormessage = pcall(function()
-- using a pcall function so errors wont stop the code
data = DS:GetAsync("key here")
end)
if data then
local stage = data
for i,v in ipairs(Barriers:GetChildren()) do
local number = string.split(v.Name, ":")[2] -- getting the barrier number (if you followed the Barrier:1 format)
if stage >= tonumber(number) then -- if the stage number is bigger then destroy the barrier
remote:FireClient(player, v)
end
end
end
end
Local:
local player = game.Players.LocalPlayer
remote.OnClientEvent:Connect(function(barrier)
barrier:Destroy()
end)
in either 2016 or 2016(i don’t remember) Roblox released a feature called FilteringEnabled … Filtering Enabled works by keeping the client from making Network calls to the server. This means that, if the server(server script) makes a part, then a client(LocaScript) deletes that part, the effect won’t replicate to the server, and therefore not to other players. All exploits run in LocalScripts, that’s why you see speed hackers in FilteringEnabled games, it’s b/c user input has to be sent to the server in order to make the player move on the screen of all players, and exploiters use this to their advantage. besides speed hacking, hackers cannot do anything - such as deleting parts - in FilteringEnabled games.