JavaScript API en - TerLauncher/TL-Mods GitHub Wiki
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+)
- NativeArray.cloneResized (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.projectile.registerNew (v22+)
- tl.texture.load (v22+)
- tl.texture.loadAnimation (v22+)
- tl.cheatMenu.getItemCategories (v22+)
- tl.cheatMenu.addItemCategory (v22+)
- tl.cheatMenu.addItemToCategory (v22+)
- tl.cheatMenu.getNpcCategories (v28+)
- tl.cheatMenu.addNpcCategory (v28+)
- tl.cheatMenu.addNpcToCategory (v28+)
- tl.cheatMenu.getBuffCategories (v28+)
- tl.cheatMenu.addBuffCategory (v28+)
- tl.cheatMenu.addBuffToCategory (v28+)
- tl.directory.create (v27+)
- tl.directory.delete (v27+)
- tl.directory.exists (v27+)
- tl.directory.listDirectories (v27+)
- tl.directory.listFiles (v27+)
- tl.path.getName (v27+)
- tl.path.getParentPath (v27+)
- tl.path.join (v27+)
- tl.log (v22+)
import.meta.currentDirectory StringDescription: 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"
NativeArray.cloneResized(number newLength) -> NativeArrayDescription: creates a new array (an instance of the NativeArray class) of size newLength and copies elements from the old array into it
Version: 22 and above
Example:
main.js
const Main = new NativeClass('Terraria', 'Main');
const initial = Main.itemFrame; // int[]
tl.log('Before cloning:');
tl.log(' Initial length = ' + initial.length);
const cloned = initial.cloneResized(initial.length + 1);
tl.log('After cloning:');
tl.log(' Initial length = ' + initial.length);
tl.log(' Cloned length = ' + cloned.length);
tl.log(' Last cloned value = ' + cloned[cloned.length - 1]);
tl.log('Before updating cloned:');
tl.log(' Initial[0] = ' + initial[0]);
tl.log(' Cloned[0] = ' + cloned[0]);
cloned[0] = 1234567;
tl.log('After updating cloned:');
tl.log(' Initial[0] = ' + initial[0]);
tl.log(' Cloned[0] = ' + cloned[0]);Log content:
Before cloning:
Initial length = 401
After cloning:
Initial length = 401
Cloned length = 402
Last cloned value = 0
Before updating cloned
Initial[0] = 0
Cloned[0] = 0
After updating cloned:
Initial[0] = 0
Cloned[0] = 1234567
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) -> NativeClassDescription: 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() -> NativeObjectDescription: 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 NativeObject.unwrap(NativeObject wrappedValue) -> AnyDescription: с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 NativeObject.wrap(Any value, String type) -> NativeObject
type - byte | sbyte | short | ushort | int | uint | long | ulong | float | double | bool | char | stringDescription: 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 StringDescription: 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 IntegerDescription: returns the integer version of Terraria
Version: 22 and above
Example:
main.js:
tl.log(tl.info.terrariaVersionCode)Log content: 300543
tl.mod.name StringDescription: 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 StringDescription: 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 StringDescription: 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 StringDescription: 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 IntegerDescription: 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 StringDescription: 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) -> BooleanDescription: 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) -> BooleanDescription: 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) -> StringDescription: 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) -> IntegerDescription: 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.projectile.registerNew(String projectileName) -> IntDescription: adds a new projectile with the name projectileName to the game and returns its ID
Version: 22 and above
Example:
let projectileId = tl.projectile.registerNew("Some cool projectile");
tl.log(projectileId);Log content: "1022"
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) -> StringDescription: 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) -> BooleanDescription: 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.cheatMenu.getNpcCategories() -> String[]Description: returns the current list of NPC categories in the cheat menu
Version: 28 and above
Example:
main.js:
tl.log(tl.cheatMenu.getNpcCategories())Log content: "all,enemy,boss,npc,friendly,mod,redirected,redirectedAnimated"
tl.cheatMenu.addNpcCategory(String categoryName, String iconPath) -> StringDescription: adds a new category to the list of NPC categories in the cheat menu and returns its name (": ") in the category list
Version: 28 and above
Example:
main.js:
tl.log(tl.cheatMenu.addNpcCategory("animated category", "textures/animated.gif"));
tl.log(tl.cheatMenu.addNpcCategory("static category", "textures/static.webp"));Log content:
00000000-0000-0001-0000-000000000001: animated category
00000000-0000-0001-0000-000000000001: static category
tl.cheatMenu.addNpcToCategory(String categoryName, int id) -> BooleanDescription: adds a NPC to the specified NPC category in the cheat menu and returns whether the addition was successful (unsuccessful if the category with the specified name is not found)
Version: 28 and above
Example:
main.js:
let categoryName = tl.cheatMenu.addNpcCategory("static category", "textures/static.webp");
tl.cheatMenu.addNpcToCategory(categoryName, 10);
tl.cheatMenu.addNpcToCategory(categoryName, 201);tl.cheatMenu.getBuffCategories() -> String[]Description: returns the current list of buff categories in the cheat menu
Version: 28 and above
Example:
main.js:
tl.log(tl.cheatMenu.getBuffCategories())Log content: "all,buff,debuff,weaponBuff,mod"
tl.cheatMenu.addBuffCategory(String categoryName, String iconPath) -> StringDescription: adds a new category to the list of buff categories in the cheat menu and returns its name (": ") in the category list
Version: 28 and above
Example:
main.js:
tl.log(tl.cheatMenu.addBuffCategory("animated category", "textures/animated.gif"));
tl.log(tl.cheatMenu.addBuffCategory("static category", "textures/static.webp"));Log content:
00000000-0000-0001-0000-000000000001: animated category
00000000-0000-0001-0000-000000000001: static category
tl.cheatMenu.addBuffToCategory(String categoryName, int id) -> BooleanDescription: adds an buff to the specified buff category in the cheat menu and returns whether the addition was successful (unsuccessful if the category with the specified name is not found)
Version: 28 and above
Example:
main.js:
let categoryName = tl.cheatMenu.addBuffCategory("static category", "textures/static.webp");
tl.cheatMenu.addBuffToCategory(categoryName, 10);
tl.cheatMenu.addBuffToCategory(categoryName, 201);tl.directory.create(String directoryPath) -> BooleanDescription: 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) -> BooleanDescription: 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) -> BooleanDescription: 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.path.getName(String path) -> StringОписание: returns the file name from the given path
Version: 27 and above
Example:
main.js:
tl.log(tl.path.getName("files/map_data/info.txt"));Log content: "info.txt"
tl.path.getParentPath(String path) -> StringОписание: returns the path to the parent directory from the given path
Version: 27 and above
Example:
main.js:
tl.log(tl.path.getParentPath("files/map_data/info.txt"));Log content: "files/map_data"
tl.path.join(String... paths) -> StringОписание: joins the given path segments into a single path
Version: 27 and above
Example:
main.js:
tl.log(tl.path.join("files", "map_data", "info.txt"));Log content: "files/map_data/info.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!"