Hmm... Battlegrounds Game?

So basically, I’m making a battlegrounds sort of game. I have no idea how to make a skill system the most optimized, secure, modular, simple possible way.

It’s like how to secure local scrips, how to organize the server scripts, how should I do the sanity checks, should I check the hitboxes client-side or server-side, how do I even check collisions on the server, best way to organize the modules, balancing between performance and security…

I’m kind of a beginner at this since I’ve always been making singleplayer games and didn’t have to deal with security and optimization since it could all be done with only Local Scripts.

ORIGINAL IDEA
So then I brainstormed and just got a general idea of how should I organize this game. There are some issues though.

  • Local script that detects input and fires the server
  • Server requires a module that handles technical stuff (damaging or hitboxing)
  • Server fires all clients and tells them to replicate the visuals
  • All clients replicate the visuals from the same module

Note: I have a series of modules, each one representing a character. Each character has a number of skills. The module has functions for each skill. My idea was to place it in ReplicatedStorage so there was only a single module to handle both the server stuff and the client stuff.

Example:

local Infernal = {}

if RunService:IsServer() then
     function Infernal.FireballServer()
     -- do stuff
     end
  elseif RunService:IsClient() then
     function Infernal.FireballClient()
     -- do stuff
     end
end

return Infernal

I tried implementing this by making a Fireball skill, but then I came into more problems. How should I implement the movement? Tweening? Body Instances? RunService? Something else?

I also realized that having one module for all wasn’t really secure. I thought that I could make it inaccessible for the client in the technical side by simply using RunService:IsClient(). Now I know that any module a client requires can still be modified by the client (so the :isClient() thingy prolly doesn’t work). But now I don’t want to mirror each of the modules so one is server-side and another is client-side. Maybe it’s the only way? Maybe my entire framework is trash and there are way better alternatives?

I’ve also heard about the FastCast module for these types of situations. But for the sake of learning, I just don’t want to use it for now.

Another related thing: For projectiles that follow the mouse’s direction, I have the client fire repeatedly to the server its mouse position with UnreliableRemoteEvents. There is probably a better way to do so (or maybe it’s just fine). Maybe the server directly doesn’t need the mouse position and the client can handle it just fine with some sanity checks.

Maybe I should just do it, and not worry too much about it being perfect, but I’m kind of lost, so yeah…

6 Likes

Instead of using a single model, you should split modules as you need. If the client will never access certain functions, you should place them in ServerScriptService to prevent theft. The basic modules would be:

  • Server: Character attacks
  • Server: Sanity checks
  • Both: Shared functions
  • Client: Primary hit detection
  • Client: Visual Effects

The client should also handle their own input and character movement, including stun and knockback.

8 Likes