Final Fantasy XIV Scripts

Table of Contents

Introduction

Scripts can be used to automate a wide variety of tasks, such as your combat rotation, gathering rotation, crafting rotation, and much more. They are essentially advanced macros, although they can be activated without pressing keys as well.

Script GUI

To get started, click on the Scripts button on the main GUI. Here, you will see all the scripts you have created. The “File name” field is the file from which Speeder will load your scripts. In general, you do not need to use “Load” unless you change the file name. “New” allows you to create a new script. Double left clicking on existing scripts will allow you to edit them. Double right clicking on existing scripts will delete them. Clicking “Save” will save the scripts to the specified file.

The Read Packet Data checkbox is not necessary for most commands but allows Speeder to read incoming packet data, which is useful for discerning overhead marks, types of fish, and more.

For now, let’s create a new script. Click the “New” button. “Script VK Code” is the virtual key code of the key you want to activate the script. Virtual key codes can be found here: https://cherrytree.at/misc/vk.htm. You want to use the decimal number. If you would like to use modifier keys, you can click the checkbox next to the modifier key(s) you want. For example, if I want my script to activate via Left Shift + 1, I would write 49 into “Script VK Code” (49 is the virtual key code for the “1” key) and click the LSHIFT checkbox. If I want the script to run without even having to press a key, I would click the “Run on Startup” checkbox.

"Function Name" is used to create a series of commands that can be called by a macro or even another function. We will not deal with functions right now, but check out the [Functions] section of the guide if you are interested because they are quite useful. Leave it blank for now.

The radio button “Repeat” will cause the script to repeat while the script key is held down. The radio button “Toggle” will cause the script to repeat until the script key is pressed again. “Neither” is the default and will cause the script to end after a single iteration.

The “interruptible” checkbox allows the script to be interrupted in the middle of operation. Please keep in mind that if you are holding keys down, they may get stuck if you allow the script to be interrupted. One fix for this is to use “End Commands” to release the keys.

The “Passthrough” checkbox allows for the script key to activate as it normally would.

“End Commands” can be a single line of commands that should activate when the script ends.

“Comment” is for your own benefit to remember what the script does.

The giant “Commands” field is where the magic happens and where you program your script. All available commands can be found below. Each line can contain a set of commands that activate in left-to-right order. Each command should be separated with the “|” character. If any command returns false, the rest of the commands for that line will not activate, and Speeder will move to the next line. Lines will be traversed in top-to-bottom order, and every line will activate unless the “gt” (goto) command is used. To better illustrate how this works, paste the following text into “Commands”:

  • store % var1,true
    eq % var1,true|dbg % var1 is true!
    eq % var1,false|dbg % var1 is false!

Click the “Test” button, and you will see “var1 is true” show in Speeder’s log. Now change “store % var1,true” to “store % var1,false” and click “Test” again. You will now see “var1 is false” in Speeder’s log.

  • Note that it is possible to test commands using the “Command” button the main GUI as well.

Now that we’ve gone over the logic of script commands, the next thing to do is understand what the commands are . . .

Script Commands

