Of course, due to security reasons, client-sided ANYTHING is never good. But you also don’t want to be too paranoid, because you can definitely ensure into your game anti-cheat measures, to prevent teleportation, or movement that obviously isn’t natural.
For the input delay, optimize your system, anything under that player’s current ping is pretty much impossible to negate, so if your system is reasonably optimized, and they’re still having delay, you can just tell them to get better wifi.
When designing your framework try to design a system where you only have to communicate between the server once. You tell the server you want to attack, and the server does checks and you’re good. Not doing checks on the server, then telling the client to do checks, and going back to the server and blah blah blah, that’s TOO much, you’ll get an extreme delay.
Another nuance, you might be already doing this, considering you already stated you had been working on the game for 7 months: Handle the effects on the client. Even IF your have a delay or dispositioning in the attacks, the players won’t be able to see it, because the effects are perfectly lined up.
Even in sword fighting this applies. The hitboxes are always going to be offset a bit due to latency. You’re always going to get a little “reached”, but you can’t control someone else’s terrible wifi. All you can do is try to represent the sword the best you can, right on the character’s hand. Would you rather have the sword where the hitbox is (floating), or where it is now? Of course where it is now! It wouldn’t make any sense.
For the delay of the attacks, that comes up to server speed. Try to write efficient code, even micro-efficient programming just to speed everything up as best as possible. You could even look into parallel programming, just for that extra speed.
if you’re using modules for the attacks on the server, try not to over-compute things. Have them already required, you wouldn’t want to require a whole modules over and over again everytime someone attacks. Even in general it’s going to be faster. Consider this code bit:
local function heavyWork()
-- some extreme heavy work (which returns a value)
return interestingValue
end
-- now I want to get this interestingValue
functionOne(heavyWork())
functionTwo(heavyWork())
But this is inefficient! If we know heavyWork
is going to be the same thing for functionOne and Two, why recall it? Instead we can do this:
local result = heavyWork()
functionOne(result)
functionTwo(result)
Hope this helped.