What is the point of using module scripts and dictionaries?

What is the point of using module scripts and dictionaries? Are they used to speed up coding (through shortcuts)?

1 Like

You already made a post about module scripts recently. You should ask this question there instead of creating a new topic.

sorry! am trying to delete the topic but it is giving me an error.

Both modules and dictionaries are data structures in Lua for storing things. Both of them are tables because tables in Lua are a one-in-all, all-in-one data structure.

Think of a dictionary as a catalog of items, any item you want. Each item has a name, which acts as a key and an identifier. The object it’s assigned to is the value.

local dict = { -- your dictionary
    key1 = "value1",
    key2 = "value2"
}

You can retrieve each value in the dictionary if you have the name of it.

print(dict["key1"]) -- prints "value1". You can also do dict.key1

You can do more things with dictionaries, such as iterating (looping) through them or storing functions to change them into different data structures.

You can read more about the different types of tables.

A module can be thought of as a table that is accessible from other scripts. There’s more things you can do with it.
https://education.roblox.com/en-us/resources/intro-to-module-scripts

1 Like

ModuleScripts aren’t data structures, they’re script fragments that will only run upon the use of the require function. They can be anything you want them to be. Any code in the main scope will get ran on the first require and you can return any valid datatype out.

ModuleScripts themselves are not tables, they are still scripts. The most common return value associated with ModuleScripts are tables for the sake of creating various systems or mimicking paradigms (e.g. OOP, again another common use for ModuleScripts) but any datatype, Lua or Roblox, will work here.

For example, a ModuleScript featuring only a function:

return function(foo)
    print(foo)
end

Mhm, modules, the tables inside modulescripts are the data structures. It’s important to know that the modules themselves are accessible throughout scripts. That’s the main feature of modulescripts, not usually the code they execute, as any script can execute code. In fact, there’s a long-running debate about the merits and demerits of executable modules. Running startup code in modules often puts projects at risk of circular dependencies, which is why some developers claim it’s a misfeature in languages that support executable modules such as Lua and Python. Using modules for storage is a practice that can avoid this.

Some might argue that executable modules have the advantage of having better control over what scripts run at certain times, but I usually say there are two good ways of communicating between scripts: modulescripts and BindableEvents (and Remotes if communicating to the other side of the client-server barrier). BindableEvents accomplish this just fine. Modulescripts are good for communicating between scripts because of the wide accessibility of the modules they store.

Care to shed some light on what you’re referring to by “executable modules”? I don’t work with other programming languages so you lost me with the comparisons between Roblox modules and libraries from other languages. They’re relatively the same in concept but I don’t think they’re fully identical.

Tables are the only native data structure in Lua. Tables are tables, ModuleScripts are ModuleScripts. Dictionaries are tables that only utilise the hash part, ModuleScripts are not necessarily storage containers but are used that way (containing items) because the application of ModuleScripts in codebases like that makes sense.

By executable modules, I mean modules than run code in them when they’re require()d (or imported if we’re talking about other languages). This concept is indeed identical between the two examples I can give you: Lua and Python. In both, modules are meant to be retrieved from different files, yet, since they support executable modules, developers can also run code within the module. Modulescripts that, instead of just containing the module, run code and are executed.

It is true that ModuleScripts can be used without returning any module, but there’s no point in using a module like that when you can simply execute code with another script. And if you’re looking for flexibility with running code, BindableEvents offer more flexibility than ModuleScripts can give.

The only practical use case I can think of with a purely executable module is that it can run on both the client and the server if the ModuleScript is in some place like workspace or ReplicatedStorage.

Thanks for the clarification!

I’m not aware of any debate like that on the DevForum but there have been a few complaints about circular dependencies in the past. Some of our nice and friendly developers have made various tools in order to steer clear of that happening. This isn’t a very common complaint though, given how Roblox developers use ModuleScripts and how much is abstracted away for us.

Most small games don’t quite run into the problem of circular dependencies, but that’s not to say it can’t happen. I usually don’t rely on that automatic execution bit when using ModuleScripts and always opt to include things in a function so that I have control over when things happen and I’m aware of what will happen when I call something. I have other problems when it comes to that execution bit, such as libraries generating methods at run time (one of my projects does this and it’s not… good).

I think the part that confuses me here is when you say ModuleScripts return a module. We don’t have that term here on Roblox, it’s just as straightforward as “ModuleScripts can return a value”. If module’s referring to that piece of returning a value, then that clears things up a bit more.

In regards to ModuleScripts not returning anything (returning nil), I have had cases like that where it actually had a point and wasn’t just useless. This was when I first started adopting single-script architecture in my games, where everything ran in ModuleScripts and not from a single script. For cases like this, to retain that single entry point for code, opting to just run that code from a regular script would not be ideal because I lose control and predictability about run time, possibly even guarantees.

2 Likes

When I say “module” (as opposed to modulescript), I refer to the table of values and functions that is accessible through any script by a modulescript returning it.

I’m not aware of any debates ongoing to the DevForum either, but I’ve heard it around the Python communities. Lua has the same support for executable modules.

Using modulescripts as a continuation of a single thread (well, pseudo-thread given that Lua is single-threaded) is understandable but I think you’ll find more flexibility if you think of modules as tools that you can use in your scripts rather than a continuation of your code to take it further into your game. The code execution inside a module runs once but a function used as a tool within a module can be used any time and any number of times.

1 Like