How do you add a IntValue to make a stage counter?

Hi, I am new to scripting and these are the questions I want to answer.

  1. What do you want to achieve? What I want to achieve is to make a Intvalue for a stage counter.

  2. What is the issue? The issue for me is that I am new to scripting and I want to know how to add a IntValue to make a stage counter?

  3. What solutions have you tried so far? Solutions that I have tried is looking on yt videos, the devforum, and the devhub.

1 Like

So first what you want to do is add a new IntValue instance inside the player when they first initially join

-- Server script
game.Players.PlayerAdded:Connect(function(player)
    local stageCount = Instance.new('IntValue',player)
    stageCount.Name = "StageCount" -- the name of your value
end)

If you want to put this in a GUI, you can set up a changed event to see when it will change, and if it does, update the GUI

-- Client script in GUI

local Player = game:GetService('Players').LocalPlayer
local StageCount = Player:WaitForChild('StageCount')
local Text = script.Parent -- location of the UI object you will update

StageCount:GetPropertyChangedSignal('Value'):Connect(function()
   Text.Text = StageCount.Value
end

This is just a really simple system, I hope you can build off of that.

3 Likes

Hey there! First of all, create a script into serverscriptservice, this will the script that creates the intvalue.

Then, type the following code:

game.Players.PlayerAdded:Connect(function(player)
     
end)

This code contains a build-in function called player added, this function runs each time a player has joined the game, upon the player joins, we’re going to make a new folder called “leaderstats”, this folder is required for the leaderboard, without this folder, there won’t show up a leaderboard.

game.Players.PlayerAdded:Connect(function(player)
     local leaderstats = Instance.new("Folder") -- Making the folder
     leaderstats.Name = "leaderstats" -- Make sure to NOT change the name of this, else it won't show up on the leaderboard.
     leaderstats.Parent = player -- Parenting the folder to the player
end)

Now, we can create the actual value, like this:

game.Players.PlayerAdded:Connect(function(player)
     local leaderstats = Instance.new("Folder") -- Making the folder
     leaderstats.Name = "leaderstats" -- Make sure to NOT change the name of this, else it won't show up on the leaderboard.
     leaderstats.Parent = player -- Parenting the folder to the player

     local stage = Instance.new("IntValue") -- Making the value
     stage.Name = "Stage"
     stage.Parent = leaderstats -- Make sure to parent the stage to the leaderstats and not the player, else it won't show up at the leaderboard
end)

Great! Now we technically already created the value, but we may want to save the player’s progress, we will do this using the datastore service.

First of all, we will define a variable for the datastore service and for the datastore itself. When defining a data store, you need to use the datastore service.

local dataStoreService = game:GetService("DataStoreService") -- This will define the variable for the datastore service.
local stageDataStore = dataStoreService:GetDataStore("StageDataStore") -- This will get a new datastore by using datastore service.

Now we called the datastore service and the datastore itself, we will have to get the data from the datastore and set the int value equal to that data, we can do that using GetAsync, with GetAsync, you basically get the data stored on a datastore, you also have to define which player you are getting the data store, this is usually done by the user of the player since if the player changes their name, he will still keep his data.

     local stage = Instance.new("IntValue") 
     stage.Name = "Stage"
     stage.Value = stageDataStore:GetAsync(player.UserId) -- Getting the data from the player's user id
     stage.Parent = leaderstats
end)

Almost there! The last thing we will have to do is actually save the data since now we’re only getting it, but we would also have to save it. You can do that by using SetAsync, this is similar to GetAsync, except this time you don’t get the data, but you set the data, make sense, right? We will only save the data when the player leaves, so all their progress will be saved directly after leaving, and when the player joins again, all of their data is saved.

So first of all, let’s check when the player leaves the game.

game.Players.PlayerRemoving:Connect(function(player)
     
end)

So this event will fire when a player left the game.

