Combat system Client/Server relations

Hello guys !

I’m starting to work on some top down mmorpg.
And of course there is combat, pve and pvp.

To give you an idea of the skills available in the combat system, let’s just speak about a grab skill (prototype don’t judge):


I think it’s one of the most complex from a network point of view, but maybe I’m wrong (I just added a dash and a basic combo for now anyway)

So for now I do the following :

  • Client/Get input

  • Client/Process the input and fire the server for a specific skill activation

  • Client/Attack animation

  • Server/Get the event for the specific attack

  • Server/Set player walk speed to 0

  • Server/Create hitbox and do damage on touch (should be a simple box raycast though)

  • Server/Move the ennemy (npc or player)

  • Server/Connect beam for vfx

  • Server/ If the attack is asked when someone is grabbed, then launch it
    And some other little stuff

So basically I always give the ownership to the server on the player asking to trigger an attack, and give it back after the execution. And when the grab start I give the ownership to the player who caught the ennemy, and reset it when released.

Even with this there is things I’m wondering :

  • Animation on the server would be a good way to trigger the hitbox on a specific part of the animation. I saw on the forum that animation on the server should be okay.
  • Some vfx need a target, which can be only know from the server if it’s not a player

But then I tried to simulate lag (only inside Roblox Studio, I couldn’t manage to setup a software to control my ping), and realized that if there is some delay, even in pve, the game would be unplayable.
I think the right way to manage the combat system is to be able to compute everything on the client and the server, and comparing the results and correct if needed.

So I searched in this direction, but… even for a simple attack, if I want the player to simulate the hit and everything. It needs ownership for at last the collision check, and maybe other things like humanoid health. And I would still need the server to trigger other clients, would this not be a problem? I’m also wondering about AI.

So the question, after all this ^^, how do you setup the architecture for this ?

Sorry for the big question, band thanks !

3 Likes

This is how I’d design the architecture for it.

1. Client-Side Processing:

a. Input Handling:

  • Client/Get input: Continue to handle input on the client side. This is where players initiate their actions.

b. Client-Side Prediction:

  • Client/Predictive Animation: Use predictive animations on the client side to initiate local visual effects (VFX) and animations for the player without waiting for the server response.

c. Client-Side Hitbox:

  • Client/Simulated Hitbox: Simulate hitbox on the client side for visual feedback. However, do not apply damage or other significant effects at this point. This is purely for the player’s visual experience.

2. Server-Side Processing:

a. Skill Activation:

  • Server/Process Input: Receive input from the client, validate it, and decide whether the action is legal and should be executed.

b. Animation Synchronization:

  • Server/Animation Control: Manage animations on the server for synchronization and to decide the correct timing for hitboxes and effects.

c. Server-Side Hitbox:

  • Server/Real Hitbox: Execute the real hitbox calculations on the server side. This ensures accuracy and prevents cheating.

d. Networking:

  • Server/Network Communication: Communicate the results of the skill activation, hitbox calculations, and game state changes to all relevant clients.

3. Ownership Management:

  • Ownership Transfer: For skills like grabbing, manage ownership effectively. For the duration of the grab, the server should have control, and ownership should be transferred back when the grab is released.

4. Lag Compensation:

  • Lag Compensation: Implement lag compensation techniques to make the game feel responsive even in the presence of network delays. This may include client-side prediction and server reconciliation.

5. Consistency Checks:

  • Consistency Checks: Periodically synchronize client and server states to ensure consistency. If discrepancies are found, correct them to prevent cheating or other issues.
4 Likes

Animation, VFX, and creating hitboxes can all be done on the Client.

Animations played on Client will replicate to the server as long as the animation is in a client-server shared space (replicated storage for example) you can also use Keyframe events on the client as well and fire them to the server if you need anything done there.

Creating hitboxes can be done on the client, and then on hit you can fire to the server to deal damage and or effects/weld for a grab attack if you wish. make sure to sanity check to check for exploits.

If i were you, I would

  1. Detect Input on client, play the animation, then fire a hitbox/raycast/boxcast (or whatever method of hitbox) Infront of the player (use keyframes or task.wait to time when you want the hitbox to be cast)

  2. On touch: Fire the hitboxes’ position and hit-target to the server

  3. After making sure the hitbox should have actually hit with a sanity check; Deal damage, set walk-speed and jump-power to 0, fire an event to all-clients to cast VFX and weld the target to the player for a grab on the server.

If you still require help after this, or it did not solve your problem, please do reply back.

5 Likes

Thanks for your answer !
But the solution you propose will wait for the server answer to apply the hit on the client right ? So if he’s laggy you’ll see the player spamming attack and see the impact after the lag delay no?

1 Like

To be honest don’t use ontouched and just use something better. On touch is inaccurate and bsd in practice.

I personally use my own module that other used too and the people who’ve used it have reported good results.

Module (usecase explained within module) :

1 Like

Thanks for the answer !
With both of you speaking about client raycast I decided to check again, and lucky me raycast doesn’t need ownership or whatever. So I definitely can trigger everything on the client side, put change the values and fire a remote function (maybe event ?) to tell other clients what happenned.

