Modding

From Avorion Wiki
Jump to: navigation, search

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.

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

Using Mods[edit | edit source]

If you want to use mods in Avorion, check out this page: Using Mods

General Interface Overview[edit | edit source]

Scripting API[edit | edit source]

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.

Script Functions[edit | edit source]

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[edit | edit source]

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[edit | edit source]

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[edit | edit source]

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()[edit | edit source]

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 required 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[edit | edit source]

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()[edit | edit source]

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[edit | edit source]