How do I avoid a "god script" in a modular structure? Or is it even worth pursuing a fully-modular hierarchy?

For the sake of experimentation and trying out new structures of coding, I’ve looked into creating a game from solely modules, with only two non-ModuleScript objects (one Script, one LocalScript) The problem is that I’m unfamiliar with this kind of a structure and in my mind, this leads to those two scripts becoming “god scripts”.

image

Does anyone have experience with this structure? How do you get your games running off of purely ModuleScripts, with only two auto-executing scripts to wrap it all together in a neat little present? Is it something even worth pursuing?

4 Likes

Based on experience, I don’t think there is a way to make use of a module script without requiring it in the first place from a local script or server script and actually telling the module do something. You can’t make a two modules work independently because a module script won’t know when to start unless it is told to.

Edit:
Whoops, I didn’t quite understand the post (haven’t slept yet)

That’s not what I’m asking though. I’m aware that ModuleScripts don’t execute without being required. The two scripts, the script in ServerScriptService and a LocalScript in StarterPlayerScripts or somewhere else, would handle such initiation of modules. I’m asking how to avoid making those two god scripts and not have all modules depend on them.

I’m thinking that if those two scripts throw errors due to errors in a ModuleScript, everything else will come crashing down.

it won’t crash down if you make them run in a coroutine or a spawn. depending on which you want to use. but i wouldn’t recommend using just 2 scripts as your main and then require all the module scripts from within those 2. so basically the idea of a “god script” is a not so handy idea as you stated you don’t want them to become a god script. i don’t see there would be a diferent way but to use several scripts

1 Like

Disregard my first reply

I have tried something like this actually, it’s not a very good model to follow and will lead to a very cluttered environment. A “god script” is achievable, but not worth it. In the long run, fixing and expanding code will be a pain. It actually depends on how far you want to take this method, I was able to get good results, but meh I’d rather not try it again.

1 Like

I’d rather not use any of those unless that’s imperative to the situation. A lot of the modules within the repository will probably lazy-loaded, if not all of them. That being said, perhaps eager-loading some of the codebase could solve my issue? I’m not really experienced with this architecture so I’m not too sure.

There are already who people who do this and implement OOP structures along with it. Some use a few more than just two scripts total but the total script count is low, opting to partition most of the codebase towards ModuleScripts.

What was your experience in that cluttering? I personally think that a modular structure gives more organisational clarity to your codebase, as well as allowing for a lot of your code to be highly reusable. I could even opt to format my repository similarly to Nevermore, where ModuleScripts are categorised within folders by responsibility or area of operation.

Hearing from someone who’s tried this kind of a structure would be valuable information, because I’m not sure whether it’s worth the pursuit or not; and if it is, then how to try doing this properly.

Yep, that’s what I mean. I don’t want a god script. If those god scripts fail, the game fails as well. I’d like to avoid that scenario.

OOP structures are usefull i must say that. OOP combined with error handling (such as pcall) could be usefull and give you an option to lower the usage of scripts in a game yet error handling here is still an issue i assumme since i only use OOP in datastorages. modulair structures are perfectly fine but you do need to make sure that all the errors are dealt with (concidering scripting wise) and that errors made via a client to the server (and vise versa) aren’t blocking the rest of the code making the script(s) irresponsive

1 Like

Disclaimer:
This is a personal experience, I have my coding practices :woman_shrugging:

Basically, it would depend on what kind of game you are making, a simple game is simpler and less cluttered, a complex game is seriously gonna take kill some brain cells. The cluttering I am referring to is making use of several Module functions repeatedly and the organization of events and global variables (not safe for people with OCD)

I think you’ve seen my post

This is basically what I am referring to, but I’d recommend not to use only two regular scripts.

Basically, if you follow what the replies are in here say, you shouldn’t have an issue.

Doing this is really worth the learning experience, I just personally consider this as “not worth it” because I really want my scripts to be as expanded as possible.

The claustrophobia really kicks in working with your given “two scrips” condition.

2 Likes

I was DMed by Dandystan via Discord who provided some insight on the matter. I’m probably going to attempt a structure similar to this. It doesn’t really solve the problem of trying to avoid a god script, but it exposes an XY-ish problem of not really using ModuleScripts for their intended purpose.

DM exchange here.



6 Likes

pcall isn’t an error handler, it wraps your function in a protected mode and catches errors. Error handling is the thing you do based on if the call is unsuccessful and you handle the aftermath. I’m also not entirely sure how this post is relevant to my problem, since it only discusses the aforementioned implement I’ve seen of this style of organising a codebase (two scripts, rest are ModuleScripts).

If you’ve ever worked in Java, then that’s how I tend to use modules - as different processes which work with each other to ultimately create the desired emergent behaviour. Coming from a Java background it makes plenty of sense to me and keeps everything relatively easy to work with. I do ultimately have a starter script but that works at the highest level of abstraction.

A lot of Roblox developers have just one Script and one LocalScript that do nothing but require one or more modules, but there is nothing wrong with having a bunch of top-level server or client initialization code in there too. If you organize most of your code into modules, your structure is probably fine. The bad design pattern to avoid is having a top level script that is a huge monolithic beast of a thing that is pushing the limits of local variables and handling a lot of not-logically-related tasks. A top-level Script doesn’t need to be just a bootloader, that’s a matter of personal style.

1 Like

This sums up what I’ve tried to say :slight_smile:

I also always had questions about using ModuleScripts such as are they intended to only be used as libraries of related functions or is it also good to have them listen to events from within the module itself so that they act more like self-contained building blocks that can communicate with each other.

Yes, the latter is standard practice. ModuleScripts work well for defining OOP classes for the same reason they are good for libraries: the code they run when required only runs once per context (server/client) and the result is cached. This is ideal for libraries, and also for class definitions and you have the choice of returning the whole class as a table, or returning the constructor, or returning just the public API in a table, or you can even force a singleton by returning the return value of the constructor as the whole module return value so that everywhere it’s required you get the same instance. They are very flexible!

1 Like