There is just a few things I didn’t understand :

  • 2b Animation synchronization : How do you “manage” the animation on the server, like if you start it again, it isn’t going to overwrite the client one ? And I don’t really have to tell other clients for the animation right ? And if I connect the server on specific keyframes, it could be already over. Basically I don’t know how to do it ^^
    EDIT : Looking at my last reply, I see a way to do this : creating an invisible clone of the player and play the animation on the server. Was it what you were thinking about ?

  • 3 ownership management : you’re saying that both player should be owned by the server ? Or only the grabbed one ? I wanted to try back both, but I run into some issues. But because there is so much lag when the player isn’t the owner of it’s character, shouldn’t the ownership goes to either only the one who used the grab or either both player ? I tried to let the ownership of the grabbed one to the server, but it didn’t work. Not sure if I did something wrong.

1 Like

Yeah don’t worry, I even realized that raycast doesn’t need network ownership. Still have an issue with the group filter, but that outside this thread ^^

1 Like

Would it be a good idea to create a local clone and use it for this like pushing an ennemy/player ?
Hidding the real one (local transparency/i have no collision anyway) and swaping with the clone only when the other player is in a situation like hit stun, push…

So if Player1 attack Player2, even if Player1 is lagging he’ll see the attack and hit animation. Meanwhile the server will be computing the real outcome and send events to synchronize everyone. And even during a grab, both player would get smooth animations and only get a “visual glitch” at the end of the skill (position mainly).

1 Like

Yes you can use invisible clones I’ve seen someone use them before, I don’t remember who and I’ve never tried to do it. You can achieve what you want without invisible clones everything has its pros and cons

1. Server-Side Animation Control Logic:

On the server, maintain control over critical animations and use a system to dictate the animation state. You can use RemoteEvents to receive animation-related commands from clients, as demonstrated in the previous examples.

2. Client-Side Animation Prediction:

Clients can initiate animations locally for a more responsive feel. However, this should be treated as a prediction, and the server will validate and correct discrepancies during reconciliation.

3. Server Reconciliation:

After receiving client updates, reconcile the client’s predicted animation state with the authoritative server state. This ensures that animations are synchronized across all clients.

4. Timestamps for Animation Events:

Include timestamps in animation events to track when they occurred. This helps in cases where an animation event is triggered at a specific keyframe, and the server can use the timestamp to determine the appropriate time to apply the animation.

“And if I connect the server on specific keyframes… Basically I don’t know how to do it ^^”

To do this:

1. Animation Keyframe Events:

Roblox provides an Animation Editor where you can define keyframes and events within an animation. When defining your animations, mark the keyframes that are critical for server-side actions.

2. Server-Side Animation Event Handling:

-- Client-side code
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer

local AnimationEvent = ReplicatedStorage:WaitForChild("AnimationEvent")

-- Function to trigger animation event
local function triggerAnimationEvent(eventName)
    AnimationEvent:FireServer(player, eventName)
end

On the server, listen for animation events and respond accordingly. You’ll need to identify which keyframes correspond to specific events and trigger server-side logic at those moments.

-- Server-side code (Server Script)
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local AnimationEvent = ReplicatedStorage:WaitForChild("AnimationEvent")

AnimationEvent.OnServerEvent:Connect(function(player, eventName)
    -- Validate player and eventName inputs
    if player:IsA("Player") then
        -- Get the character and humanoid
        local character = player.Character
        local humanoid = character and character:FindFirstChildOfClass("Humanoid")

        -- Check if the humanoid exists
        if humanoid then
            -- Perform server-side actions based on animation events
            if eventName == "KeyframeEvent1" then
                -- Logic for actions related to KeyframeEvent1
            elseif eventName == "KeyframeEvent2" then
                -- Logic for actions related to KeyframeEvent2
            -- Add more conditions for other keyframe events as needed
            end
        end
    end
end)

For ownership:

  1. Client Ownership for Responsiveness:
  • Approach:
    • Allow the client initiating the grab to have temporary ownership for a more responsive feel.
  • Reasoning:
    • Granting temporary ownership to the client can enhance responsiveness, allowing the player to feel immediate control over the action.
  1. Server-Side Validation and Authority:
  • Approach:

    • Even when the client has temporary ownership, critical actions (like grabbing) should be validated and authorized by the server.
  • Reasoning:

    • Server-side validation ensures that the client’s actions are legitimate, preventing potential exploits or unauthorized actions.
  • Consideration:

    • Lag can be a significant challenge when the player doesn’t have ownership of their character.

    • If there’s noticeable lag when the player doesn’t have ownership, consider strategies to minimize the impact, such as optimizing network communication or providing visual feedback to the player.

So, in summary, the client might have temporary ownership for certain actions to improve responsiveness, but the server remains the ultimate authority to validate and authorize those actions. This combination aims to provide a responsive gameplay experience while maintaining a secure and fair multiplayer environment. Now there is no “hey do this and lag will be fixed,” its all trial and error with how you are designing it all and can often times lead to headaches.

1 Like

Ahh okay I really didn’t understand what you meant with animations, that’s clear now !
I think I this discussion is at least enough for me to decide the base of my architecture and we’ll see how it does evolve !
Thanks a lot (to everyone)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.