Should I have multiple scripts with PlayerAdded connections, or just one and use ModuleScripts?

(Visualization of my question below)

image

Imagine all of these scripts have multiple but similar connections. Like for example maybe Script 1, 2 and 3 have the game.Players.PlayerAdded connection while Script 4 has a PlayerRemoving connection.

The downside with this is that there are multiple duplicate connections, when I could just be using one script to have them all, then call on module scripts to do certain tasks.

64363

Would this be worth it? How many RBXSignal connections will cause an impact on my game? Is this a micro-optimization?

It looks easier to use the one module script to me. You onlt write the code once and it does the same thing.

1 Like

Probably, you got other things to worry about in memory before 3 extra event connections.

1 Like

One Module script - it’ll be much cleaner

1 Like

Here, do this:

  • Multiple Normal Scripts
  • Single Module Script
  • Other, explain below

0 voters

Unless you write an unreal amount of connections to an event like PlayerAdded, you will see almost no performance difference (provided you aren’t doing a ridiculous amount of extra work each time someone joins).

The truth is that, likely in an ideal game you would mostly be working off of a singular primary event connected to numerous reactions. But, the fact is that because this is indie-dev at its core and most Roblox coders are not as organized as you wish they were - this will hardly ever be the case.

You asked if this is a “micro-optimization” and it may be, and you can test it. That said, most games will have no problems running a few connections to core game events. Our games (whether ideal or not) hold a few separate connections to PlayerAdded for the purpose of organization and we see no performance difference (but we do still write most of our game in modules).

If this is worth it to you, then do it. Try not to stress over duplicate connections too much unless the amount is totally unnecessary or you’re planning on a massive network of connections where code cleanliness has to be kept as a top priority. Every game is different.

2 Likes

Answer (TL;DR)

No, not at all.
I don’t think this is micro-optimization; I don’t know how many RBX Signals are needed to connect to crash a game (let alone lag a game.) but as long as it’s in ServerScriptService; you should be okay, however don’t abuse the system. The most i’ve ever had is 58 in different scripts, it was a poor choice as that was when I first started scripting and it was unorganized and unnecessary.

What To Do

Option #1

For starts, you could just run multiple functions in a script with a spawn(function()) or a coroutine.wrap(function()end)(). On-top of that, you could call each function and if you want optimal organization, use one module and call to it through the script and the module can do what you need it to do.

First Example
game.Players.PlayerAdded:Connect(function(plr)
	--[[I alternate between the two depending on what i'm programming, use this as an example.]]
	spawn(function()
		--Call a function here or program here in this.
	end)
	coroutine.wrap(function()
		--Call a function here or program here in this.
	end)()
end)

Option #2 (Not Recommended)

You could put multiple connections into a script, like so;

Second Example
game.Players.PlayerAdded:Connect(function(plr)
	--[[I alternate between the two depending on what i'm programming, use this as an example.]]
	spawn(function()
		--Call a function here or program here in this.
	end)
	coroutine.wrap(function()
		--Call a function here or program here in this.
	end)()
end)

game.Players.PlayerAdded:Connect(function(plr)
	--[[I alternate between the two depending on what i'm programming, use this as an example.]]
	spawn(function()
		--Call a function here or program here in this.
	end)
	coroutine.wrap(function()
		--Call a function here or program here in this.
	end)()
end)

game.Players.PlayerAdded:Connect(function(plr)
	--[[I alternate between the two depending on what i'm programming, use this as an example.]]
	spawn(function()
		--Call a function here or program here in this.
	end)
	coroutine.wrap(function()
		--Call a function here or program here in this.
	end)()
end)

Option #3

The last thing you could do is have it tied to a module and call the functions in the module;
I won’t give a full example of this because it would be tedious to, there are plenty of examples of modules in use you can look at and Roblox has a great example of Modules and the functions inside of them; click here to view it.

What I Do

Here’s a picture example of what I do now of days;
image
I only have multiple modules because I had to have multiple modules. You can’t have modules communicate with each other on their own so I had to make this system. It’s a Module Communication system, Functions are to do things inside of the other things such as Grab the Player or tool throughout a table… etc, Commands are for admin commands, Communication is so I can communicate in-between each module and Settings is the most self explanatory, it has the settings for the other modules to refer to.


I hope this answers your question, if it did; mark it as the solution… have a great day and reply with any questions.

2 Likes

This is inaccurate. Modules can require each other and call each other and themselves, in fact they should actively be doing that in most well programmed games.

Also, in most cases, you do not need to spawn a new thread when PlayerAdded triggers. It already starts a new thread, so this would be building two threads per player which is pointless unless that thread needs to temporarily suspend the code flow.

With that said, most of your game should be wrote into modules. Having multiple modules for the sake of organization is fine. They should be requiring each other and communicating with one another where needed.

1 Like

This is and isn’t true. You are able to communicate between two modules but you need a third module to do so; however without this communication module, you can not communicate between two modules at the same time such as Module 1 talks to module 2 and then module 2 talks to module 1.
Evidence: image
Both of those modules are calling to the module Communications; hence why it errored. Here’s a thread where I asked about Module Communication. Click here to view it.

This is absolutely correct, that’s why I made sure to put (Not Recommended) in the Header.

You are right, however I must restate that you need a third module to communicate between modules; else you will be stuck with an inability to do so.

1 Like

I didn’t understand that you meant they would call one another, I thought you meant modules cannot communicate at all (that is how your statement read to me), which isn’t true. One sided communication should be taken advantage of almost always.

But yes, understanding how modules organizationally need to communicate is very important and makes things easier.

1 Like

Oh no, I get it man; I rephrased my statement to avoid confusion. Hope it helps, have a good one mate.

the benefit would be very minor a good thing to note is that event connections reuse coroutines unless they yield so even having multiple connections so long as they don’t all yield won’t cause much of performance difference

here’s a quick example I just made

local count = 0

game:GetService("RunService").Heartbeat:Connect(function()
    count += 1
    if count % 100 == 0 then
        task.wait()
    end
    print(coroutine.running())
end)

every 100 heartbeats it’ll yield for a single heartbeat which causes the coroutine to change for the next heartbeat

1 Like