Splitting your code
As we explained in the Your first mod tutorial, the only Lua scripts that get executed when the VeniceEXT engine starts up are the ones named __init__.lua
in each of the respective ext/client
, ext/server
, and ext/shared
folders. However, unless we're creating a very small mod, it is not ideal to keep all of our code in those files alone. It's instead better to split it into multiple scripts and use those when needed.
Putting code in different files
As with __init__.lua
, all your other scripts must also be within the ext/client
, ext/server
, and ext/shared
folders. You are also free to create additional folders within those folders so you can organize your code better. As should be evident by the folder names, scripts in the ext/client
directory will only be available to connecting clients, scripts in the ext/server
directory only to the server, and scripts in the ext/shared
directory to both.
For the sake of this guide, let's create a new file in the ext/server
folder and name it serverscript.lua
, and another file in the ext/shared
folder and name it sharedscript.lua
. We'll put the following code in them:
ext/server/serverscript.lua
print('This is a server script!')
serverThing = 'Some server thing'
ext/shared/sharedscript.lua
print('This is a shared script!')
sharedThing = 'Some shared thing'
The require
syntax
Now that we have created those two files, let's look at how we can use them from our other scripts. To do so, we need to use the global require(path: string)
function. We call this function by passing the file path of the script we want to load to it, and in turn it will try to find this script and execute it.
Let's look at an example. In this example we'll be assuming we're using the server-side __init__.lua
script, present in the ext/server
folder, and we'll be loading the two scripts we created above.
print('Main server script has loaded!')
require('serverscript')
require('__shared/sharedscript')
print(serverThing)
print(sharedThing)
Here, we make two calls to the require function:
require('serverscript')
to load theext/server/serverscript.lua
script, andrequire('__shared/sharedscript')
to load theext/shared/sharedscript.lua
script
As you might have noticed, in order to load scripts in the ext/shared
folder, we need to prefix the their require path with __shared/
. If we don't, then require
will try to look for a file in the ext/server
or ext/client
folder, depending on whether our mod is running on the server or the client. Keep in mind that even if we're in a shared script (eg. ext/shared/__init__.lua
) and we want to require another shared script, we still need to prefix its path with __shared
.
You might have also noticed that we don't add a .lua
suffix to the require paths. This is because the .lua
extension is optional when calling require
. We can add it if we want, but if we don't, the engine will add it for us automatically. Requiring files with other extensions is not supported.
Now that we have established how to require files, let's look at what this example will actually do. As soon as our server starts up and our mod is loaded, the following lines will be printed in the server console:
Main server script has loaded!
This is a server script!
This is a shared script!
Some server thing
Some shared thing
What happens in this example is that as soon as our script requires another script, that script gets loaded and executed. This makes our serverscript.lua
for example print the This is a server script!
line and also define the global serverThing
variable, which we then print from our __init__.lua
script.
Requiring scripts in subfolders
As we mentioned before, we can put our scripts in subfolders inside the ext/server,client,shared
folders. The way to load them remains exactly the same. For example, if we have this script: ext/server/somefolder/somescript.lua
, we would load it by calling require('somefolder/somescript')
. If we had a script in ext/shared/somefolder/somescript.lua
we would load it by calling require('__shared/somefolder/somescript.lua')
.
A thing to note is that the paths we pass to the require
call are always relative to the ext/server,client,shared
directories. What that means is that if we are have for example a require('myscript')
call inside a script that's placed in ext/server/somefolder/somescript.lua
, the engine will look for ext/server/myscript.lua
and not ext/server/somefolder/myscript.lua
.
Requiring scripts multiple times
Let's look at this example:
print('Main server script has loaded!')
require('serverscript')
require('serverscript')
You might expect this script to print:
Main server script has loaded!
This is a server script!
This is a server script!
But it will instead print:
Main server script has loaded!
This is a server script!
That is because when we require
a script, it will only get loaded and executed once, regardless of how many times we require
it again in the future.
Returning values from scripts
Another thing you can do is that you can return values from your required scripts. Let's change the ext/server/serverscript.lua
script to this:
print('This is a server script!')
return 'Hello other script!'
As you see, we return a value at the end of the script by using the return
keyword. If then in our ext/server/__init__.lua
script we do the following:
print('Main server script has loaded!')
local serverScriptValue = require('serverscript')
print(serverScriptValue)
We will see the following lines printed in our console:
Main server script has loaded!
This is a server script!
Hello other script!
Basically, the value we return
from our script will be returned by the call to require
.
Another thing to note is that the rule about scripts being executed only once still applies to return values. If for example we change the ext/server/serverscript.lua
script to return a random number:
return math.random()
And then we require it multiple times from another script and print its return value:
print(require('serverscript'))
print(require('serverscript'))
print(require('serverscript'))
We will notice that all three prints will print the exact same number.