Great! Let’s now save the data. We would have to use 2 arguments for this, the player’s userid (once again), since we’re getting the data from that, so it would make sense to also save the data from there, and what we would like to save, so the stage value.

game.Players.PlayerRemoving:Connect(function(player)
     stageDataStore:SetAsync(player.UserId, player.leaderstats.Stage.Value) -- Saving it by the player's user id, and we're saving the stage's value.
end)

Now, this would technically work, but there is still a problem when the game gets shut down (by a network problem for instance) and the player gets kicked unexpectedly, the player left event may not fire, and the data may not save, what would be unfortunate, so what we will have to do, is we will have to check when the game shuts down. We can do this using game :BindToClose().

Like this:

game:BindToClose(function()

end)

Alright, but there’s a problem with it, we don’t know which player’s data we have to save, well, when a server shuts down, obviously, we want to save everyone’s data, we can do this using an in pairs loop, with this we will loop through something (in our case the players) and do something with that player. In our case, saving their data.

This would work like this:

game:BindToClose(function()
     for i, v in pairs(game.Players:GetPlayers()) do
          
     end
end)

Okay, so you may be a little confused, like, where does that i and v stand for? Well, i stands on the index, so on which number is the player, this is mostly useful for example tables, what’s a whole different subject, so don’t focus on i too much, what we want to focus on, is the v, the v is the item itself, in our case, the player, so v stands for our case for the player, you can even change the v to the player, if that’s less confusing for you.

So let’s now save the player’s data again, we can do this exactly like we did this in the player removing function.

game:BindToClose(function()
     for i, player in pairs(game.Players:GetPlayers()) do
         stageDataStore:SetAsync(player.UserId, player.leaderstats.Stage.Value) 
     end
end)

Now, if you would have followed all these steps, your script should look something like this:

local dataStoreService = game:GetService("DataStoreService")
local stageDataStore = dataStoreService:GetDataStore("StageDataStore")

game.Players.PlayerAdded:Connect(function(player)
   local leaderstats = Instance.new("Folder")
   leaderstats.Name = "leaderstats"
   leaderstats.Parent = player

   local stage = Instance.new("IntValue")
   stage.Name = "Stage"
   stage.Value = stageDataStore:GetAsync(player.UserId)
   stage.Parent = leaderstats
end)

game.Players.PlayerRemoving:Connect(function(player)
   stageDataStore:SetAsync(player.UserId, player.leaderstats.Stage.Value)
end)

game:BindToClose(function()
   for i, player in pairs(game.Players:GetPlayers()) do
      stageDataStore:SetAsync(player.UserId, player.leaderstats.Stage.Value)
   end
end)

Also, make sure that you go to settings

image

And turn HTTP and API service on:

I really hope this helped you and also made you get a better understanding of Lua, I’m not sure if you know how to let this work with your stage script, if you don’t, let me know and I can help you out.

Edit: I’m not sure if this works, I didn’t have time to test it out yet, so if it doesn’t, please let me know.

3 Likes

For some reason when I went to another stage the counter went up. Why did this happen?

That would be an issue with your stage script, could you send the script to me?

local dataStoreService = game:GetService(“DataStoreService”)
local stageDataStore = dataStoreService:GetDataStore(“StageDataStore”)

game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new(“Folder”)
leaderstats.Name = “leaderstats”
leaderstats.Parent = player

local stage = Instance.new("IntValue")
stage.Name = "Stage"
stage.Value = stageDataStore:GetAsync(player.UserId)
stage.Parent = leaderstats

end)

game.Players.PlayerRemoving:Connect(function(player)
stageDataStore:SetAsync(player.UserId, player.leaderstats.Stage.Value)
end)

game:BindToClose(function()
for i, player in pairs(game.Players:GetPlayers()) do
stageDataStore:SetAsync(player.UserId, player.leaderstats.Stage.Value)
end)
hum.touched:connect(function(hit)
if hit.Parent == checkpoint then
if tonumber(hit.Name) == v.Value +1
v.value = v.value +1

end

end)