Modding

This page is meant to be a resource for modders. If you want to use mods in Avorion, check out this page: Using Mods

Avorion can be modded by changing existing or adding new scripts to the game.
As of now, there are multiple kinds of script that are used by the game. These scripts are loaded by the game and provide functions that will be executed by the game, all during runtime. This interface varies from script type to script type.
There are already a lot of scripts running in the game, for missions, objects, sectors, items, generating sectors and many more.

You can review the script code for the core game, Workshop mods and manually installed mods.

Script File Locations
 Workshop Mods
 Manually-installed Mods

**Disclaimer: In order to mod the game, you should have a basic understanding of programming and the programming language Lua.**

## General Interface Overview

### Scripting API

Note: These are only a few excerpts of the API for an initial overview. For a full overview of the API provided by Avorion, please check out the Scripting API or the included documentation in your Avorion install folder (open *Avorion\documentation\index.html* in a web browser).

### Script Functions

Scripts need to have a certain methods defined, depending on the type of the script, that will be called by the game at specific points during the update loop. When a script is loaded into memory, the entire script will be executed once. After this, the game will invoke certain functions defined in the script. Which functions are called, as well as their names and arguments, depend on the kind of script you're working with.

Here's an example of what the predefined functions of a script can look like:

```
function initialize()
    -- called only once in the lifetime of a script, when the script is first attached to an entity, player or sector
    -- or when the object it's attached to is loaded from disk
end

function update(timeStep)
    -- will be called periodically, every frame if not configured otherwise
end

```

Note: Script functions that are not used by the script (especially functions like **update** above that would be called every update frame) should not be defined in the script in order to improve performance. It is faster not to call a function at all, than to execute an empty lua function.

For a full overview of all the callable, predefined functions of all possible scripts, please check out the Predefined Functions in the Scripting API.

### API Functions

The game exposes a large API of various functions that can be called from scripts. These functions are either bound to an object, or can be called without a specific object.

An example for such a function would be:

```
Entity(id):moveBy(vec3(1, 0, 3))

```

This function is called "moveBy" and is associated with the object type "Entity".

Depending on which application the script runs on (server or client), different API calls will be available. For example, there won't be any rendering functionality on the server scripting API.

For a full overview of all functions of all objects, please check out the Objects section in the Scripting API.

### Callbacks

Sometimes, when scripting, it is easier to be notified when something special happens in the game, than checking every update step whether or not that special event happened.
So scripts can register callback handlers for different callbacks. These handlers will then be executed whenever a certain event happens.

To register a callback handler, use the callback registration functions. Registering a callback would look something like this:

```
function onStartUp()
    Server():registerCallback("onPlayerLogOff", "handlePlayerLogoff")
end

function handlePlayerLogoff(context, player)
    print("A player has logged out.")
end

```

In this example, a function called "handlePlayerLogOff" is registered at the server as the callback handler for the event "onPlayerLogOff". So, whenever a player logs out of the server this function will be executed.

For a full overview of all the possible callbacks of all objects, please check out the Callbacks section in the Scripting API.

## Avorion Modding Quirks

Avorion has a few quirks considering modding and its handling of lua. You may have come across these quirks while reading its lua code.

You should also be aware of the pitfalls that come with the Avorion Scripting API.

### include() instead of require()

Avorion defines its own version of `require()`: `include()`. `include()` behaves the exact same way as `require()`, with one important difference: It can load mod file extensions. `require()` can only load a single file, and that can be problematic. It can be necessary for mods to modify files such as *data/scripts/lib/utility.lua*, which are being `require`d by other lua files. But `require()` doesn't know about Avorion's mod structure, and so it cannot load additional files provided by mods, that are supposed to change how *data/scripts/lib/utility.lua* works.

`include()` looks for those files in addition to the vanilla file, and includes them into the loaded file.

You can read more about mod loading with include, and why you should use it, here.

**Note:** `require()` is still around and wasn't altered at all.

### Restricted Access to local File System

In Avorion, client mods only have restricted access to the file system, for security reasons. So with `io` functions, you cannot modify files outside of *%AppData%/Avorion* (*~/.avorion/* on Unix).

### print()

Avorion extends the basic `print()` function of lua a little, to implicitly format strings. You can use `print()` like this:

```
print("Hello World")
> Hello World

```

```
print("%s was here", "Someone")
> Someone was here

```

```
print("%s was here %i days ago", "Someone", 5)
> Someone was here 5 days ago

```

## See Also

* Writing your own Mod
* Scripting API
* Avorion Internal Architecture
* Dedicated Server Mods
* Using Mods
* Uploading Mods To The Workshop
* Quick-start Guide