FFXIV script commands can be categorized into two types: “do/check” types and “get” types. The first will be discussed below and refers to commands that either perform an action or check whether something is true/false. In most situations, you will use “get” commands first to retrieve the data you need and then “do/check” commands second. In some situations, you will not need to use “get” commands at all. Please note that all key commands use the virtual key code of the key. For example, to hold the “1” key down on the keyboard, I would use 49d. Virtual key codes can be found here: https://cherrytree.at/misc/vk.htm

  • “d” — The key will be held down and will not be released, such as 49d for the “1” key on the keyboard.
  • “u” — The key will be released, such as 49u to release the “1” key.
  • “[#]” — The key will be pressed and released, such as 49 for the “1” key. Example:
    • 49|s1000|49|dbg % pressing the 1 key twice with one second delay
  • “s” — Speeder will wait for the specified number of milliseconds. (s2000 = wait 2000 milliseconds).
  • “rs[min],[max]” — Speeder will wait for a random time (in milliseconds) between [min] and [max]. For example, rs1000,10000 would wait for a random time between 1000 milliseconds and 10000.
  • “m” — The mouse cursor will be moved to this location in x,y. For example, if I wanted to move my cursor to the top left of my screen, I would use m0,0. Make use of the get % mouse command to retrieve your cursor’s position.
  • “kd[key]” — If “key” is currently pressed, the rest of the command line will process. The inverse is possible with “!kd.” As always, “key” should be the virtual key code of the key. This command may be preferable to creating a multi-key macro.
  • “gp[x],[y],[color],[precision] — If the pixel color on your screen at x,y matches “color,” the rest of the command line will process. The inverse is possible by using “!gp”. Use the get % pixel command to retrieve pixel colors. “Precision” is how close you want the current pixel color to be to “color.” All colors can be broken into RBG combinations with each color (i.e., red, blue, or green) having a possible value between 0 and 255. What “precision” does is compare the absolute value of the individual colors. For example, if I have a precision of 10 and am checking for a color with a red value of 40, the current red color must be between 30 and 50. The same logic is applied to green and blue. A precision of 0 means the color must match exactly.
  • “abl[ability_id],[target_id]” — The ability with ID “ability_id” will be used and/or queued on the target with ID “target_id.” If “target_id” is omitted, Speeder will assume you want to use the ability on your current target. If “target_id” is set to 0 or any invalid number, the ability will be used on your character. Example:
    • get % ogcd 936|eq % OGCD936,0|abl7517|dbg % using fleche because it is off-cooldown
  • “mp[percent]” — If your current MP percentage is less than or equal to “percent,” the rest of the commands will process. 0.5 is equal to 50%, 0.6 is 60%, and so on. The inverse is possible with “!mp.” Example:
    • mp0.75|abl7562,0|dbg % using lucid dreaming
  • “mp*[value]” — If your current MP is less than or equal to “value,” the rest of the commands will process. The inverse is possible with “!mp*.”
  • “hp[percent]” — If your current HP percentage is less than or equal to “percent,” the rest of the commands will process. 0.5 is equal to 50%, 0.6 is 60%, and so on. The inverse is possible with “!hp.” Example:
    • hp0.75|abl7541,0|dbg % using second wind
  • "cp[percent]" — If your current CP percentage is less than or equal to “percent,” the rest of the commands will process. 0.5 is equal to 50%, 0.6 is 60%, and so on. The inverse is possible with “!cp.”
  • "cp*[value]" — If your current CP is less than or equal to “value,” the rest of the commands will process. The inverse is possible with “!cp*.”
  • "gp[percent]" — If your current GP percentage is less than or equal to “percent,” the rest of the commands will process. 0.5 is equal to 50%, 0.6 is 60%, and so on. The inverse is possible with “!gp.”
  • "gp*[value]" — If your current GP is less than or equal to “value,” the rest of the commands will process. The inverse is possible with “!gp*.”
  • “ch[hotbar],[slot]” — If the hotbar slot on hotbar “hotbar” and slot “slot” is currently active (i.e., ready to be used), the rest of the commands will process. The inverse is possible with “!ch.” Example:
    • ch2,5|dbg % the ability on hotbar 2 and at slot 5 is ready!
  • “ch*[hotbar],[slot]” — Similar to “ch” above but checks for procs rather than if the slot is ready to be used. The inverse is possible with “!ch*.” Example:
    • ch*2,1|abl7510|dbg % using verfire because it is assigned to hotbar 2 slot 1 and is proc’d
  • “chid[hotbar],[slot],[ability_id]” — If the ability with the ID “ability_id” is assigned to the hotbar slot at “hotbar” and “slot,” the rest of the command line will process. The inverse is possible with “!chid.” Example:
    • chid2,1,7510|dbg % verfire is assigned to hotbar 2 slot 1
  • "ms[speed],[mode]" — Your movement speed will be set to "speed," and the Movement Speed Hack Mode will be set to "mode."
  • "freemove[+]" — The "Allow All Movement" hack will be toggled on or off. To toggle it on, use freemove+. To toggle it off, use freemove- or just freemove. The "Allow All Movement" hack allows you to move during DRG jumps, gap closers, rescue, and many animations that normally freeze you in place.
  • “caw” — If FFXIV is the active window, the rest of the command line will process. The inverse is possible with “!caw.”
  • “wmark[x],[y],[z],[type]” — The “type” of waymark (1,2,3,4,5,6,7,8) will be placed at x,y,z. Please note “type” must be numerical with “5” equal to “a,” “6” to “b,” “7” to “c,” and “8” to “d.” Example:
    • get % wmark 1|wmark0,100,0,1|dbg % waymark 1 moved to middle of arena|s3000|wmark(VAR % WMARK1X),(VAR % WMARK1Y),(VAR % WMARK1Z),1|dbg % waymark 1 moved back to original position
  • “se[target],[status_id],[duration],[applier]” — If “target” currently has a status effect with the ID of “status_id,” and the remaining duration is greater than “duration,” and the mob/player who applied the status effect is “applier,” the rest of the command line will process. “Duration” and “applier” are optional. “Target” can be 0 for your own character, 1 for your current target, or the ID of any mob/player. The same is true for the “applier.” The inverse is possible with “!se” and allows you to check for the absence of a status effect. Example:
    • !se1,2041,2,0|abl16554|dbg % using combust because duration is less than 2 or it isn’t applied on current target.
  • "se+[status_id]" — Applies the status effect with the ID "status_id" to your character. Pretty much all status effects are server checked, although there were some cool exploits in the past, such as being able to change AST cards to whatever you wanted.
  • "se-[status_id]" — Removes the status effect with the ID "status_id" from your character. This can be useful for abilities that hinder your movement.
  • "thp[percent]" — If target's HP percent is less than or equal to "percent," the rest of the command line will process. The inverse is possible with "!thp." "Percent" should be written as a decimal between 0 and 1.0 with 0.5 equal to 50%. Example:
    • !thp0|dbg % my target is alive!
  • "it" — If you are currently targeting something, the rest of the command line will process. The inverse is possible with "!it."
  • "gcd[gcd reduction]" — Reduces your GCD by "gcd reduction." "gcd reduction" is the amount of milliseconds you would like to remove from your GCD. If "gcd reduction" is 0, the GCD hack will be disabled. This can be useful for some weapon skills that have a lower GCD than normal by disabling the GCD hack when these weapon skills are used (to prevent server resets). Example:
    • Commands: gcd0|dbg % disabling gcd hack
    • End Commands: s2000|gcd20|dbg % reenabling gcd hack after 2 seconds
  • "fish[size]" — If a fish is currently on the line, the rest of the command line will process. If "size" is specified, the fish's size must also match. Sizes can be discerned via the "get % fish" command. The Read Packet Data checkbox must be checked for this command to work. Example:
    • fish36|dbg % small fish!
      fish37|dbg % medium fish!
      fish38|dbg % big fish!
  • “gt[#]” — Moves to the command line matching #. For example, if you used “gt1,” Speeder would restart from the first line in the current script.
  • “to” — The script will be toggled off.
  • “macro % [text]” — An in-game macro will be activated as if you had clicked on a macro containing “text.” Example:
    • macro % /echo hello!
  • “st % [timername],[delay]” — A timer will be created with a value of current time + delay. Delay should be in milliseconds, so if you want to create a two-second timer, you would use st % twosecondtimer,2000. This command is meant to be used in conjunction with the “ct %” command below.
  • “ct % [timername]” — If the timer “timername” has expired, the rest of the commands on this line will process. If the timer has not expired, the rest of the commands on this line will NOT process.
  • “var % [variable name]” — The commands stored in “variable name” will activate. For example, let’s say we have two scripts, one that auto-loads and sets our variables to their initial default values, and one that executes a script when F2 is pressed. The first script might look like
    store % cmdvar,1’|s1000’|1
    and the second script, activated by F2, might look like
    var % cmdvar
    Pressing F2 will left click twice with a 1000 millisecond delay between clicks because those are the commands stored in the variable “cmdvar.”
  • “(VAR % [variable name])” — Everything in the parentheses will be replaced by the value stored in “variable name.” This command can be used anywhere in a command and is extremely versatile. You CAN include multiple variables within variables, such as (VAR % STATUS(VAR % num)ID). This technique is particularly useful for iterating through a list. Simple concept example:
    • store % testvar1,-1
      store % testvar2,0
      cmp(VAR % testvar1),(VAR % testvar2)|dbg % testvar1 is less than testvar2
  • “store % [variable name],[value]” — “value” will be placed into the variable “variable name.” If you are placing commands into “variable name,” you must escape the “|” character with a single-quote character: ‘|, such as store % varname,1’|s1000’|1’|s1000
  • eq % [variable name],[value]” — If the variable “variable name” is equal to “value,” the rest of the command line will process. The inverse is possible via “!eq.”
  • “cmp[value1],[value2]” — If “value1” is less than “value2,” the rest of the keys will process. The opposite (i.e., greater than or equal to) is possible with “!cmp.”
  • “str % [variable name],[text]” — If the string “text” is stored anywhere in the variable “variable name,” the rest of the command line will process. This is a way to check for partial text within a string rather than relying on an exact match.
  • “or % [command1]’|[command2]’|etc.” — This is your basic “or” statement, which will check “command1,” “command2,” and so on until one is true. As soon as one of the commands is true, the rest will not be checked. Each “command” should be separated by an escaped version of the normal delimiter: ‘|. Essentially, this allows you to perform multiple checks in a single command line.
  • “add % [variable name],[value]” — “value” will be added to “variable name,” and the result will be stored in “variable name.”
  • “sub % [variable name],[value]” — “value” will be subtracted from “variable name,” and the result will be stored in “variable name.”
  • “mul % [variable name],[value]” — “value” will be multiplied by “variable name,” and the result will be stored in “variable name.”
  • “div % [variable name],[value]” — “variable name” will be divided by “value,” and the result will be stored in “variable name.”
  • "call % [function name]" — All of the commands present in the function "function name" will activate. See the [Functions] section.
  • “dbg % [text]” — Speeder will output “text” to Speeder’s log. Useful for debugging.
  • “time % [variable]” — The current time (in milliseconds) will be placed into “variable.” This is meant to measure the efficiency of your macro/waymark. You can also use it as a timer if you wish.
  • If no commands appear, the key will be pressed a single time (and released).

The second type of command is the “get” type. These commands are all prefaced with “get %” and are used to retrieve data from FFXIV’s memory.

  • “get % player” — The following global variables related to your character will be populated: PLAYERID, PLAYERX, PLAYERY, PLAYERZ, PLAYERD (current direction), PLAYERJOB, PLAYERSPL (current spell/cast ability), PLAYERABL (current ability with or without cast time), and PLAYERANI (current animation).
  • “get % playerse [output]” — The following global variables related to your current status effects will be populated: STATUS[#]ID (the ID of the status effect), STATUS[#]D (the remaining duration of the status effect), STATUS[#]A (the ID of the applier of the status effect), and STATUST (the total number of active status effects), with “#” being a number from 1 to 30 depending on how many status effects are currently active. “Output” can be set to “o” to have all this information displayed in Speeder’s log, such as get % playerse o.
  • “get % target” — The following global variables will be populated: TARGETID, TARGETX, TARGETY, TARGETZ, TARGETSPL (ID of current ability with a cast time), TARGETABL (ID of current ability with or without a cast time), TARGETCAST (current cast time), TARGETAOEX (x coordinate of current AoE attack), TARGETAOEY, TARGETAOEZ, TARGETANI (ID of current animation), TARGETMDL (ID of current model [rarely used to indicate certain abilities, like double buster, single buster, etc. in A6]), TARGETHP (the current percentage of your target's HP with 0.5 being equal to 50%).
    • If you are not currently targeting anything, TARGETID will be set to 0, so you can use that to check for a target.
  • “get % targetse [output]” — The following global variables related to your target’s status effects will be populated: TSTATUS[#]ID (the ID of the status effect), TSTATUS[#]D (the remaining duration of the status effect), TSTATUS[#]A (the ID of the applier of the status effect), and TSTATUST (the total number of active status effects), with “#” being a number from 1 to 30 depending on how many status effects are currently active. “Output” can be set to “o” to have all this information displayed in Speeder’s log, such as get % targetse o.
  • “get % party [output]” — The following variables related to your party members will be populated: PT[#]ID, PT[#]JOB, PT[#]SE[1-30] (the ID of an active status effect), PT[#]SE[1-30]D (the duration of an active status effect), PT[#]SE[1-30]A (the applier of an active status effect), and PT[#]SETOTAL (total number of status effects), where “#” refers to the number of the party member and “1-30” refers to the number of an individual status effect. “Output” can be “o” to have all this data outputted to Speeder’s log.
  • “get % wmark [number] [output]” — Retrieves x,y,z coordinates for specified “number” waymark. Please note the number 5 refers to the A waymark, 6 to B, 7 to C, and 8 to D. “Output” is optional and should be written as “o,” which will write the waymark data to Speeder’s log. If “number” is omitted, data for all waymarks will be retrieved. If “number” is set to the letter “o,” all waymark data will be outputted to Speeder’s log. If “number” is specified, the following global variables will be populated: WMARK[number]X, WMARK[number]Y, WMARK[number]Z, WMARK[number]A (whether the waymark is active or not). If “number” is not specified, the same global variables will be populated, with WMARK1X equaling the x coordinate of waymark 1, WMARK2X equaling the x coordinate of waymark 2, etc. Example:
    • get % wmark 1|wmark0,100,0,1|dbg % waymark 1 moved to middle of arena|s3000|wmark(VAR % WMARK1X),(VAR % WMARK1Y),(VAR % WMARK1Z),1|dbg % waymark 1 moved back to original position
  • “get % _ogcd [output]” — Scans the memory locations for all cooldowns and populates the following variables: OGCD[offset] (if greater than 0, the current value of the cooldown located at “offset”). “Output” is optional and should be written as “o,” which will write all cooldown data to Speeder’s log (good for determining the offset of cooldowns). Please note that the variables will not be updated if the current cooldown value is 0. This saves CPU. To determine if a cooldown is inactive, you can manually set the cooldown variable to a number the cooldown would never be equal to and then use this command. If the value changes, you know the cooldown is active. Example:
    • store % OGCD936,-1.0|get % _ogcd|!eq % OGCD936,-1.0|dbg % cooldown must be active
  • “get % ogcd [offset]” — Retrieves the data for the cooldown located at “offset” and populates the following variables: OGCD[offset] (the current timer value), OGCD[offset+4] (the total recast time), and %OGCD[offset] (how close the cooldown is to being ready, starting at 0 and ending at 0.99). "Offsets" can be found by using the "get % _ogcd o" command above. Example:
    • get % ogcd 936|eq % OGCD936,0|abl7517,0|dbg % using fleche because it is off-cooldown
  • “get % cast” — Populates the following variables: *CAST (total cast time of your current ability/spell), CAST (current cast time of your current ability/spell), and %CAST (how close you are to completing the ability/spell from 0 to 0.99).
  • “get % gcd” — Populates the following variables: *GCD (total GCD timer), GCD (current GCD timer), and %GCD (how close you are to your GCD being ready from 0 to 0.99).
  • “get % jobg” [output] — Populates the following variables: JGCHAR1–JGCHAR8 (single byte values that correspond to the values in your job gauge), JGSHORT1–JGSHORT4 (2-byte values), JGINT1–JGINT2 (4-byte values). Every job gauge works differently, so that’s why this command seems somewhat awkward. In practical use, it is fairly straightforward, and I recommend using the “output” parameter to see what these variables look like for your job. To do this, write the command as get % jobg o. Once you understand how the variables work for your job, you can remove the “o.” Example:
    • get % player|eq % PLAYERJOB,35|get % jobg|eq % JGCHAR1,100|dbg % my white magic is full on RDM!
  • “get % mspd” — Populates the following variable: MOVESPD (your current movement speed).
  • “get % abldel” — Populates the following variable: ABLDEL (the current delay before you can use your next ability).
  • "get % fish [output]" — Populates the following variable: FISH (the size of your current or previous fish). "Output" can be "o" if you would like this data outputted to Speeder's log. The Read Packet Data checkbox must be checked for this command to work.
  • “get % pixel [output]” — The pixel color at your current cursor location will be retrieved, and the following variables will be populated: PCOLOR (pixel color), PMOUSEX (cursor x coordinate), and PMOUSEY (cursor y coordinate). “Output” can be “o” if you would like this data outputted to Speeder’s log.
  • “get % mouse [output]” — Your cursor’s current location will be retrieved, and the following variables will be populated: MOUSEX, MOUSEY. “Output” can be “o” if you would like this data outputted to Speeder’s log.

Functions

If you have ever programmed anything, you will have heard of functions, and Speeder's functions are similar conceptually. If you have never programmed before, functions are a way to make your coding more efficient. Instead of writing the same commands 10 times, you can create a single function with those commands, and then call the function 10 times. In this way, the commands only have to be written a single time.

Functions are created in the same way as macros. The only real difference is that you will type in a "Function Name" and click the "Function" radio button to let Speeder know that you are creating a function instead of a macro.

Most importantly: Every function name must begin with the lowercase letter "f"; when reading your script file, this notifies Speeder that it is reading a function and not a macro.

Let's try creating a simple function. Click on the Scripts button and then New. Type "fTest" in for our function name. Click the "Function" radio button. In the "commands" field, type
dbg % test1
dbg % test2
Now click OK, and then click Save.

On the main GUI, in the field next to the "Command" button, type
call % fTest
and then press the Command button. You will now see "test1" and "test2" appear in Speeder's log. You can now use "call % fTest" in any script to activate any of the commands present in fTest. Of course, you will want your functions to be, well, more functional that just outputting text, but I hope this gives you an idea of how useful they can be when you need to process the same commands more than once or in multiple macros.

Scroll to Top