Modding: Difference between revisions

From APICO Wiki
Jump to navigation Jump to search
Content added Content deleted
No edit summary
No edit summary
Line 66: Line 66:
<p>The game completely trusts the save file when it loads - because of this your players save file will load with any mod content in the save (custom items, objects, etc). If it can't then find these items in the dictionary you'll end up with a bunch of pink cubes - basically undefined instances.</p>
<p>The game completely trusts the save file when it loads - because of this your players save file will load with any mod content in the save (custom items, objects, etc). If it can't then find these items in the dictionary you'll end up with a bunch of pink cubes - basically undefined instances.</p>


<p>https://www.tutorialspoint.com/execute_lua_online.php</p>
<p>https://www.lua.org/cgi-bin/demo</p>





Revision as of 16:02, 12 August 2021

This is a WIP page that I'm using to document the game's modding API as I go

function init()
  -- comment
end

Modder application form: https://forms.gle/gaqa4S6jUcoxePrA6

Mods for APICO are written in LUA. All standard LUA libraries are available 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 use into GameMaker is Apollo.

When creating a mod you will need to decide on a unique mod ID, which is a lowercase name with no spaces (underscores are accepted) - this will be used as not only your mod directory folder within the game but also for identifying your game in various debugging (so we can see which one of you keeps breaking stuff :P).

In all the documentation examples, we use sample_mod which is also the name of the sample mod you can download to test out the various API methods.

All API methods can be found here

Game Load: - Game checks mod folder area exists - Game gets all active mods for the player

Save Load: - Game goes through each active mod and calls it's register() + init() methods, adding hooks - When the game has loaded each mod it calls ready() on all hooks - Game then refreshes undefined instances (potentially made by mods) that were in the save file

Glossary

Dictionary

In the game every single item, object, machine, NPC, or button has a definition in the Dictionary. If there is not a definition the game will not recognise what you are trying to reference.

You can add definitions through the api_define_*() methods.


Modding 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


In-Game Console

When enabled, 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


Getting Started

To get started you just need your favourite IDE! You don't need to compile your LUA code in advance, the game does this when it loads your mod, so outside of any LUA extensions you might find useful you don't need any other resources

When modding is properly live, a player will be able to see all mods from the "Modding" section thats accessible from the home screen. They'll be able to pick the mods they want and download them, which will save the mod into the /mods directory, as well as update their settings.json file. For now you'll need to do this manually.

For example if your mod is called "sample_mod", you'll need to set the "downloaded_mods" key inside settings.json as ["sample_mod"], as well as add your mod in a folder called "sample_mod". Your directory will look like this:

<img/>

If done correctly, when you go to the "Modding" section you'll see your mod in the right-hand section, just inactive.Pressing the "tick" button will activate the mod, and now any time you start a game you'll see a "Loading mods..." screen


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:

mod_id = "sample_mod"

function register()
  return mod_id
end

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

function clock()
  api_create_log("clock", "1 second has passed!")
  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: 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
Error: Duplicate Mod Registered
This means the mod id you have provided is already registered by the game, try a different mod id!
Error: Mod Failed To Load
This is called if your init() method does not return "Success", allowing you to debug your mods setup


General Notes

The game completely trusts the save file when it loads - because of this your players save file will load with any mod content in the save (custom items, objects, etc). If it can't then find these items in the dictionary you'll end up with a bunch of pink cubes - basically undefined instances.

https://www.lua.org/cgi-bin/demo


Common Gotchas

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

Booleans are not real! Anytime there's a boolean involved from GameMaker you should use 0 or 1 for your comparisons.

If a hook doesn't return "Success" then it will get ignored (intentionally) - make sure you are returning something!

Lists start at 1! If you use [0] somewhere you'll probably get "invalid key to 'next'" as you need to be using [1] instead

Example Mods

Here are some basic example mods to get you started, and to show you the sort of things you can achieve with the tools available to you in the Modding API

  • Magic Biome Brush