What is the best way to implement a dodge mechanic into a melee combat system?


Captured from Cube World, which uses a similar dodge mechanic

I’m in the process of making a combat system and am trying my best to make sure that combat feels fluid and responsive, even on poor network connections. So far, when a raycast from the player’s weapon hits another player, both the hit feedback (damaged player “glows” a bit to indicate they’ve been damaged) and damage indicator (numbers popping up above the damaged player’s head to show how much health they lost) are run on the client, and a RemoteEvent is fired to the server where verification is done.

At this point, if the hit is verified, the server damages the relevant player and tells all other clients to display the damage indicator and feedback. So far, this has worked well (only downside is that a player with high ping will think they’re damaging a player when in fact they’re not, but I’m not sure there’s a good way around that). However, I’m beginning to implement dodging, and I’m not sure of the best way to go about this.

Essentially, when a player dodges, an animation plays and they shouldn’t be targetable. I’d love to handle this in a similar fashion - client checks to see if the player being attacked is dodging, then the server verifies and only deals damage if they are. But what would be a fast and reliable way that the client could check to see if a player is dodging? So far the only thing I’ve come up with is:

weapon.OnHit:connect(function(playerHit)
    if not playerHit.Animations.Dodging.IsPlaying then
         ---run damage indicator/hit feedback code, tell server to verify/replicate
    else
         ---instead of printing the damage amount (because the player wouldn't be damaged), display "DODGE"
    end
end)

If anyone can answer that question and provide possible critiques for how I have this whole system set up, I’d greatly appreciate it.

2 Likes

Try to make a Key function with a debounce value which plays the animation and sets the debounce to false, then after the animation has played it will set it to true.
So then you could change “if not playerHit.Animations.Dodging.IsPlaying then” to " if debounce == false then"

1 Like

You could implement a system like this in a very easy way, in my opinion:

You could add a value in ServerStorage (to prevent hackers from abusing this) which would determine if the player is dodging/rolling.

If it’s true, you could change the walk animation to one that makes you feel that the player is rolling, speed, and disable the jump. And 1 second later, you could disable those functions, and disable the value.

This would be a quick way to do it, if you want a better explaination, you could ask me and i’ll answer you, i hope this helps you :+1:.

1 Like

There is something called a BinaryStringValue instance. Basically it’s just a value without a value. The only thing you can do with it is change it’s name.

Create a binary value called “Block” every time the player is blocking, when the person attacks, check if that value is a descendant of the player.

1 Like

So, I think I’ll use the value method that both you and @VegetationBush mentioned. However, since I want feedback to be immediate for the player (for example, I don’t want a player with high ping having to wait, say, 1 second before they know if they’ve hit an enemy or not), wouldn’t it make more sense to have a value (probably a BoolValue with the name set to the player’s name) for each player in ReplicatedStorage? If that’s the case, upon connecting a hit, the client can immediately check if a player was rolling or not (according to them), and then the server can verify and only deal damage if the “Rolling” value was in fact false. When a player rolls, they can fire a RemoteEvent to the server to update the bool value. If an exploiter tries to change the value locally, it might appear to them that they’re damaging the character, but in reality they won’t be. Since this is the case I don’t see a benefit to placing the value in ServerStorage. If you’ve any criticisms of this method, I’d appreciate them.

1 Like

I would still use your current method but instead you could use the Humanoid:GetPlayingAnimationTracks() method, and then check if the animation is playing, in my opinion this would be the quickest method, since everthing can be done on the client without remotes, and to verify on the server you can just check if the animation is playing again.

2 Likes

So, I’m tempted to go this route, but it would mean that the client would have to loop through all of the playing animationTracks every single time a player lands a hit. I guess the array will only ever be a few instances long at any given time, and I do send less data through RemoteEvents this way helping the server out a bit. I just wish there was some way to reference a specific animation track in a Humanoid at any given time.

yeah but that would inexpensive