NAV Navbar
  • Introduction
  • Setup
  • Creating a module
  • The Basics
  • ChatLib
  • Rendering
  • Objects
  • Books
  • Displays
  • Guis
  • KeyBinds
  • LookingAt
  • Inventory
  • XMLHttpRequests
  • Triggers
  • Introduction

    ct.js is a framework for Minecraft Forge that allows for mods to be scripted, in languages such as JavaScript. Scripts are able to be hot reloaded, which means you can make changes to your mod without restarting!

    JavaScript scripts are executed with Java's Nashorn library, which means you can use all extensions it includes, found here.


    To setup a ct.js coding environment, all you have to do is put the ct.js jar into your .minecraft/mods folder, and launch Minecraft. In your mods folder, you will get a folder structure automatically created. The default file location is
    .minecraft/config/ChatTriggers/modules/ but this can be changed in the configuration.

    Creating a module

    To create an import, create a folder in your .minecraft/config/ChatTriggers/modules folder, and have it's name be the name of your import. Our import will be called Example. Our folder structure now looks like

    We now need to create our scripts, so create a file in the folder named whatever you would like, the name is only for your own management of the import. We'll call our main file main.

    The Basics

    Registering a Trigger

    We register a WorldLoad trigger like so:

    // OR
    register("worldLoad", exampleWorldLoad);

    The argument passed into the register function is the function you want to trigger:

    function exampleImportWorldLoad() {
    register("worldLoad", exampleImportWorldLoad);

    You can also register an anonymous function for simplicity:

    register("worldLoad", function() {

    The base of ct.js imports are "Triggers". These are events that get fired when a certain action happens in game, like a sound is played, or chat message is received. A full list of these is at the bottom of the page.

    So, we want to start of by listening to one of these, let's start with one of the simplest, WorldLoad.

    What we're doing here is calling a method in the "TriggerRegister" class that registers the exampleWorldLoad function as a trigger to be activated when the world is loaded. However, there is no function with that name yet!

    We now create a function with the same name before the register so it exists when we try and pass it into our register. We have now registered a callback for our trigger!

    Everything inside of this function is ran when the world loads. From here we can call other methods, interact with Minecraft, and many other things.

    Responding to an Event

    For code to be activated by a trigger, simply put it in your function called by that registered trigger

    register("worldLoad", function() {"&6Gold Text says that the world has just loaded!");

    One of the things we can do inside of function is send a message to the player.

    The best way to interact with Minecraft's chat is via the ChatLib class. It is accessed very simply through the variable ChatLib. A list of the methods it provides can be found in the documentation here.

    A more complicated Trigger

    A chat trigger that gets fired on the chat message <FalseHonesty> Hello World!

    register("chat", function(message, event) {
    }).setChatCriteria("<${*}> ${message}");

    This function receives chat messages based on a certain criteria. If a received chat message follows the pattern put in .setChatCriteria(), then the function will be called. ${variableName} creates a variable in the criteria, and when the event is fired, its value is passed into the function.

    TriggerRegister.registerChat() and .setChatCriteria() return the created trigger, so you can chain configuration methods. A list of these are found in the documentation for each specific trigger type, you can find the available modifications here.

    Canceling events

    To cancel a cancellable event, do this:

    register("chat", function(message, event) {
      cancel(event); // OR event.setCanceled(true);
 "I did cancel this: " + message + "!");
    }).setChatCriteria("<${*}> ${message}");

    The event parameter is optional, so this works just the same if you don't need to use the event

    register("chat", function(message) {"I didn't cancel this: " + message + "!");
    }).setChatCriteria("<${*}> ${message}");

    Some events are cancelable, like chat events. If it is cancelable, the last parameter passed into the function will always be the event.


    The ChatLib is a utility provided to imports for interacting with Minecraft chat. It has functionality to send, edit, and delete messages in Minecraft's chat. You can create clickable, and hoverable, text in chat, run commands, and much more.

    Sending messages

    This sends a message in chat"Coming from the code!");

    This sends a message in chat that doesn't trigger chat listeners"Coming from the code, but I don't trigger anything!", false);

    The first example sends a simple string into the player's chat. However, this will trigger all imports' chat triggers with our message. If we send this message in a trigger that listens for the same one, the game will crash.

    That's where the second example comes in. The false flag passed in at the end indicates that we don't want this to occur, and no imports will receive this message.

    Message objects

    This example sends messages that have clickable and hoverable text

    var clickableMessage = new Message("This is not clickable. ", ChatLib.clickable("This is clickable", "run_command", "/help", "This is shown when hovering over the message!"), "!");
    var hoverableMessage = new Message(ChatLib.hover("This message does nothing when clicked.", "But it shows this text when hovered over!"));;;

    Here we are creating new Message objects. These are required to send messages that have clickable or hoverable text. The constructor of a Message can take as many strings, ChatLib.clickable(text, action, value, hoverText), or ChatLib.hover(text, hoverText) as you want, simply separate them with commas as shown in the first example. All of these can use color codes.


    The first message we create is a message that has clickable, and non-clickable, text. The first part is regular text, followed by a clickable part that runs the /help command when clicked, and shows the hoverText when the mouse is hovering over that part of the message. Then, at the end, it has a non-clickable exclamation point.


    The second message created and chatted is a message that only contains a hoverable message. Nothing will be activated or ran when the message is clicked.

    Message IDs

    This is how you send a chat message with an ID, and then delete it"This will be deleted!", 5050);

    This is how you send a message object with an id, then delete it

    var myMessage = new Message("This will be deleted!");
    myMessage.chatLineId = 5050;;

    Every message can have an ID specified, which can then be deleted from chat. This is best suited for auto-replacing menus, chat messages you only want to display in chat for a certain amount of time, etc.

    Only one chat message can have the same ID, as it will replace any messages with the same ID before sending. The ID is passed as the last argument, and you pass the same ID to ChatLib.clearChat(id) to delete it.

    Specially formatted messages

    This is how you center a chat message"This is in the center of the chat!"));

    This is how you make a line break"-"));

    Centered messages

    To center a message in chat (padded by spaces), use the ChatLib.getCenteredText(text) method, and then chat what's returned.

    Line breaks

    To create a line break in chat that will be the exact length of the chat box no matter the user's width and size settings, use the ChatLib.getChatBreak(seperator) method. This can take any seperator, like "-" as we used in the example.

    Editing chat

    This is how you edit a chat message after it has been sent to chat"Hey there! This will change...");
    ChatLib.editChat("Hey there! This will change...", "And... changed!")

    ChatLib.editChat(message, replacer) is a simple method that takes in an unformatted message and replaces all instances of it with the replacer. This is a slightly laggy operation if done extremely rapidly, like 60 times per second.

    Chat message from event

    This is how you get the unformatted message from a chat event

    function onChatReceived(event) {
      var unformattedMessage = ChatLib.getChatMessage(event);

    This is how you get the formatted message from a chat event

    function onChatReceived(event) {
      var formattedMessage = ChatLib.getChatMessage(event, true);

    Formatted chat

    To get the unformatted chat from a chat event passed into a function by a Chat Trigger, pass it to the ChatLib.getChatMessage(event) method, which returns an unformatted string.

    Unformatted chat

    However, if you want the formatted version of the chat message, append the true flag to the ChatLib.getChatMessage(event, formatted) method.


    Rendering is where imports can draw most anything on to the game screen. All 2D rendering involves calling methods in the Renderer object. 3D rendering involves calling methods in the Tessellator object.

    Setting up

    Function to be ran everytime the game overlay is rendered

    register("renderOverlay", "myRenderOverlay");
    function myRenderOverlay() {

    Rendering has to be done every frame of the game, otherwise it will only be on the screen for one frame. The RenderOverlay Trigger is called every frame of the game, so it is required for rendering. All of the actual rendering code will go inside this function, although it could be separated into separate ones.

    Setting priority

    It is possible to set a certain trigger's priority like so:

    register("renderOverlay", "myRenderOverlayLast").setPriority(Priority.LOWEST);
    register("renderOverlay", "myRenderOverlayFirst").setPriority(Priority.HIGHEST);
    function myRenderOverlayLast() {
    function myRenderOverlayFirst() {

    Here, were are dealing with the priority of triggers. Priorities are LOWEST, LOW, NORMAL, HIGH, HIGHEST. Triggers with a priority of HIGHEST are ran first, because they have first say on an event. Triggers with a priority of LOWEST then, are ran last. The function lan rast will draw on TOP of anything before it.

    Simple text rendering

    You can render text onto the screen with this code:

    register("renderOverlay", "myRenderOverlay");
    function myRenderOverlay() {
      Renderer.drawString("Hello World!", 10, 10);

    Every frame, the code inside myRenderOverlay is called. Inside of this function, we make one call to Renderer.drawString(text, screenX, screenY). We make the text say "Hello World!", and place it on the screen at 10, 10 (the top left corner).

    More complex text rendering

    This is how you would draw the same string (but colored) with an object

    register("renderOverlay", "myRenderOverlay");
    var myTextObject = Renderer.text("Hello World!", 10, 10).setColor(Renderer.RED);
    function myRenderOverlay() {

    Here, instead of simply making a method call, we are instatiating an object to do our drawing. This allows for much greater customization, such as rotation, scaling, and as described below, coloring.

    The other interesting part to take a look at is the call to setColor, which will, as you can guess, set the color of the text. For the color, we use a preset color in Renderer. We could have also made a call to Renderer.color(red, green, blue, alpha), and subsequently passed that in to the method. In this example, that call would be Renderer.color(255, 255, 255, 255). Values should range from 0-255.

    Rendering of shapes

    This example renders a rectangle, circle, and triangle

    register("renderOverlay", "myRenderOverlay");
    function myRenderOverlay() {
      var white = Renderer.WHITE;
      Renderer.drawRectangle(white, 10, 10, 50, 50);
      Renderer.drawShape(white, 360, 100, 100, 25);
      Renderer.drawPolygon(white, [300, 300], [400, 400], [200, 400]);

    In our rendering function we are now drawing a bunch of shapes with a bunch of different methods. The first line is simply a variable keeping the color white so we don't have to repeat ourselves so much.

    Rendering rectangles

    The first actual rendering line is the call to Renderer.drawRectangle(color, screenX, screenY, width, height);. In this example, its a simple 50x50 square, starting at (10,10) on the player's screen.

    Rendering perfect shapes

    The second line that does rendering calls the Renderer.drawShape(color, segments, screenX, screenY, radius); method. This one draws a perfect shape with that number of segments. 3 would draw a perfect triangle, 5 a pentagon. This could be used instead of the next line to draw a triangle, or the line before for a square. For this example, it draws a circle.

    Rendering polygons

    The last line makes use of the Renderer.drawPolygon(color, [x, y]...); method. It can take as many arrays with x,y coordinates as you pass it to add more and more points. This example is used to make a triangle.

    Rendering images

    This example renders the images on the screen

    register("renderOverlay", "myRenderImageOverlay");
    Renderer.downloadImage("", "ctjs-logo.png");
    function myRenderImageOverlay() {
        Renderer.drawImage("ctjs-logo.png", 10, 10, 0, 0, 256, 256, .5);
        Renderer.drawItemIcon(250, 250, "minecraft:apple");

    As before, we register for a render overlay trigger so we can do our rendering in it. However, this time, we also make a call to Renderer.downloadImage(url, resourceName) in the initialization of our script. This downloads the image from the provided link and makes it available for rendering.

    Rendering custom images

    The first thing we do in the render function is call Renderer.drawImage(resourceName, screenX, screenY, textureMapX, textureMapY, textureWidth, textureHeight, scale) to render the image with 1/2 of its normal size.

    The resource name has to be the same as what you pass in when you download the image. For the most part, textures will start at 0,0 and be 256x256 in size.

    Rendering minecraft images

    The last thing we do in the render function is call Renderer.drawItemIcon(screenX, screenY, itemName). Here we pass the x and y of where on the screen we want the item image to be rendered, and the name of the item, such as minecraft:apple.

    Advanced rendering

    Here we are rendering text that is a rainbow color

    register("renderOverlay", "myRenderOverlay");
    var exampleImportStep = 0;
    function myRenderOverlay() {
      Renderer.drawString("Rainbows!", 10, 10, Renderer.getRainbow(exampleImportStep));

    This topic covers advanced rendering, like rainbow colors and dynamic positioning.

    Rainbow colors

    Again, we setup the default rendering scheme of a RenderOverlay trigger and its corresponding function. However, this time we also create a "exampleImportStep" variable that starts of at 0. Then, every time we render to the screen, we increment this step variable by 1.

    This variable is used when it is passed into the Renderer.getRainbow(step) method, which produces rotating colors, which we then use as the color for the drawString method.

    Dynamic positioning

    This example showcases how to make render positioning dynamic

    register("renderOverlay", "myRenderOverlay");
    function myRenderOverlay() {
      var renderWidth = Renderer.getRenderWidth();
      var white = Renderer.WHITE;
      var textToRender = "Rainbows!";
      Renderer.drawString(textToRender, (renderWidth / 2) - (Renderer.getStringWidth(textToRender) / 2), 100, white);
      var rectWidth = 50;
      Renderer.drawRectangle(white, (renderWidth / 2) - (rectWidth / 2), 200, rectWidth, 50);

    Here we are making all of our rendered objects be perfectly aligned horizontally on the screen for all windows sizes. We start off by getting the height of the current window, with the call to Renderer.getRenderWidth().

    Then, for eachpart we render, we get half the width of the window, and then subtract half the width of our rendered object. For a string this is done with (renderWidth / 2) - (Renderer.getStringWidth(textToRender) / 2). For a fixed width object, you can replace Renderer.getStringWidth(textToRender) with the width of the object.

    Step triggers

    This example shows how to create a step trigger

    register("renderStep", "myStep");
    function myStep() {


    ct.js provides several objects to expand the functionality of your imports without you needing to delve into base Minecraft code. A list is found below.

    Object Description
    Book Makes an openable book in Minecraft
    Display Renders text on to the game screen
    Gui Makes an openable gui in Minecraft
    KeyBind Used for detecting a key's state
    LookingAt Contains information about what the player is looking at
    Inventory Contains information about the player's inventory
    XMLHttpRequest Used for making an HTTP request
    Thread This is a pseudo object, used to do tasks that take a long time
    CPS Contains information about the player's clicks per second
    ParticleEffect Allows creation of custom particle effects to be displayed client side


    Books objects are used for displaying base Minecraft book GUI's with customizable text.


    This is how you create a book

    var book = new Book("Example Book");

    We create our book with the Book constructor of new Book(bookName);. We want to create our book in the global scope, as explained below.

    Adding content

    This is how you add pages to the book

    var book = new Book("Example Book");
    book.addPage("This is a very simple page with just text.");
    book.addPage(new Message("This is a page with a ", ChatLib.hover("twist!", "Hi! I'm hover text :o")));

    To add content to our book, we'll want to utilize the .addPage(message) method. This can take either a simple string as the message for the page, or a Message object if you want to utilize the functionality the provide, covered here. This should be done right after the instantiation of the book.

    Updating content

    This is how to update a page's content

    book.setPage(1, new Message("lul!"));

    To set a page, we use the .setPage(pageNumber, message). Page number is the number of the page you wish to update, 0 based. The message has to be a Message object, there is no method for just a string.

    This can be done anytime, just re-display the book to see the updated version. The page you try to set must already exist, or else there will be errors. Just add the page if you need to add a new page afterwards.


    This is how to display the book to the user


    This is how to display the book starting on a certain page


    This is a very simple operation which just opens the book. You can also specify a page number to open the book to as the first argument, it defaults to 0. If the page you specify doesn't exist, the player will have to click one of the arrows to go to the next available page.


    Displays are used for rendering simple text on to the players screen. If you would like to utilize other rendering functions found in the rendering section, use custom rendering functions.


    This is how you can create a Display object

    var display = new Display();

    This display object is now created, but it doesn't do much of anything yet.

    Adding content

    This is how you add lines to a display

    var display = new Display();
    display.addLine("Ay! First line.");
    display.addLines("2nd line", "3rd line");

    Displays consist of lines of text. These lines can be added and set, and they can use color codes. The first call to .addLine(message) adds a line to the display with the text passed in. The second call to .addLines(messages...) adds as many lines as you pass into it, in our case just 2. The final call to .addLines(number) adds as many lines as you pass in, this is used for setting lines later that you don't want to say anything yet.

    Setting content

    This is how you set a line in a display

    display.setLine(3, "Now this line has text :)");

    In this example the call to .setLine(lineNumber, message) sets the 4th line in the display (0 based) which was previously blank to our example text. This is what we would use if we want to update a display with information, like the player's current coordinates.

    Setting positioning

    This is how you set the alignment of a display


    This aligns your display on the left side of the screen. Other options are CENTER and RIGHT.

    This is how you set the order of the lines


    This renders the lines from 0 going downwards, usually what you'd want. Other options are UP.

    This is how you set the exact position of the display

    display.setRenderLoc(10, 10);

    This sets the X and Y coordinate of where your display should start, with the first argument being X, and the second Y.

    Setting background and foreground options

    This sets the background color of the display


    This makes the background color of the display orange. Other options are all the colors in RenderLib, or a custom color with RenderLib.color(r, g, b, a).

    This sets the type of background for the display


    This option sets how the background color should be displayed. PER_LINE says that the background should be the width of each line. NONE would mean don't show background color, and FULL would indicate make the background color draw in a box around the entire display.

    This sets the foreground (text) color of the display


    All text in the display will now show blue. This method can take any RenderLib color, including custom ones described above.


    Guis are screens that are opened in game, such as the chat gui, or the escape menu. These stop the player from moving.


    This is how you create a gui

    var gui = new Gui();

    Like other objects, creating a Gui is very simple.

    Rendering the gui

    This is how you set up a function to render the gui

    var gui = new Gui();
    function myGuiRenderFunction(mouseX, mouseY, partialTicks) {
      RenderLib.drawRectangle(RenderLib.WHITE, mouseX, mouseY, 50, 50);

    Everything inside of the "myGuiRenderFunction" will be ran while the gui is open. Inside of this function you should make use of the RenderLib functions to draw what you want on to the screen. The three arguments passed in are the x coordinate of the user's mouse, the y coordinate of the users mouse, and the partial ticks.

    In this example, we render a 50x50 square with the top left corner being the user's mouse position.

    Adding interactivity

    This is how you detect when a user presses a key

    var gui = new Gui();
    function myGuiKeyTypedFunction(typedChar, keyCode) {"You typed " + typedChar);

    This is how you detect when the user clicks

    var gui = new Gui();
    var renderSquareX = 0;
    var renderSquareY = 0;
    function myGuiRenderFunction(mouseX, mouseY, partialTicks) {
      RenderLib.drawRectangle(RenderLib.WHITE, renderSquareX, renderSquareY, 50, 50);
    function myGuiClickedFunction(mouseX, mouseY, button) {
      renderSquareX = mouseX;
      renderSquareY = mouseY;

    In the first example we register our key typed function to be activated when someone types a key in our Gui. The keyCode passed can be compared with the Keyboard class keys.

    In the next example we make things more complicated. We register both a draw function and a mouse clicked function. We render the same box as in the previous draw example, however, we make the coordinates of it be the last place the mouse was clicked.

    Displaying the gui

    To display the gui, use this;

    To close the gui, use this


    These very simple methods open and close the gui, and neither take any arguments.


    KeyBinds are used for detecting the state of a key.


    This is the preferred method to get a keybind

    var wKeyBind = getKeyBindFromKey(Keyboard.KEY_W, "My W Key");
    function getKeyBindFromKey(key, description) {
      var mcKeyBind = MinecraftVars.getKeyBindFromKey(key);
      if (mcKeyBind == null || mcKeyBind == undefined) {
          mcKeyBind = new KeyBind(description, key);
      return mcKeyBind;

    Let's break this down. First, we call the function "getKeyBindFromKey" and save the result in a variable. This result is our finished KeyBind. We pass into this function a keyCode, from the Keyboard class.

    Next, we have our function. First, it tries to get the Keybind for our specified key from MinecraftVars. We do this because if we want a keybind Minecraft already uses, we don't want to override it. However, if Minecraft isn't using that key (because the function returned null), we need to make our own, with the description and key we specified.

    In our case, this will return the keybind already used by minecraft for the run key (unless of course you changed yours to a different key).

    Using the keybind

    To check if they key bind is being held, do this

    if (wKeyBind.isKeyDown()) {"Key is down!");

    To check if the key bind was pressed, use this

    if (wKeyBind.isPressed()) {"Key is pressed!");

    This first example would spam your chat if it was in an Tick trigger or something of the like, as it will always be true if you are holding down the key.

    Now, in the second example, we would only get the chat message once every time we press and hold the key. It only returns true one time per key press. If you let go and press again, it will return true once more.


    The LookingAt object contains many methods used for retrieving information about what the player is looking at.


    You can determine the LookingAt type by calling getType()

    if (LookingAt.getType() === "entity") {
      // The player is looking at an entity
    } else if (LookingAt.getType() === "block") {
      // The player is looking at a block
    } else {
      // The player isn't looking at anything

    There are two types of things that the player can be looking at: entities and blocks. There are some methods that apply to both of these types, but most methods apply to either one or the other. If a method applies to only one type, it will have that type in the name (eg: LookingAt.getEntityDisplayName()).


    Below is a list of all of the methods available to both types in the LookingAt object:

    Method Name Description Example return value
    getType() The type of thing the player is looking at "block" or "entity"
    getName() The name of the block or entity "Villager", "Diamond Block"
    getDistanceFromPlayer() The distance of the block or entity from the player 3.1882948
    getPosX() The X coordinate of the block or entity 30 (block), 30.18472 (entity)
    getPosY() The Y coordinate of the block or entity 30 (block), 30.18472 (entity)
    getPosZ() The Z coordinate of the block or entity 30 (block), 30.18472 (entity)

    The block-specific methods:

    Method Name Description Example return value
    getBlockMetadata() The block's metadata 4
    getBlockUnlocalizedName() The block's unlocalized name "sandStone", "blockDiamond"
    getBlockRegistryName() The block's registry name "sandstone", "diamond_block"
    getBlockId() The block's Minecraft id 24, 57
    getBlockLightLevel() The light level of the particular block face the player is looking at 0, 15
    isBlockOnFire() Whether or not the block is on fire true, false

    And finally, the entity-specific methods:

    Examples of how to use getEntityNBTData()

    // Returns true if the wolf the user is looking at is angry, otherwise returns false
    function isWolfAngry() {
      var NBTData = JSON.parse(LookingAt.getEntityNBTData());
      if (LookingAt.getName() === "Wolf") {
        return NBTData.Angry;
      } else {
        return false;

    Function to display all the JSON keys of an entity's NBT data

    function getNBTDataKeys() {
      var NBTData = JSON.parse(LookingAt.getEntityNBTData());;
    Method Name Description Example return value
    getEntityDisplayName() The entity's display name "kerbybit", null (for unnamed entities)
    getEntityMotionX() The entity's motion in the X direction 1.2049175
    getEntityMotionY() The entity's motion in the Y direction 1.2049175
    getEntityMotionZ() The entity's motion in the Z direction 1.2049175
    getEntityTeamName() The entity's team name "Blue team"
    getEntityNBTData() A JSON string of the entity's nbt data See example for details
    isEntityHuman() Whether or not the entity is human true, false


    The Inventory object contains methods used for getting information about the user's inventory


    The InventorySlot object is a subset of the Inventory object. An InventorySlot, as the name would suggest, is a common slot in the player inventory. For example, InventorySlot.helmet refers to the player's helmet.

    The valid InventorySlots are as follows: hotbar1, hotbar2, ..., hotbar9; helmet, chestplate, leggings, boots


    As an example, lets create a function to display information about the user's held item

    function displayHeldItemInfo() {
        var item = Inventory.getHeldItem();
        if (!item.isEmpty()) {
            var durabilityPercentage = Math.ceil(item.getDurability() / item.getMaxDurability() * 100);
            // If NaN, that means it's a block
            if (isNaN(durabilityPercentage)) durabilityPercentage = "N/A (not a tool!)"
  "Item: " + item.getDisplayName());
  "Durability: " + durabilityPercentage + "%");
  "Stack Size: " + item.getStackSize());
        } else {
  "&4You aren't holding anything!")

    All of the Inventory methods are shows below. Currently there is only one, but there may be more added in the future.

    Method Name Description Example return value
    getHeldItem() The player's currently held item InventorySlot.hotbar3

    All of the InventorySlots share the same methods, which are listed below.

    Method Name Description Example return value
    isEmpty() Whether or not that inventory slot is empty true, false
    isBlock() Whether or not that inventory slot contains a block, as opposed to, say, a tool true, false
    getDisplayName() The item's display name "Oak Fence", "Flint and Steel"
    getRegistryName() The item's registry name "fence", "flint_and_steel"
    getMaxDurability() The item's max durability 364, null (for blocks)
    getDurability() The item's current durability 115, null (for blocks)
    getStackSize() The item's stack size 1, 64
    getMetadata() The item's metadata 7


    XMLHttpRequests are used to send HTTP requests. This can be used for things like making API calls.


    This is how you can create the request object

    var request = new XMLHttpRequest();

    This creates the request object from which will will make the HTTP connection.

    Opening a connection

    This is how you can open a GET request

    var request = new XMLHttpRequest();"GET", "", true);

    This first example opens the GET request to a url (this is just a simple testing website) with the .open(method, url, async) method. The last flag is whether or not we want the request to be done asynchronously.

    This is how you can open a POST request

    var request = new XMLHttpRequest();"POST", "", true);

    The second example showcases how to open a POST request. All arguments are the same, .open(method, url, async).

    Setting the callback

    This is how you set the callback for the request

    var request = new XMLHttpRequest();"GET", "", true);
    function requestCompleted(request) {

    The function we set as the callback method will be called when the request has finished. Currently, it will never be called, because we haven't sent the request yet. The callback method should take one parameter, which will be the XHR request object, because it is what you get the response data from.

    Sending the request

    This is how you actually send the GET request

    var request = new XMLHttpRequest();"GET", "", true);
    function requestCompleted(request) {
      print("Finished GETting!");

    This sends the asynchronous GET request with one request data, that being foo=bar. This prints "Finished!" to the console when completed.

    This is how you actually send the POST request

    var request = new XMLHttpRequest();"POST", "", true);
    request.send("foo", "bar");
    function requestCompleted(request) {
      print("Finished POSTing!");

    This sends the asynchronous POST request with one bit of post data, again being foo=bar. The send method takes as many strings as you pass in, and every other is the key, and the one following be the value.

    Receiving the request

    This is how you can receive the response data

    var request = new XMLHttpRequest();"GET", "", true);
    function requestCompleted(request) {

    The request object passed into the function is the same XMLHttpRequest you created, opened, and sent. It has three fields, status, statusText, and responseText which are set when the request completes. Status is used for the response code for the request, i.e. 200 for OK, 404 for not found, etc.

    Extra data

    This is how you can store extra data in your request for use in the callback

    var request = new XMLHttpRequest();"GET", "", true);
    request.extras.put("myMessage", "seekrits");
    function requestCompleted(request) {

    Here we are utilizing the "extras" map that is a part of the XHR object. When we are setting up our request, we put a key value pair in the extras map. The key in this case is "myMessage", and the value could be anything at all, we are just using a string.

    When we get the request passed back to the callback function, we print out the message we stored. This prints seekrits, just like it should. This is an easy way to tunnel information from the request sending to completion without needing global variables.

    Custom headers

    This example sets the Max-Forwards header

    var request = new XMLHttpRequest();"GET", "", true);
    request.addRequestHeader("Max-Forwards", "5");

    Here we are attaching our own header to the HTTP request, in this case it is Max-Forwards. The method used is .addRequestHeader(header, value), both arguments being strings.


    This is a list of all the Triggers currently available:

    Trigger Description Cancelable
    Chat Fires when a chat event is received yes
    RenderOverlay Fires when the game's overlay is rendered, tied to the game's FPS no
    SoundPlay Fired when a sound is played no
    Step Fired a certain amount of times per second, no matter the FPS no
    Tick Fired every time the Minecraft game loop is ran no
    WorldLoad Fired when the game loads a world no
    WorldUnload Fired when the game unloads a world no
    Clicked Fires when a certain position is clicked no
    Command Fires when a specified command is run by the player no
    Dragged Fires as a specified mouse button is being held down no
    GuiOpened Fires when a gui is opened yes
    RenderAir Fires when the player's air level is rendered (i.e. while the player is underwater) yes
    RenderBossHealth Fires when a boss health bar is being rendered yes
    RenderCrosshair Fires as the crosshair is drawn yes
    RenderDebug Fires when the debug screen (F3) is being drawn yes
    RenderExperience Fires when the player's experience bar is being drawn yes
    RenderFood Fires when the player's food (hunger) is being drawn yes
    RenderHealth Fires when the player's health is being drawn yes
    RenderHotbar Fires when the player's hotbar is being drawn yes
    RenderMountHealth Fires when the mount's health (horse or pig) is being drawn yes
    RenderPlayerList Fires when the player list (tab list) is being drawn yes
    SoundPlay Fires when a specified sound is played yes

    Advanced registering

    This is how you unregister a trigger

    var myTrigger = TriggerRegister.registerChat("myMethod");
    function myMethod() {

    This is how you re-register a trigger

    var myTrigger = TriggerRegister.registerChat("myMethod");
    function myMethod() {

    This is how you check if a trigger is registered

    var myTrigger = TriggerRegister.registerChat("myMethod");
    if (myTrigger.isRegistered()) {

    In this first example, the "myMethod" function will only be ran once, because it is unregistered in the function.

    In the second example, we simply re-register the trigger, this can be done at anytime.

    In the last example, we are only running a block of code if the trigger is actually registered.

    General triggers

    How to set the priority of any trigger


    These examples apply to all triggers, not just the examples given.

    Setting priority

    This sets the order in which triggers of the same type are ran. Available priorities are LOWEST, LOW, NORMAL, HIGH, and HIGHEST. Triggers with a priority of LOWEST are ran first, then LOW, all the way until HIGHEST.

    Chat triggers

    A chat trigger is a trigger that responds to chat messages. You have plenty of options to customize on which specific message, or types of messages, you wish to respond to. You can cancel this event, so you can customize chat very heavily.


    This is how you create a chat trigger

    function myChatMethod() {

    This is how you create the simplest possibly chat trigger that activates on all chat messages.

    These are all of the available settings for chat triggers

    var myChatTrigger = TriggerRegister.registerChat("myChatMethod");
    myChatTrigger.setChatCriteria("<${*}> ${message}");

    Set chat criteria

    Setting the chat criteria sets what chat messages this trigger will receive. In our case, it only fires for chat messages that have something inside of <>'s, and then something afterward.

    The ${} we created are variables, thatmeans they will match anything, but have to match the parts around them too If the variable has a name inside the block, it will be passed to your callback function. However, if it is just a star, it won't be.

    Set criteria parameter

    The "parameter" is a special flag for the type of check that should be done on the criteria. By default, this is if the chat message is the same as what the message was (including variables).

    The other options are "<s>" for if the message starts with your criteria and then can have anything else afterwards. "<c>" is for if the message contains your criteria, and finally, "<e>" checks if your criteria comes at the very end of the chat message.

    Sound play triggers