How to manage walkspeed in combat system

so i have this combat system, and i try to rework the sprint, and i notice i really have mess up walk speed, between client and server, so i want to start all over again, on the walkspeed management

what im looking to in here is:

  • manage stun walkspeed.
  • manage walkspeed when doing an attack.

im looking recomendations, or advice, or examples, etc. pls help i having this problem for so long, and i dont know where to start.

1 Like

You could apply some sort of boolean, such as an attribute, which the server changes to true or false depending on its state.

So when the player is stunned for example you set the Stunned attribute in the player to true on the server:

-- when they are stunned
player:SetAttribute("Stunned", true) --Tells everybody that the player is stunned
-- when the stun releases again
player:SetAttribute("Stunned", false) --Tells everybody that the player is stunned

Then on the client where you usually handle sprint and walk speed you should probably have a function that checks the player’s sprint status etc, and assigns their walk speed. This function can then be called on Humanoid.Running, Humanoid.StateChanged, as well as :GetAttributeChanged() for all relevant denounces and flags.

local function updateSpeed()
  -- You should probably have a variable called sprinting and one called pressing or something, pressing would tell the script they are pressing the sprint button, and sprinting tells it if they are actually sprinting
  if humanoid:GetState() == Enum.HumanoidStateType.Running and pressing == true and not player:GetAttribute("Stunned") then -- Check everything in here, also stamina and stuff
      humanoid.WalkSpeed = SprintSpeed -- Assign walk speed on the client
      sprinting = true
      -- Send remote event to server that assigns the player's walk speed on the server side
  else
    -- They should not be sprinting, so check which state they are in and if they are stunned or something then apply the proper walk speed and send the remote to the server.
    sprinting = false -- They definitely aren't sprinting here anymore
    if player:GetAttribute("Stunned") then
      humanoid.WalkSpeed = StunnedWalkSpeed
    elseif humanoid:GetState() ~= Enum.HumanoidStateType.Running then
      -- Here the player is jumping, climbing, or whatever, not sure what you want to set them to here and if you want them to stop sprinting
    end
  end
end

humanoid.Running:Connect(updateSpeed)
player:GetAttributeChangedSignal("Stunned"):Connect(updateSpeed) -- can also do this with stamina and stuff

You would want to run the same checks on the server when the client send the signal to the server.

SprintEvent.OnServerEvent:Connect(function(player)
  -- The same stuff as in updateSpeed function pretty much, might need to be a bit different since its on the server
end)

These checks will also change the walk speed but globally, so your server sided anti cheat will be able to detect large differences in the actual speed of the player and the walk speed on the server, then kick them if it reaches some sort of threshold.

I’ve never made an anti-cheat, but this is how I’ve been making my sprint system and other stuff, although there could be a better way out there that I don’t know of.

The code I provided is just an example and barely functional, if you need any more assistance in implement this kind of system, I’m glad to help.

2 Likes

thanks so much, ima use this example and see whats up, cuz i use tho a stunned attribute, but is more like ehhh if there any value in a folder the stun attribute is on true if else is on false. very primitive stun system to get riddle the weird stuff when doing combos, but anyways, thanks for the example, ima use that example and see what’s up :3

1 Like

If you really want to get complicated with it, you can set a system up like a priority system, just like ContextActionService.

You could have a method which would intake an actionName, a walkSpeed, and a priority number.

You can then sort based via priority and set walkspeed from the action or effect with the highest priority. For example:

WalkSpeedManager.NewInput("Stunned",4,10) 

You can also have methods to remove those inputs so that you can resort and see which is then the highest priority. Meaning once the stun effect is removed, then the normal attack walk speed will be at the highest priority, meaning you’ll be all fine.

I only recommend this if you have multiple effects that factor into WalkSpeed.

2 Likes

emmh i have a question, it working i can see, but, when i make the running input, doesnt check the function, what check should i put?, and what i make for the server side for the check, i put only player kick, this is just for asking but should add something more on the server side? other than player kick?.

here are the scripts:

client:

local stun_value = chr:WaitForChild("Values").StunFolder.OriginalStunned.Stun -- this is my stun value, like the attribute you put on the example

local lastTime = tick()
local pressing_runningbutton = false
local sprinting = false -- i re-named the press and sprint bool variable
local speedremote = replicatedstorage.Basics.WalkSpeedCheck

local function updateSpeed()
	-- You should probably have a variable called sprinting and one called pressing or something, pressing would tell the script they are pressing the sprint button, and sprinting tells it if they are actually sprinting
	if human:GetState() == Enum.HumanoidStateType.Running and pressing_runningbutton == true and not stun_value.Value then -- Check everything in here, also stamina and stuff
		human.WalkSpeed = 25 -- Assign walk speed on the client
		sprinting = true
		human.AutoRotate = true
		print("running", pressing_runningbutton, sprinting)
		speedremote:FireServer(pressing_runningbutton, sprinting, stun_value.Value) -- Send remote event to server that assigns the player's walk speed on the server side
	else
		speedremote:FireServer(pressing_runningbutton, sprinting, stun_value.Value) -- They should not be sprinting, so check which state they are in and if they are stunned or something then apply the proper walk speed and send the remote to the server.
		sprinting = false -- They definitely aren't sprinting here anymore
		if stun_value.Value then
			human.WalkSpeed = 0
			human.AutoRotate = false
			print("stun", pressing_runningbutton, sprinting)
		elseif human:GetState() ~= Enum.HumanoidStateType.Running then
			human.WalkSpeed = 16
			human.AutoRotate = true
			print("normal walk", pressing_runningbutton, sprinting)
			-- Here the player is jumping, climbing, or whatever, not sure what you want to set them to here and if you want them to stop sprinting
		end
	end
