How would I go about making a stamina system?

Hmm, it seems that you don’t clearly understand my point is yet, even if you are using BindableEvent, it is clear that you are still firing event, which mean’s that you can save the time when a script fired the event and using a spawn(function() creating A new thread adding a wait() for when the regen can start, then compare the the tick() of when it was last fired, to the current time, with a while loop if the condition is a true then while loop will start, once A script fired another event the while loop will stop (the old thread will just end). creating another thread.

I think I understand this better, when you explain it like this. I will try and make smth!

1 Like

I already made something using only logic! I don’t have to use tick() as long as I just change some values when it spawns a function and when it ends. It basically just checks if there is already a loop going on, and if there is it returns

1 Like

That’s A good idea, my idea was from checking if the player is spamming an event, never really though of just using boolean if the event was fired or not. I might have to bookmark this for future reference.

Hmm, I only got it to work partially. When I start running it will decrease the stamina, after 2 seconds it will start generating, and if I start running mid-generate it will stop the generating as it should. However, if I start running and after 2 seconds it will generate and then jump, it will keep generating. I don’t know how to fix this, I thought these booleans would help but they didn’t

local RS = game:GetService("ReplicatedStorage")
local STAM_REMOTE = RS:WaitForChild("Remotes"):WaitForChild("Stamina")
local STAM_BIND = RS:WaitForChild("Remotes"):WaitForChild("StaminaBind")
local run = false
local timer = 0

local canRegen = true
local canSpawn = true

STAM_REMOTE.OnServerEvent:Connect(function(plr, action)
	
	local stamina = plr.Character:WaitForChild("Stamina")
	
	if action == "startedRun" then
		
		run = true
		canRegen = false
		
		while run == true do
			
			if stamina.Value >= 1 then
				
				stamina.Value -= 1
				
				wait(0.05)
				
				if stamina.Value == 0 then
					
					run = false
					
				end
				
			else
				
				stamina.Value = 0
				break
				
			end
			
			print(stamina.Value)
			
		end
		
	elseif action == "stoppedRun" then
		
		run = false
		
		wait(2)


		if canRegen == false then

			canRegen = false
			canSpawn = true

		end

		canRegen = true

		spawn(function()
			
			if canSpawn == true then
				
				canSpawn = false
			
				while canRegen == true do

					if stamina.Value < 100 then

						stamina.Value += 1

						wait(0.1)
						print(stamina.value)
						
					elseif stamina.Value == 100 then
						
						canRegen = false

					end

				end
				
				canSpawn = true
				
			end

		end)
		
	elseif action == "jump" then
		
		if stamina.Value >= 10 then

			stamina.Value -= 10


		else

			stamina = 0

		end
		
		print(stamina.Value)
		
		wait(2)
		
		if canRegen == false then
		
			canRegen = false
			canSpawn = true
			
		end
		
		canRegen = true

		spawn(function()

			if canSpawn == true then

				canSpawn = false

				while canRegen == true do

					if stamina.Value < 100 then

						stamina.Value += 1

						wait(0.1)
						print(stamina.value)

					elseif stamina.Value == 100 then

						canRegen = false

					end

				end

				canSpawn = true

			end

		end)

	end
	
end)

STAM_BIND.Event:Connect(function(plr, action)
	
	local stamina = plr.Character:WaitForChild("Stamina")
	
	if action == "punch" then
		
		if stamina.Value >= 5 then
			
			stamina.Value -= 5
			
			
		else
			
			stamina = 0
			
		end
		
		print(stamina.Value.. " punch")
		
	end
		
end)

I knew you would have this problem, because the problem with running is that you also need to check if the speed is above or below 0.

No, this is already being checked, when run = true, the player is actually running, this is also checked on client.

The issue is that whenever i jump, it doesn’t cancel the other spawned function

From what I saw in your script your should be only using 1 spawn(function() put it at the end.

Yea that’s what i just thought of, what about in the bindable, how would they cancel eachother

I would highly recommend using an array, so that the bindable event would be able to access it as well. Just use the name of the player as the variable.

Can you give me some example code? I don’t know how implementing an array / table would work here other than just normal booleans

Instead of using local canRegen = true; local canSpawn = true you should just use data[player.Name]["canRegen"] = true; data[player.Name]["canSpawn"] = true

Note: if you wan’t to remove the player from the array just create a PlayerRemoving function and just set the lastCall[player.Name] = nil.

It sounds way more complicated than it really should be, maybe I can use coroutines to yield until 2 seconds have passed since an event

local data = {}

STAM_REMOTE.OnServerEvent:Connect(function(plr, action)
	data[plr.Name]["canRegen"] = true
	data[plr.Name]["canSpawn"] = true
end)

STAM_BIND.Event:Connect(function(plr, action)
	data[plr.Name]["canRegen"] = true
	data[plr.Name]["canSpawn"] = true
end)

where would i define data (max chars)

What do you mean by data (max chars) are you also planning to add a max characters to be added?

no haha, i just couldnt send the message if i didnt add some more text

Just asking for how and where i should define data

The reason why I recommended using array is that once you have multiple player accessing the function they would have some complication with the local variable, lets say one of the player is running and the other is not running with no stamina, the player who is not running would not be able to generate A stamina since local canRegen = false.

local data = {}

STAM_REMOTE.OnServerEvent:Connect(function(plr, action)
	data[plr.Name]["canRegen"] = true
	data[plr.Name]["canSpawn"] = true
end)

STAM_BIND.Event:Connect(function(plr, action)
	data[plr.Name]["canRegen"] = true
	data[plr.Name]["canSpawn"] = true
end)

the data array should be created outside of the thread and only be assigned to each player inside the threat right?

1 Like

Yes, you can still try to use print(data) check if the name of the player who fired is there.