Regeneration issue

Hello, I am a Roblox scripter and recently I’ve encountered an issue which I’d never seen before on the platform. I’ll explain it down below and I would appreciate your help.

What I wish to achieve is a simple regeneration blocking system, where you regenerate your blocks while some time passes. It is not finished yet, however I encountered an issue which doesn’t let me advance further into my project. The issue itself isn’t in the coding portion, I believe and I’ve yet to find where does the specific issue come from.

As you know, I’ve already scripted a Regeneration system, however when I am changing it client-side, it regenerates instantly. Though, when I change it from the server-side, it regenerates as it should. Not sure what is the issue here, but I’d love to know the solution.

I’ve tried changing my Code and Regeneration system, yet no luck. Hence why I do not think it is a scripting issue. I have looked into the Developer forum, yet nothing satisfied me in terms of solutions. I’ll include screen-shots and Gifs of the issue down below.

When I change it from the server-side:
https://gyazo.com/c3666b65cfacd79921c076223696ae49
When I change it from the client-side:
https://gyazo.com/2da0ea010e528a3c2073d86d86f50761

Server-Script:

-- 
local block = game.StarterPack.Lightsaber2.Main.Blocking
local RunService = game:GetService("RunService")
local Lightsaber = game.StarterPack.Lightsaber2
local Player = game.Players.LocalPlayer
local Debounce = false
local MaxBlock = 6
local REGEN_AMMOUNT = 1
local NextRegen = tick() + 1
game:GetService("Players").PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(Character)
		local Humanoid = Character:WaitForChild("Humanoid")
		local isBlocking = Instance.new("BoolValue")
		isBlocking.Name = "isBlocking"
		isBlocking.Value = false
		isBlocking.Parent = Humanoid
		local BlockingDetector = Instance.new("IntValue")
		BlockingDetector.Name = "BlockingDetector"
		BlockingDetector.Parent = Humanoid
		BlockingDetector.Value = 6		
RunService.Heartbeat:Connect(function()		
		if tick() >= NextRegen then
		   NextRegen = NextRegen + 1
			wait(3)
			BlockingDetector.Value = BlockingDetector.Value + REGEN_AMMOUNT
			if BlockingDetector.Value >= MaxBlock then
				BlockingDetector.Value = MaxBlock
				end
			end
		end)
	end)	
end)

block.OnServerEvent:Connect(function(player)
	player.Character.Humanoid.isBlocking.Value = not player.Character.Humanoid.isBlocking.Value
end)

This is the server-script which covers the Regeneration system. It works perfectly fine with no errors in the output. The system itself is not yet finished, however it works with as mentioned no errors in the output. I’d appreciate anyone’s help. You are more than welcome to ask me any questions regarding this.

Took me a bit to understand what you were doing from the videos but its cause you dont update the client until everything on the server is done as seen here

block.OnServerEvent:Connect(function(player)
	player.Character.Humanoid.isBlocking.Value = not player.Character.Humanoid.isBlocking.Value
end)
local isBlocking = Instance.new("BoolValue")
		isBlocking.Name = "isBlocking"
		isBlocking.Value = false
		isBlocking.Parent = Humanoid

You are looking for a while loop, not a heartbeat connection.

It can still be done of course.

local Elapsed = 0
RunService.Heartbeat:Connect(function(dt)		
    Elapsed += dt
    if Elapsed >= 3 then
      Elapsed -= 3
      ...

By using Heartbeat, things are run asynchronously, i.e. it waited in THAT frame, but when the next frame comes in, the function is called again asynchronously, ignoring the wait you had.

I avoided wait loops as they can cause great lag on the server, though I’ll try your method and see if it works. I appreciate both of you guys’ help on this and I’ll definitely keep you updated.

No it doesn’t.
It depends on what you are doing with the loop.

Something like this shouldn’t be done with multiple while loop or heartbeat event loops anyways.

Also memory leak from not disconnecting heartbeat loops. You have been warned.

I did the code changes and the issue is still here. When I do it from the Client-side, it regenerates from 1 to 6 instantly, yet on the Server-side, it regenerates like it should.

Those lines of code focus on a different aspect of my project and aren’t really related to the Regeneration system, only for the blocking one. So, it isn’t that either.

Then you did it wrongly. There is no such thing as the server spitting different output if they are using the same thing.

local block = game.StarterPack.Lightsaber2.Main.Blocking
local RunService = game:GetService(“RunService”)
local Lightsaber = game.StarterPack.Lightsaber2
local Player = game.Players.LocalPlayer
local MaxBlock = 6
local REGEN_AMMOUNT = 1
local NextRegen = tick() + 1
local Elapsed = 0
game:GetService(“Players”).PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(Character)
local Humanoid = Character:WaitForChild(“Humanoid”)
local isBlocking = Instance.new(“BoolValue”)
isBlocking.Name = “isBlocking”
isBlocking.Value = false
isBlocking.Parent = Humanoid
local BlockingDetector = Instance.new(“IntValue”)
BlockingDetector.Name = “BlockingDetector”
BlockingDetector.Parent = Humanoid
BlockingDetector.Value = 6
RunService.Heartbeat:Connect(function(dt)
Elapsed += dt
if Elapsed >= 3 then
Elapsed -= 3
BlockingDetector.Value = BlockingDetector.Value + REGEN_AMMOUNT
if BlockingDetector.Value >= MaxBlock then
BlockingDetector.Value = MaxBlock
end
end
end)
end)
end)

block.OnServerEvent:Connect(function(player)
player.Character.Humanoid.isBlocking.Value = not player.Character.Humanoid.isBlocking.Value
end)

I am pretty certain this is how I was supposed to do it and it works. But the issue is still here. I am sorry if I am doing anything wrong.
It basically does this: https://gyazo.com/2da0ea010e528a3c2073d86d86f50761
Regenerates instantly.

You are supposed to put the Elapsed variable before the heartbeat or it will be shared by the players.
Anyhow, it doesn’t do that at all. Not for me at least.

local Elapsed = 0
game['Run Service'].Heartbeat:Connect(function(dt)
	Elapsed += dt
	if Elapsed >= 3 then
		Elapsed -= 3
		print(os.time())
	end
end)

Output:

  1615830246
  1615830249
  1615830252
...

Unless you updated the value somewhere else, there is no way that it happens.

1 Like

Didn’t work either, though I update the value of it in another script. When somebody hits the character while they are blocking, they lose 1 of the specific value. Perhaps this helps a bit more with understanding the issue?

Have you tried disabling the other script that also updates the value?

Just did so, yet it still doesn’t work. I don’t know why it happens and I am very confused.

I have also a stamina script and when I changed it on the client, it did the same thing. I don’t think it is a glitch nor an issue, but perhaps the way it works? If updated on the client, it will go back to it’s original value, however if done what triggers the value to change, for instance someone hitting my character while blocking, it will be reduced. I’ll go ahead and do a few more tests to understand this and come up with a conclusion. I’ll be sure to update you, if you wish to.

If a value is changed on the server, it is changed for all clients.
Even if a client has a localscript that does Value.Value = 9999999 if the server changed to the new value.

You should use 1 value and change that value on the server, and the client shouldn’t ever change it. Unless it is one of the edge cases like Cookie Clickers where the current value can be calculated by using the time passed since the last request, but since this not the case, you should just do the former.

If this work (printing the current time every 3 seconds) on your end than its something else.

Thanks for the help. It fixed my issue after I did some tests.