Fast and Synced Communication

I’m working on a very fast paced game where players will be using skill combos. When a player attempts to press a skill key, what is the best way to make sure the player can use skill?

My theoretical system uses the following set up:
client - Player presses key
client - Player checks state that is repeatedly updated by a RemoteEvent
client - Change the clients active debounce (player runs animations and will call events as animation progresses) then fires to the server for the first time

server - Receives the request to use a skill and checks that the player can
server - Edits the players state and fires to client
server - Makes sure that the player can use the part of the skill it is requesting

Once the skills usage is over:
server - Fires a message to the client with the skill cool-down time
client - Displays cool down on skill bar

Is this the most viable option? If not, tell me where I can improve. Thank you.

Its pretty easy to do such thing. You check for the cooldown on the client and run the animation on the client/server (really doesn’t matter since animations Replicate) after checking if the player is able to preform said move you fire a remote event (basically gives you the ability to communicate between the client and the server learn more about them here: https://developer.roblox.com/articles/Remote-Functions-and-Events)
and you can do all your move stuff on the server.
An example would be

local plr = game.Players.LocalPlayer 
local UIS = game:GetService("UserInputService")
local cooldown = false
UIS.InputBegan:Connect(function(input,gameproc)
 if input.KeyCode == Enum.KeyCode.X and not gameproc and not cooldown then --player clicked the 
 -- Button X and his cooldown is not active
  cooldown = true
  game.ReplicatedStorage.YourRemoteEvent:FireServer()
  wait(5) -- YourCooldown
  cooldown = false
    end
end)

for further Explanation “gameproc” is a bool value that returns either true or false if the player is typing in chat/a textbox etc
for further info on how InputBegan functions work take the time to read this: https://developer.roblox.com/api-reference/event/UserInputService/InputBegan
hope that helped!