Responsive Combat

I am currently working on a combat system and need advice on how to make it feel responsive while maintaining synchronization between the client and server. Here’s a brief overview of my current implementation:

  • When the client presses a key, an animation is played instantly with client-sided checks (cooldown and combo).
  • Simultaneously, a remote function is invoked on the server (without yielding the client) to validate the cooldowns and the state change. If the validation fails the animation on the client is cancelled, otherwise the player state is changed.
  • Then when the client hits an enemy (the hitbox is on the client), effects and sounds are played based on the enemy’s state and a remote event is fired to the server to validate the hit and state. If valid then the enemy is damaged and effects and sounds are played for other clients.

However, I am encountering an issue where the states on the client and server are not always synchronized. For instance, when a client hits an enemy, they play effects for hitting the enemy. However, due to delayed state replication, the actual state of the enemy on the server might be ‘parry’, which triggers the parry effect for others and prevents damage to the enemy.

I would greatly appreciate any advice or suggestions on how to address this issue.

2 Likes

As far as I am aware Roblox runs at about 30Hz tick rate. Meaning it is relatively slow at processing and sending data compared to the AVG game tick rates of 60-128Hz for fast paced games that require more responsive gameplay like FPS games.

I think the main solution would be try and do as much calculations on the client as possible instead of waiting for a response.

Another idea could be to update all clients or clients engaged with fighting eachother when a stance changes. If player one holds the parry button, send this to server and server sends this to player 2. When player 2 tries to hit player 1 they already have the information that player 1 is parrying. It’s not the nicest way but it might feel a little smoother, I’m not sure to be honest without testing

This is what I already do. Player states are stored in attributes and thus they they should instantly replicate to every client when changed on the server. However the problem is the delay while sending the remote after hitting a player. For example if I have 100ms ping, it would take the server around 0.1s to receive the remote and the player states might have changed by then. I did try playing effects for the attacker after validating on the server but it was super delayed and did not feel responsive at all.

Unfortunately, because of the nature of latency, I don’t think it’s possible to create a system like this. You cannot change how state replication works, so we have to adapt to it.

I’d say move most things like hitboxes and states onto the server. While this may introduce slight input delay, it will eliminate the issue present and the slight lag is very, very hard to notice when < 100 ping.

1 Like