Which aproach should i take?

Hey, i decided to make artillery system, but there is a problem, i have 3 options to choose from how to do it:

  1. Have all server scripts inside each cannon model
  2. Have lightweight server script inside each cannon model that will require OOP classes from server script service to create actual cannon
  3. Have all scripts inside server script service

For now i use second aproach because it’s easier to make statement effects (i rotate few parts on server because making it on client would be less effective) or i can go for more invidual/customizable cannons, still i wanted to ask which one is best

option 3

repeating code for each cannon is unnecessary unless each cannon should have completely different code

you can use modulescripts and loop through the cannons (in one script) to get the same effect as having individual scripts inside each cannon

2 Likes

As long as your server scripts know what they are dealing with… workspace.myartillery
You really don’t need them to be in the models.

1 Like

In my project I have a total of 0 scripts outside of (ServerScriptService + 2 folders inside starterplayer). A lot of scripters that are better than me do this too. Edit: Talking about active scripts of course. Plenty of scripts in ReplicatedStorage.

For loops and event triggers in a thread should handle any system, or at least a part of the system (for example for a mining system you can have 1-2 threads for the mining process itself and then 1 script for the spawning of the mine’s minerals). If the artillity weapons act differently, I would use if statements to handle each one. Connect a bindable/remote function/event and pass the name or ID of the weapon when they fire or become active . So all of the weapons are handled by thread in a script. You could then do the same with another script that is for upgrading of the weapons.

You can do use a module script for the stat math, and insert the values like Damage and RateOfFire inside of the weapon model. Often number/int values. That way it will account for upgrades easily. A table in a script would need to be updated and scoped in a messy way, so using physical values for most of your stats / weapon information is what I prefer.

Really the only approach that is realistic with ease of hacking tools for Roblox.
May as well consider local content prototyping till it’s set up for anti-hacking also.

wdym by this.
I’m kind of clueless on hacking stuff.
Do you mean that the client can see the server scripts if they are in workspace?

?.. I meant I agree. No the client can not see the server scripts. Unless they are on the client…
They can see and mess with everything on the client…

When you run your program in the studio there are a few folders you can not open while it’s running. Them are total server folders. Anything in there cannot be touched.

The trick is to get everything that could hurt the game if hacked inside them.
local scripts fire:remotes to talk to the boss.

1 Like

Still option 3 makes that i can’t have big customizability even with systems that support it, as every cannon, also main script in cannon only initializes this cannon depending on what type is it

What do you mean by not being able to customize?

Was wondering if Server Scripts replicated to the clients if they are in workspace, which they seem to do. Good to learn stuff.
image

for instance i can add boolean debounces freely, instead of relying on tick based ones, it’s simply easier to customize and write clean code

It may just be my small brain here, but I don’t know what you mean.
You can set up a timer for each weapon.

Now I get what you mean if you have complex weapons like a champion’s in League of Legends. You should definitely make either a function or a script for each weapon that has a special, however the call to attack with the weapon should still optimally be handled by 1 event, and then send it sends you to the script/function for that weapon. And even then about half of the weapon can probably still be handled by the main thread.

	--Define gun
	local gun = character:FindFirstChildWhichIsA("Tool") --A different bool ensures this doesn't mistake it for another tool.
	if not gun then return end
	local gunClass = gun:FindFirstChild("GunClass")
	
	--Define wait for reload sound
	local wait1 = nil
	local wait2 = nil
	
	if gunClass.Value == "Class1" then
		
		wait1 = 0.3
		
	end
	
	wait2 = 1 - wait1


	--Wait for a time determined by fireRate
	task.wait(wait1/fireRate.Value)
	
	playGunSound("GunReloadSound",gun,soundAssetReload,baseVolumeValueReload,playbackspeedReload)
	
	task.wait(wait2/fireRate.Value)
	
	--Reset values
	canShoot.Value = true
	isShooting.Value = false

Sent you an image of one of my setups … image is too big to post here.

1 Like

Ok again, in setup script per model scenario, i can set up easy debounces, this mean i don’t need to store them inside objects, but rather inside script inside my cannon, also i can require my classes to get functionality, and control them directly from model , this way i have easy maintanance over specific model

If i’ll go for one script scenario, i can only call Cannon:Shoot() or Cannon:Load() also i can only create new cannon object only via pattern, this mean i can’t make

local cannon = Cannon.new("Cannon", "Iron Breech", "Wooden wheel")

this easily

If you don’t want to make values inside of the objects, you could make a grand table in the main-script approach. This is again, not something you’d usually do, because it makes things less easy to comprehend and read from: Instead of using FindFirstChild on the weapon, you’d instead determine a path in the table. However once you have set up the necessary events for the table, you can theoretically store everything inside of it without needing any physical values.

I don’t understand what you mean by not being able to do local cannon = Cannon.new("Cannon", "Iron Breech", "Wooden wheel").
It looks like a function call that creates a cannon based on its class properties, which you could set up in a module script and simply look at the cannon’s name in workspace to determine its class. If you want to get real crazy about it, you could make the name some kind of code that determines its properties, and then use string functions to decypher it.

hmmmm, ok i’ll definetively try, but last question is, if using script per cannon only to require few modules and eventually determine some functions is really bad for performance?

1 Like

Well it will generally have the same peformance no matter what approach you take, because there will be an equal amount of threads running. Beyond that, Idk peformance well. Bindable events shouldn’t delay by any noticable amount, but if you’re worried about them, you could make a function per cannon instead of a script per cannon. Each function would practically be its own script that starts when it’s called at the 1 event that triggers when a weapon requests to fire.

Now Idk how weapons are fired, but assuming it’s player input (if it’s player and input and then it autofires, you can just make a loop inside of the thread it’s firing in).

This is poorly written pseudo-code.

local functions = {

   class1 = function()

         --code for this weapon

   end

}


WeaponFireEvent.OnServerEvent:Connect(function(plr,weapon)

    functions[weapon:FindFirstChild("Class").Value}()

end)

1 Like

Use one module script that manages all of your artillery