end


UIS.InputBegan:Connect(function(input,gp)
	if gp == true then 
		return
	end
	if input.KeyCode == Enum.KeyCode.W then
		local now = tick()
		local difference = (now - lastTime)

		if difference <= 0.5 then
			pressing_runningbutton = true
		end
		lastTime = tick()
	end
end)

UIS.InputBegan:Connect(function(input,gp)
	if gp == true then 
		return
	end
	if input.KeyCode == Enum.KeyCode.W then
		pressing_runningbutton = false
	end
end)

human.Running:Connect(updateSpeed)
chr:GetAttributeChangedSignal("Stunned"):Connect(updateSpeed) -- can also do this with stamina and stuff

serverside:

game:GetService("ReplicatedStorage").Basics.WalkSpeedCheck.OnServerEvent:Connect(function(player, press, spr, stun)
	local maxwalkspeed = 25
	local maxstunspeed = 0
	local maxwalkspeednormal = 16
	
	if player.Character.Humanoid:GetState() == Enum.HumanoidStateType.Running and press == true and not stun then
		if type(player.Character.Humanoid.WalkSpeed) ~= "number" or player.Character.Humanoid.WalkSpeed >= maxwalkspeed then
			player:Kick("walkspeed_kick")
		end
	else
		if stun then
			if type(player.Character.Humanoid.WalkSpeed) ~= "number" or player.Character.Humanoid.WalkSpeed >= maxstunspeed then
				player:Kick("stun_walkspeed_kick")
			end
		elseif player.Character.Humanoid:GetState() ~= Enum.HumanoidStateType.Running then
			if type(player.Character.Humanoid.WalkSpeed) ~= "number" or player.Character.Humanoid.WalkSpeed >= maxwalkspeednormal then
				player:Kick("normal_walkspeed_kick")
			end
		end
	end
end)

to explain my self more ima show a video, and something that explain more, is after to dont pressing the “W” still i can run and having the walkspeed change:
(sorry for the low quality, potato pc)


(after pressing “W” 2 times, only can change the speed by just jumping)
@Chrasher_06

i mean is a more complicated method, but i think theres no more rather then stun, some random attack of yourself, and sprint that effects the walkspeed

Sadly, your video isn’t loading for me!

On the client, I think you’re doing most things right, except for that you don’t want to send the stunned value through a remote event. Not only can an exploiter change this value on the client as they wish, which would completely make your checks on the server useless, they can fire remote events on their own and could simply put “true” where you put sprinting. Instead, only send the input along with the remote event as that is the only thing that the client should be able to change freely.

The client can’t be trusted by the server AT ALL, therefore, passing on values such as sprinting and stunned through a remote event isn’t a good idea. Instead retrieve the stunned value on the server and check if its true or false there.

This, on the server, would therefore be useless and is easily exploited:

As for the server script, you seem to have misunderstood something:

Movement is handled entirely on the client, so the walk speed doesn’t need to be replicated to the server to do something. So the server doesn’t know what the client has set walk speed to, at the most, they know the velocity of the character and can check if that aligns with the player, but you’d want to do this in your anit-cheat system, not here.

What this remote event is used for is to tell the server when the client changes the walk speed, from where the server then runs its own checks, and sets the walk speed to what it thinks its right. This doesn’t prevent the client from changing its walk speed as the server can’t change what the client has put it to, but now the server knows what their walk speed is.

From here, you want to build a server sided anti cheat, which checks if the velocity and walk speed align. If they don’t align within a certain threshold, the player will then be punished.

This means that the lines in which you check if the walk speed >= what its supposed to be, are useless.

Building a robust anti cheat requires deep knowledge of client to server communication and replication, therefore I recommend you read into it or maybe even search for an open-source option, although that might cause issues with your system as these anti-cheats are not built to fit your specific use case.

1 Like

sorry for not responding, i been waiting a lot but, damn i mean, im very new to the anti cheat stuff, now if i think of about it you are really right, and the mean time i change a little bit the scripts, but kinda stills is the same what i give you recently, i have very poor knowledge about between client and server so there for, when i was making the anti cheat one, the server check, i thought i needed to make those player kick, but before i thought what youre saying, make an actual check to say the server that the player speed that is set on, are right, but i scratch that at the moment, bc of my poor knowledge about the anti cheat and client and server, still im thinking to finish the whole thing, and just posted to idk, just to have it there for more people to watch it