I am currently figuring out how efficient this approach is, and is it exploitable in any way.
I currently have an entity class that handles serverside things, for example: ability cooldowns, stats, transferring data over to the client and etc.
And the client is split into several modules that each handle their own thing (ui, movement, camera, controls)
My ability framework on the client is split into 2 modules: the ability itself and the effects for that ability.
Firstly, theres a function that runs when a client presses a keybind for an ability. The functions checks if an ability exists and if you can actually use the ability and after that it runs the code for the ability itself, and it waits for the code to return true. The code inside that ability does things that the client should handle for the least amount of latency possible (movement manipulation, raycasting etc.) AND it also executes the code for the ablity effects (things like particles, trails, parts you get the point) after it returns true, the client fires a remote event to the server, with the only parameter being the name of the ability.
On the server, it once again checks if the ability exists, and if it has enough charges/off cooldown to be used. It then runs the server side code for the ability (damaging entities, adding items, etc…) AND it fires an event to all clients(except the player who used the ability) to replicate the effects of that ability (the particles, the trails just like i said earlier)
Sorry if this text is hard to read, i was trying to explain myself in the best way possible, with a bunch of details so you dont get confused.
Once again thank you, if you have read this and gave me your opinions about it