Hello! I’m making an obby game and every time you beat a stage, you should get 3 coins.
The problem is, I get coins regularly but I’m at stage 24 and when I restart, I couldn’t get any until I reach the one after which is Stage 25. Still, if I restart at Stage 3 after that, I still need to reach Stage 25 to get coins again, or I can rejoin. But I shouldn’t rejoin just to fix it- after restarting, no matter what stage I was previously on, I should get 3 coins every stage I beat.
I tried it every way I could to try to fix it but it never worked out.
My current script is below, and the main problem is above. Help is appreciated!
local DataStoreService = game:GetService("DataStoreService")
local DS = DataStoreService:GetDataStore("PlayerData")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
-- Main player setup and data handling
local function OnCharacterAdded(character)
local player = Players:GetPlayerFromCharacter(character)
if player and player.TeleportedStage.Value < 251 then
RunService.Stepped:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
humanoidRootPart.CFrame = workspace.Checkpoints[tostring(player.TeleportedStage.Value)].CFrame + Vector3.new(0, 3.25, 0)
end
end
local function SetupPlayerValues(player)
-- Create leaderstats and values folders
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local values = Instance.new("Folder")
values.Name = "Values"
values.Parent = player
-- Create all value instances
local stage = Instance.new("IntValue")
stage.Name = "Stage"
stage.Parent = leaderstats
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
local teleportedStage = Instance.new("IntValue")
teleportedStage.Name = "TeleportedStage"
teleportedStage.Parent = player
local speedCoil = Instance.new("BoolValue")
speedCoil.Name = "SpeedCoil"
speedCoil.Value = false
speedCoil.Parent = values
local jumpCoil = Instance.new("BoolValue")
jumpCoil.Name = "JumpCoil"
jumpCoil.Value = false
jumpCoil.Parent = values
local fusionCoil = Instance.new("BoolValue")
fusionCoil.Name = "FusionCoil"
fusionCoil.Value = false
fusionCoil.Parent = values
local laserWall = Instance.new("IntValue")
laserWall.Name = "LaserWall"
laserWall.Value = 0
laserWall.Parent = values
return leaderstats, values
end
local function LoadPlayerData(player)
local key = "player_" .. player.UserId
local success, savedData = pcall(function()
return DS:GetAsync(key)
end)
if success and savedData then
-- Load saved data
player.leaderstats.Stage.Value = savedData.Stage or 0
player.leaderstats.Coins.Value = savedData.Coins or 0
player.TeleportedStage.Value = savedData.Stage or 0
player.Values.SpeedCoil.Value = savedData.SpeedCoil or false
player.Values.JumpCoil.Value = savedData.JumpCoil or false
player.Values.FusionCoil.Value = savedData.FusionCoil or false
player.Values.LaserWall.Value = savedData.LaserWall or 0
-- Initialize reward tracking
if not player:FindFirstChild("_RewardData") then
local rewardData = Instance.new("Folder")
rewardData.Name = "_RewardData"
rewardData.Parent = player
local lastRewarded = Instance.new("IntValue")
lastRewarded.Name = "LastRewardedStage"
lastRewarded.Value = player.leaderstats.Stage.Value
lastRewarded.Parent = rewardData
local needsInitialReward = Instance.new("BoolValue")
needsInitialReward.Name = "NeedsInitialReward"
needsInitialReward.Value = true
needsInitialReward.Parent = rewardData
end
else
-- Set default values
player.leaderstats.Stage.Value = 0
player.leaderstats.Coins.Value = 0
player.TeleportedStage.Value = 0
-- Initialize reward tracking
if not player:FindFirstChild("_RewardData") then
local rewardData = Instance.new("Folder")
rewardData.Name = "_RewardData"
rewardData.Parent = player
local lastRewarded = Instance.new("IntValue")
lastRewarded.Name = "LastRewardedStage"
lastRewarded.Value = 0
lastRewarded.Parent = rewardData
local needsInitialReward = Instance.new("BoolValue")
needsInitialReward.Name = "NeedsInitialReward"
needsInitialReward.Value = true
needsInitialReward.Parent = rewardData
end
end
end
local function SavePlayerData(player)
local key = "player_" .. player.UserId
local rewardData = player:FindFirstChild("_RewardData")
local dataToSave = {
Stage = player.leaderstats.Stage.Value,
Coins = player.leaderstats.Coins.Value,
SpeedCoil = player.Values.SpeedCoil.Value,
JumpCoil = player.Values.JumpCoil.Value,
FusionCoil = player.Values.FusionCoil.Value,
LaserWall = player.Values.LaserWall.Value,
LastRewardedStage = rewardData and rewardData.LastRewardedStage.Value or player.leaderstats.Stage.Value
}
local success, err = pcall(function()
DS:SetAsync(key, dataToSave)
end)
if not success then
warn("Failed to save data for "..player.Name..": "..err)
end
end
local function HandleCoilItems(player)
if player.Values.SpeedCoil.Value then
if not player.Backpack:FindFirstChild("SpeedCoil") then
game.ServerStorage.SpeedCoil:Clone().Parent = player.Backpack
game.ServerStorage.SpeedCoil:Clone().Parent = player.StarterGear
end
end
if player.Values.JumpCoil.Value then
if not player.Backpack:FindFirstChild("JumpCoil") then
game.ServerStorage.JumpCoil:Clone().Parent = player.Backpack
game.ServerStorage.JumpCoil:Clone().Parent = player.StarterGear
end
end
if player.Values.FusionCoil.Value then
if not player.Backpack:FindFirstChild("FusionCoil") then
game.ServerStorage.FusionCoil:Clone().Parent = player.Backpack
game.ServerStorage.FusionCoil:Clone().Parent = player.StarterGear
end
end
end
local function OnPlayerAdded(player)
-- Setup player values
SetupPlayerValues(player)
-- Load saved data
LoadPlayerData(player)
-- Set up character event
player.CharacterAdded:Connect(function(character)
OnCharacterAdded(character)
HandleCoilItems(player)
end)
-- Handle initial character if already exists
if player.Character then
OnCharacterAdded(player.Character)
end
-- Set up stage change tracking for coins
player.leaderstats.Stage:GetPropertyChangedSignal("Value"):Connect(function()
local rewardData = player:FindFirstChild("_RewardData")
if not rewardData then return end
local currentStage = player.leaderstats.Stage.Value
local lastRewarded = rewardData:FindFirstChild("LastRewardedStage")
local needsReward = rewardData:FindFirstChild("NeedsInitialReward")
if not lastRewarded or not needsReward then return end
-- INITIAL REWARD AFTER JOINING
if needsReward.Value and currentStage > lastRewarded.Value then
player.leaderstats.Coins.Value += 3
if game.ReplicatedStorage:FindFirstChild("StageCompleted") then
game.ReplicatedStorage.StageCompleted:FireClient(player)
end
lastRewarded.Value = currentStage
needsReward.Value = false
return
end
-- NORMAL PROGRESSION
if currentStage > lastRewarded.Value then
local stagesGained = currentStage - lastRewarded.Value
player.leaderstats.Coins.Value += stagesGained * 3
if game.ReplicatedStorage:FindFirstChild("StageCompleted") then
game.ReplicatedStorage.StageCompleted:FireClient(player)
end
lastRewarded.Value = currentStage
end
end)
end
-- Set up checkpoint system
for _, checkpoint in pairs(workspace.Checkpoints:GetChildren()) do
checkpoint.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
local checkpointNumber = tonumber(checkpoint.Name)
if player.leaderstats.Stage.Value == checkpointNumber - 1 then
if player.leaderstats.Stage.Value < checkpointNumber then
player.leaderstats.Stage.Value = checkpointNumber
end
end
if player.leaderstats.Stage.Value >= checkpointNumber then
player.TeleportedStage.Value = checkpointNumber
end
end
end)
end
local RS = game:GetService("ReplicatedStorage")
repeat wait() until script.Main ~= nil
local main = require(script.Main)
function recived(plr, direction)
if direction == "up" then
main.up(plr, direction)
elseif direction == "down" then
main.down(plr, direction)
elseif direction == "doubleup" then
main.doubleup(plr, direction)
elseif direction == "doubledown" then
main.doubledown(plr, direction)
elseif plr.Stages > main.TOTAL_STAGES_IN_GAME then
print("Player is in an older version of the game!")
end
end
RS.StageTransfer.OnServerEvent:Connect(recived)
for _, v in pairs(workspace.Checkpoints:GetChildren()) do
v.Touched:Connect(function(hit)
if v ~= nil then
if v.Parent == workspace.Checkpoints then
local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
if player then
if player.leaderstats.Stage.Value == tonumber(v.Name) - 1 then
if player.leaderstats.Stage.Value < tonumber(v.Name) then
player.leaderstats.Stage.Value = tonumber(v.Name)
end
end
if player.leaderstats.Stage.Value >= tonumber(v.Name) then
player.TeleportedStage.Value = tonumber(v.Name)
end
end
end
end
end)
end
-- Connect player events
Players.PlayerAdded:Connect(OnPlayerAdded)
Players.PlayerRemoving:Connect(SavePlayerData)
-- Set up auto-save
while true do
wait(120) -- Save every 2 minutes
for _, player in pairs(Players:GetPlayers()) do
SavePlayerData(player)
end
end
I’m sorry the script is very long so I made some comments. You may ask me for any scripts for something that helps fix this. Again, help is appreciated!