-
Notifications
You must be signed in to change notification settings - Fork 3
JavaScript API en
Mods are written in JavaScript. By default, JavaScript does not provide any methods for working with Terraria or mods. However, these methods are necessary, otherwise JavaScript would be useless. Therefore, TL provides an API (a set of functions) that allows you to work with the game and mods.
The set of available functions depends on the pack structure version (which can be viewed and modified in TL Packer or manually in the packStructureVersion
field in the pack's Settings.json
). We strive to ensure that new TL versions support working with all structure versions so that mods don't need to be rewritten after we change some functions. Ideally, mods should be created using the latest pack structure version available at the time of mod creation to access the maximum number of functions.
Type Conversions:
In C#, there are concepts of boxing and unboxing. Boxing occurs when an instance of a structure (or primitive) is converted to an object type. Example: object number = 3
- the primitive 3
is boxed into an object. In C#, boxing is done automatically, but for unboxing you need to specify the concrete type in parentheses (Example: object boxedNumber = 3; int unboxedNumber = (int) boxedNumber
).
The TL Mod API automatically converts primitive types to their JavaScript equivalents when working with C# objects for convenience. For example, the field Terraria.ID.ItemID.SummonerEmblem
has a type of short
, so the code new NativeClass('Terraria.ID', 'ItemID').SummonerEmblem
automatically converts the returned value to the Number
type in JavaScript.
These type conversions usually don't cause problems, but sometimes they do.
For example, you might need to pass an object as an argument to a function when creating and filling an int
array:
const Array = new NativeClass('System', 'Array');
const CreateInstance = Array['Array CreateInstance(Type elementType, int length)'];
const GetValue = Array['object GetValue(long index)'];
const SetValue = Array['void SetValue(object value, long index)'];
const Type = new NativeClass('System', 'Type');
const GetType = Type['Type GetType(string typeName)'];
const Int32Type = GetType('System.Int32');
const newArray = CreateInstance(Int32Type, 1);
SetValue(newArray, 20, 0n) // Will throw an error due to type mismatch - an object is needed, but a primitive is passed
SetValue(newArray, NativeObject.wrap(20, 'int'), 0n); // All good
const arrayBoxedValue = GetValue(newArray, 0n); // The type of `arrayBoxedValue` is NativeObject, in other words, a boxed primitive value
const arrayUnboxedValue = NativeObject.unwrap(arrayBoxedValue); // The type of `arrayUnboxedValue` is `Number`
In the example above, the Array.SetValue
method, according to its signature, takes a value of type object
as the first argument. If you pass a JavaScript Number
(20
) instead of a NativeObject
, the Mod API will not be able to determine which primitive type this number should be converted to (whether it should be passed as int
, short
, byte
, etc.). Therefore, before passing the value, it needs to be wrapped using NativeObject.wrap
.
The Array.GetValue
method, according to its signature, returns an object, so arrayBoxedValue
will not be automatically converted to a JavaScript Number
. To convert it and perform calculations using standard JavaScript operations, you need to use the NativeObject.unwrap
function.
NativeObject.wrap/unwrap
is also used to convert other C# objects to their JavaScript equivalents. For example, calling NativeObject.wrap('hello', 'string')
will return a wrapped instance of type string
, and NativeObject.unwrap(<some string object>)
will return a JavaScript string.
For information on the NativeObject.wrap/unwrap
methods, see below.
- import.meta.currentDirectory (v22+)
- NativeClass.constructor (v22+)
- NativeClass.makeGeneric (v22+)
- NativeClass.new (v22+)
- NativeObject.unwrap (v27+)
- NativeObject.wrap (v27+)
- tl.info.terrariaVersionName (v22+)
- tl.info.terrariaVersionCode (v22+)
- tl.mod.dataDirectory (v27+)
- tl.mod.name (v22+)
- tl.mod.path (v22+)
- tl.mod.uuid (v22+)
- tl.mod.packUuid (v22+)
- tl.mod.packStructureVersion (v22+)
- tl.translation.add (v22+)
- tl.file.delete (v27+)
- tl.file.exists (v22+)
- tl.file.read (v22+)
- tl.file.write (v27+)
- tl.item.registerNew (v22+)
- tl.texture.load (v22+)
- tl.texture.loadAnimation (v22+)
- tl.cheatMenu.getItemCategories (v22+)
- tl.cheatMenu.addItemCategory (v22+)
- tl.cheatMenu.addItemToCategory (v22+)
- tl.directory.create (v27+)
- tl.directory.delete (v27+)
- tl.directory.exists (v27+)
- tl.directory.listDirectories (v27+)
- tl.directory.listFiles (v27+)
- tl.log (v22+)
import.meta.currentDirectory String
Description: returns the path to the folder of the current script.
Version: 22 and above
Example:
main.js
import { callScript } from 'inner/script.js'
callScript();
inner/script.js
export function callScript() {
tl.log(import.meta.currentDirectory)
}
Log content: "inner"
new NativeClass(String namespace, String name)
Description: creates a new instance of the NativeClass
. This class allows you to work with methods from C#
Version: 22 and above
Example:
main.js
const ItemID = new NativeClass('Terraria.ID', 'ItemID');
tl.log(ItemID.SummonerEmblem);
Log content: 2998
NativeClass.makeGeneric(NativeClass[] types) -> NativeClass
Description: allows working with generic C# classes
Version: 22 and above
Example:
main.js
const List = new NativeClass('System.Collections.Generic', 'List`1');
const Int32Type = new NativeClass('System', 'Int32');
const IntList = List.makeGeneric(Int32Type);
const list = IntList.new();
list['void .ctor()']();
list.Add(5);
list.Add(10);
list.Add(15);
const lastItem = list['int get_Item(int index)'](2);
tl.log(lastItem);
Log content: 15
NativeClass.new() -> NativeObject
Description: allows creating instances of objects
Important: after creating an object, you must call one of the class constructors on the created instance. If this is not done, the object's fields will be uninitialized, which can lead to unexpected problems when working with the object
Version: 22 and above
Example:
main.js
const Viewport = new NativeClass('Microsoft.Xna.Framework.Graphics', 'Viewport');
const instance = Viewport.new();
instance['void .ctor(int x, int y, int width, int height)'](1, 2, 3, 4);
tl.log(instance.Y);
Log content: 2
NativeClass.property or NativeClass["property"]
Description: allows working with methods/properties/fields of a C# class
Version: 22 and above
Example 1 - static field:
main.js
const ItemID = new NativeClass('Terraria.ID', 'ItemID');
tl.log(ItemID.SummonerEmblem);
tl.log(ItemID["SummonerEmblem"]);
Log content:
2998
2998
Example 2 - static method:
main.js
const Path = new NativeClass('System.IO', 'Path');
const method1 = Path.GetExtension; // Works because Path has only one method named GetExtension
const method2 = Path['string GetExtension(string path)'];
tl.log(method1('file.txt'));
tl.log(method2('file.txt'));
Log content:
.txt
.txt
static NativeClass.unwrap(NativeObject wrappedValue) -> Any
Description: сonverts C# objects to JavaScript objects
Version: 27 and above
Example:
main.js
const Array = new NativeClass('System', 'Array');
const GetValue = Array['object GetValue(long index)'];
const someArray = ... // `someArray` is a NativeObject with an array of `int` inside
const arrayBoxedValue = GetValue(newArray, 0n); // Type of `arrayBoxedValue` is NativeObject
const arrayUnboxedValue = NativeObject.unwrap(arrayBoxedValue); // Type of `arrayUnboxedValue` is `Number`
static NativeClass.wrap(Any value, String type) -> NativeObject
type - byte | sbyte | short | ushort | int | uint | long | ulong | float | double | bool | char | string
Description: converts JavaScript objects to C# objects
Version: 27 and above
Example:
main.js
const Array = new NativeClass('System', 'Array');
const SetValue = Array['void SetValue(object value, long index)'];
const someArray = ... // someArray is a NativeObject with an array of int inside
const valueToSetUnboxed = 20; // Type of valueToSetUnboxed is Number
const valueToSetBoxed = NativeObject.wrap(valueToSetUnboxed, 'int'); // Type of valueToSetBoxed is NativeObject
SetValue(someArray, valueToSetBoxed, 0n);
tl.info.terrariaVersionName String
Description: returns the string version of Terraria
Version: 22 and above
Example:
main.js
:
tl.log(tl.info.terrariaVersionName)
Log content: "1.4.0.5.2.1"
tl.info.terrariaVersionCode Integer
Description: returns the integer version of Terraria
Version: 22 and above
Example:
main.js
:
tl.log(tl.info.terrariaVersionCode)
Log content: 300543
tl.mod.name String
Description: returns the pack name taken from the title
field of the Settings.json
file
Version: 22 and above
Example:
Settings.json
:
{
"title": "Interesting pack"
}
tl.log(tl.mod.name);
Log content: "Interesting pack"
tl.mod.path String
Description: returns the path to the mod directory on the user's device. TL functions that work with files consider this path as the root directory where the required file path is searched. For example, tl.file.read("some_file.txt")
will read the file from the folder tl.mod.path + '/some_file.txt'
, this happens implicitly
Version: 22 and above
Example:
main.js
tl.log(tl.mod.path);
Log content: "/storage/emulated/0/Android/data/com.pixelcurves.terlauncher/tl_files/packs/7634960c-2c5a-4509-b586-c26a35fa5546/Modified/1.mod"
tl.mod.uuid String
Description: returns the id
of the mod - the id
field inside the <mod_dir>.json
file
Version: 22 and above
Example:
<mod_dir>.json
:
{
"id": "ae7d54e7-c8db-4d66-bb50-713c76b76d59"
}
tl.log(tl.mod.uuid)
Log content: ae7d54e7-c8db-4d66-bb50-713c76b76d59
tl.mod.packUuid String
Description: returns the id
of the mod's pack - the guid
field inside the Settings.json
file
Version: 22 and above
Example:
Settings.json
:
{
"packStructureVersion": 17,
"title": "Bosses stop spawn mobs",
"guid": "7634960c-2c5a-4509-b586-c26a35fa5546"
}
tl.log(tl.mod.packUuid)
Log content: 7634960c-2c5a-4509-b586-c26a35fa5546
tl.mod.packStructureVersion Integer
Description: returns the pack structure version of the mod - the packStructureVersion
field inside the Settings.json
file
Version: 22 and above
Example:
Settings.json
:
{
"packStructureVersion": 17,
"title": "Bosses stop spawn mobs",
"guid": "7634960c-2c5a-4509-b586-c26a35fa5546"
}
tl.log(tl.mod.packStructureVersion)
Log content: "17"
tl.mod.dataDirectory String
Description: returns the directory where files are saved when the pack is updated. Use this folder to store mod data
Version: 27 and above
Example 1 (output path):
main.js
tl.log(tl.mod.dataDirectory)
Log content: "data"
Example 2 (saving and restoring data):
main.js
function saveData(dataString) {
tl.directory.create(tl.mod.dataDirectory);
tl.file.write(tl.mod.dataDirectory + "/some_data.json", dataString);
}
function restoreData() {
tl.directory.create(tl.mod.dataDirectory);
return tl.file.read(tl.mod.dataDirectory + "/some_data.json");
}
saveData("Hello everyone");
tl.log(restoreData());
Log content: "Hello everyone"
tl.translation.add(String languageCode, String jsonContents)
Description: adds a translation for the specified language
Version: 22 and above
Example: TBD
tl.file.delete(String filePath) -> Boolean
Description: deletes the file at the specified path and returns true
if the deletion is successful
Version: 27 and above
Example:
main.js
:
tl.file.write("test.txt", "Hello");
tl.log(tl.file.delete("test.txt"));
Log content: "true"
tl.file.exists(String filePath) -> Boolean
Description: checks for the existence of a file at the specified path
Version: 22 and above
Example:
main.js
:
tl.file.write("test.txt", "Hello");
tl.log(tl.file.exists("test.txt"));
Log content: "true"
tl.file.read(String filePath) -> String
Description: reads text from a file in UTF-8 encoding and returns it as a string
Version: 27 and above
Example:
main.js
:
tl.file.write("test.txt", "Hello");
tl.log(tl.file.read("test.txt"));
Log content: "Hello"
tl.file.write(String filePath, String data)
Description: writes text to a file in UTF-8 encoding
Version: 27 and above
Example:
main.js
:
tl.file.write("test.txt", "Hello");
tl.log(tl.file.read("test.txt"));
Log content: "Hello"
tl.item.registerNew(String itemName) -> Integer
Description: adds a new item with the name itemName
to the game and returns its ID
Version: 22 and above
Example:
let itemId = tl.item.registerNew("Some cool item");
tl.log(itemId);
Log content: "6000"
tl.texture.load(String filePath) -> NativeObject (Xna Texture2D)
Description: loads an image in .png
format from a file, converts it to Xna Texture2D, and returns it
Version: 22 and above
Example:
let myTexture = tl.texture.load("textures/myLovelyTexture.png");
tl.texture.loadAnimation(String filePath, Integer horizontalFramesCount, Integer millisPerFrame) -> NativeObject (Xna Texture2D)
Description: TBD
Version: 22 and above
Example: TBD
tl.cheatMenu.getItemCategories() -> String[]
Description: returns the current list of item categories in the cheat menu
Version: 22 and above
Example:
main.js
:
tl.log(tl.cheatMenu.getItemCategories())
Log content: "all,tile,wall,pick,axe,hammer,armor,melee,summon,magic,ranged,thrown,accessory,wings,shield,mount,expert,potion,fishingPole,questItem,helmet,breastplate,boots,painting,mod,redirected,redirectedAnimated"
tl.cheatMenu.addItemCategory(String categoryName, String iconPath) -> String
Description: adds a new category to the list of item categories in the cheat menu and returns its name (": ") in the category list
Version: 22 and above
Example:
main.js
:
tl.log(tl.cheatMenu.addItemCategory("animated category", "textures/animated.gif"));
tl.log(tl.cheatMenu.addItemCategory("static category", "textures/static.webp"));
Log content:
00000000-0000-0001-0000-000000000001: animated category
00000000-0000-0001-0000-000000000001: static category
tl.cheatMenu.addItemToCategory(String categoryName, int id) -> Boolean
Description: adds an item to the specified item category in the cheat menu and returns whether the addition was successful (unsuccessful if the category with the specified name is not found)
Version: 22 and above
Example:
main.js
:
let categoryName = tl.cheatMenu.addItemCategory("static category", "textures/static.webp");
tl.cheatMenu.addItemToCategory(categoryName, 10);
tl.cheatMenu.addItemToCategory(categoryName, 201);
tl.directory.create(String directoryPath) -> Boolean
Description: creates a directory with subdirectories at the specified path and returns true
if the creation is successful
Version: 27 and above
Example:
main.js
:
tl.directory.create("files/textures");
tl.log(tl.directory.exists("files/textures"));
Log content: "true"
tl.directory.delete(String directoryPath) -> Boolean
Description: deletes the directory at the specified path and returns true
if the deletion is successful
Version: 27 and above
Example:
main.js
:
tl.directory.create("files/textures");
tl.log(tl.directory.delete("files/textures"));
Log content: "true"
tl.directory.exists(String directoryPath) -> Boolean
Description: checks for the existence of a directory at the specified path
Version: 27 and above
Example:
main.js
:
tl.directory.create("files/textures");
tl.log(tl.directory.exists("files/textures"));
Log content: "true"
tl.directory.listDirectories(String directoryPath) -> String[]
Description: returns a list of directories at the specified path
Version: 27 and above
Example:
main.js
:
tl.directory.create("files/textures/custom");
tl.directory.create("files/sounds");
tl.file.write("files/file.txt", "Hello");
tl.log(tl.directory.listDirectories("files"));
Log content: "files/textures","files/sounds"
tl.directory.listFiles(String directoryPath) -> String[]
Description: returns a list of files at the specified path
Version: 27 and above
Example:
main.js
:
tl.directory.create("files/textures/custom");
tl.directory.create("files/sounds");
tl.file.write("files/file.txt", "Hello");
tl.log(tl.directory.listFiles("files"));
Log content: "files/file.txt"
tl.log(Object data)
Description: logs the passed object
Version: 22 and above
Example:
main.js
:
tl.log("Hello world!")
Log content: "Hello world!"