Modding Guide: Difference between revisions

From APICO Wiki
Jump to navigation Jump to search
Content added Content deleted
No edit summary
No edit summary
Line 34: Line 34:
<li>First when the game loads it checks that the mods folder exists (where saves are stored), and if not it creates one</li>
<li>First when the game loads it checks that the mods folder exists (where saves are stored), and if not it creates one</li>
<li>Then the game gets all the currently "active" mods from the players <span class="aw-inline--code">settings.json</span> file</li>
<li>Then the game gets all the currently "active" mods from the players <span class="aw-inline--code">settings.json</span> file</li>
<li>When the player picks a save the game then goes through each of the active mods, attempts to compile the <span class="aw-inline--code">mod.lua</span></li>
<li>When the player picks a save file the game goes through each of these active mods and attempts to compile the main <span class="aw-inline--code">mod.lua</span> file for each mod.</li>
<li>If the mod compiled successfully, the game tries to call the mods <span class="aw-inline--code">[https://wiki.apico.buzz/wiki/Modding_API#register() register()]</span> and <span class="aw-inline--code">[https://wiki.apico.buzz/wiki/Modding_API#init() init()]</span> methods, as well as adds in any [https://wiki.apico.buzz/wiki/Modding_API#Hooks Hooks] the mod creator has specified</li>
<li>If the mod compiled successfully, the game tries to call the mods <span class="aw-inline--code">[https://wiki.apico.buzz/wiki/Modding_API#register() register()]</span> and <span class="aw-inline--code">[https://wiki.apico.buzz/wiki/Modding_API#init() init()]</span> methods, as well as adds in any [https://wiki.apico.buzz/wiki/Modding_API#Hooks Hooks] the mod creator has specified</li>
<li>Once all mods have loaded the game calls the <span class="aw-inline--code">[https://wiki.apico.buzz/wiki/Modding_API#ready() ready()]</span> hook for any mods that have subscribed to it, and then finally loads the save.</li>
<li>Once all mods have loaded the game calls the <span class="aw-inline--code">[https://wiki.apico.buzz/wiki/Modding_API#ready() ready()]</span> hook for any mods that have subscribed to it, and then finally loads the save.</li>

Revision as of 23:07, 13 August 2021

To get started with creating mods you don't need to do anything special! You just need a basic understanding of LUA and your favourite code/text editor, as well as our handy API Reference.

However to make your mod "official" you will need to apply to become a Mod Creator and get your mod approved - this will give you access to all the mod creator resources on Guilded as well as the mod uploading tools. Although players can choose to side-load APICO with any mod they download, they will get shown a warning around the mod when activated.

Modding

Getting Started

Language

As mentioned earlier, mods are written in LUA! All standard LUA libraries are available to use except io and os for security reasons. If there is something you specifically need let us know and we can look into a way of exposing it through the API! The LUA interface we are using into GameMaker is Apollo.

If you haven't written LUA before there are definitely a few quirks you'll have to get used to! Here's some common gotchas we have come across:

  • In LUA "not equals" is ~=, not !=. Using != will cause a compile error with no useful message
  • IF statements follow the format of if SOMETHING then SOMETHING end - missing the "then" will throw a compile error with no useful message
  • Lists start at 1! If you use list[0] somewhere you'll probably get "invalid key to 'next'" as you need to be using list[1] instead
  • If you see an "attempt to add a 'string' with a 'string'" error it means you used + instead of .. for string concatenation.

We recommend using the Online Lua Compiler to test the syntax of your LUA code before running it in APICO

Process

In the game, a player can choose the mods they want to load from the home screen. They'll be able to download any of the official mods and choose which downloaded mods they want to activate or deactivate. When they load their game the mods will be loaded in the following processes:

  • First when the game loads it checks that the mods folder exists (where saves are stored), and if not it creates one
  • Then the game gets all the currently "active" mods from the players settings.json file
  • When the player picks a save file the game goes through each of these active mods and attempts to compile the main mod.lua file for each mod.
  • If the mod compiled successfully, the game tries to call the mods register() and init() methods, as well as adds in any Hooks the mod creator has specified
  • Once all mods have loaded the game calls the ready() hook for any mods that have subscribed to it, and then finally loads the save.
  • Any "undefined" instances in the player save file (created by mods) are refreshed at this point

Mod Structure

For mods to work they need to follow a basic structure so that APICO can register and load mods correctly, as well as handle any errors that might occur when trying to compile your code.

Every mod needs to start with a mod.lua file at the root of your mod folder. This is the main file that initially gets loaded - a basic mod file would look something like this:

function register()
  return {
    name = "sample_mod",
    hooks = {}
  }
end

function init() 
  api_create_log("init", "Hello World!")
  return "Success"
end

When the game loads, it'll retrieve the player's mod settings to get a list of all active mods. It will then try and init these mods through the sc_init_mod() method that you'll see in the Modding Console.

This method will first try and call a register() method in your mod, which will check for duplicate names, and will then call an init() method.

Your init() method is a place for you to setup all mod code you need at the start, and needs to return either Success or an error message - this lets the game know if your mod loaded correctly.

If there are any errors while trying to define an item you'll see one of the following codes logged in the Modding Console

Error Description
Mod Failed To Init this means your mods code could not be compiled correctly! You'll also see related LUA errors logged after this error message that should help narrow down the issue
Duplicate Mod Registered this means the mod id you have provided is already registered by the game, try a different mod id
Mod Failed To Load this is shown if your init() method does not return "Success", allowing you to debug your mods setup

You don't have to put all your mode code inside the main mod.lua file (thank god!). LUA allows you to require() other modules you need from within your mod directory, like so:

require("mods.sample_mod.modules.utility")

function register()
  return {
    name = "sample_mod",
    hooks = {}
  }
end

function init() 
  utility_method() -- method defined in /modules/utility.lua
  return "Success"
end

Although you can technically require files from other mods this way, you should use the Mod Methods just so that you can be sure the mod has been loading correctly first and avoid runtime issues

Modding Console & In-Game Console

The Modding Console is a debugging tool available by pressing . and it shows all messages from both the Modding API itself as well as any logs or errors from individual mods

When enabled with api_set_devmode() the In-Game Console is an inline command runner you can use while playing the game by typing / followed by a command.

For example to spawn in 5 logs you'd use /gimme log 5