Stand Lua API Documentation

Table of Contents

§ Helpful Resources

Our goal is to provide a high-performance Lua API with low-level access. We highly encourage you to create abstractions, and we'd be happy to link it here.

§ Runtime Environment

Language

Stand uses a custom Lua fork which allows you to leverage the latest Lua features, additional tokens (+=, -=, *=, /=, //=, %=, and !=), and fast runtime performance.

Sandboxing

Lua scripts in Stand run in a sandboxed environment that will be removed from memory once the script has finished.

This means that for idle background scripts that only register event handlers or menu commands and have no passive tasks to perform, a call to util.keep_running is needed.

§ Native Invoker

Stand allows you to call most natives via its Lua API by providing a native invoker. However, native_invoker is not recommended for direct use and therefore not documented. Instead, you should use the natives lib, available from the repository.

§ Types

Vector3

A v3 instance or a table with x, y & z fields of type number.

Colour

A table with r, g, b & a fields of type number with values between 0.0 and 1.0.

Functions that take this as a parameter also support 4 floats instead of it, which is more performant.

Label

A string or the return value of lang.register.

§ Global Variables

SCRIPT_NAME

A string containing the name of your script (this excludes .lua).

SCRIPT_FILENAME

A string containing the name of your script file.

SCRIPT_RELPATH

A string containing the path to your script file from the Lua Scripts folder.

SCRIPT_MANUAL_START

A bool indicating if your script was started in direct response to a user action.

SCRIPT_SILENT_START

A bool indicating if a silent start of your script is desired.

§ Menu Functions

int menu.my_root()

Returns a reference to the list that your script gets when it is started.

int menu.player_root(int player_id)

Returns a reference to the list that the given player owns.

int menu.ref_by_path(string path, ?int tree_version = nil)

Returns a reference to any command in Stand using a path such as Self>Immortality. Note that the path has to be in English (UK) and using the no-space greater-than separator.

Providing a tree version is optional but highly recommended for future-proofing. You can find this in any tree config file, such as your profile.

int menu.ref_by_rel_path(int base, string path)
int menu.ref_by_command_name(string command_name)
int menu.list(int parent, Label menu_name, table<any, string> command_names = {}, Label help_text = "", ?function on_click = nil, ?function on_back = nil)
int menu.action(int parent, Label menu_name, table<any, string> command_names, Label help_text, function on_click, ?function on_command = nil, ?string syntax = nil, int perm = COMMANDPERM_USERONLY)

perm may be any of:

  • COMMANDPERM_FRIENDLY
  • COMMANDPERM_NEUTRAL
  • COMMANDPERM_SPAWN
  • COMMANDPERM_RUDE
  • COMMANDPERM_AGGRESSIVE
  • COMMANDPERM_TOXIC
  • COMMANDPERM_USERONLY

Your on_click function will be called with click_type and effective_issuer. The click type could be any of:

  • CLICK_MENU
  • CLICK_COMMAND
  • CLICK_HOTKEY
  • CLICK_BULK
  • CLICK_AUTO
  • CLICK_SCRIPTED
  • CLICK_WEB
  • CLICK_WEB_COMMAND
  • CLICK_CHAT_ALL
  • CLICK_CHAT_TEAM

And could match any or neither of these bitflags:

  • CLICK_FLAG_AUTO
  • CLICK_FLAG_CHAT
  • CLICK_FLAG_WEB

Your on_command function will be called with the provided arguments, click_type, and effective_issuer. If on_command is not provided, commands will be redirected to on_click.

int menu.toggle(int parent, Label menu_name, table<any, string> command_names, Label help_text, function on_change, bool default_on = false)

Your on_change function will be called with on and click_type.

int menu.toggle_loop(int parent, Label menu_name, table<any, string> command_names, Label help_text, function on_tick, ?function on_stop = nil)

Your on_tick function will be called every tick that the toggle is checked; you should not call util.yield in this context.

int menu.slider(int parent, Label menu_name, table<any, string> command_names, Label help_text, int min_value, int max_value, int default_value, int step_size, function on_change)
int menu.slider_float(int parent, Label menu_name, table<any, string> command_names, Label help_text, int min_value, int max_value, int default_value, int step_size, function on_change)

Your on_change function will be called with value, prev_value and click_type.

Note that the float variant is practically identical except the last 2 digits are indicated to be numbers after the decimal point.

int menu.click_slider(int parent, Label menu_name, table<any, string> command_names, Label help_text, int min_value, int max_value, int default_value, int step_size, function on_click)
int menu.click_slider_float(int parent, Label menu_name, table<any, string> command_names, Label help_text, int min_value, int max_value, int default_value, int step_size, function on_click)

Your on_click function will be called with value and click_type.

Note that the float variant is practically identical except the last 2 digits are indicated to be numbers after the decimal point.

int menu.list_select(int parent, Label menu_name, table<any, string> command_names, Label help_text, table<int, table<Label, table<any, string>, Label>> options, int default_value, function on_change)

options must be table of tables. The inner tables must contain at least a string (menu_name), and can optionally have command_names and help_text.

Your on_change function will be called with the option's index, the option's menu_name, and previous option's index, and click_type as parameters.

int menu.list_action(int parent, Label menu_name, table<any, string> command_names, Label help_text, table<int, table<Label, table<any, string>, Label>> options, function on_item_click)

options must be table of tables. The inner tables must contain at least a string (menu_name), and can optionally have command_names and help_text.

Your on_item_click function will be called with the option's index, the option's menu_name, and click_type as parameters.

int menu.text_input(int parent, Label menu_name, table<any, string> command_names, Label help_text, function on_change, string default_value = "")

Your on_change function will be called with the string and click type.

int menu.colour(int parent, Label menu_name, table<any, string> command_names, Label help_text, Colour default, bool transparency, function on_change)

Your on_change function will be called with a Colour as parameter.

int menu.colour(int parent, Label menu_name, table<any, string> command_names, Label help_text, number default_r, number default_g, number default_b, number default_a, bool transparency, function on_change)

Your on_change function will be called with a Colour as parameter.

int menu.rainbow(int colour_command)

Creates a rainbow slider for the given colour command. This should be called right after creating the colour command.

int menu.divider(int parent, Label menu_name)
int menu.readonly(int parent, Label menu_name, string value = "")

Pairs well with menu.on_tick_in_viewport and menu.set_value.

int menu.hyperlink(int parent, Label menu_name, string link, Label help_text = "")
int menu.action_slider(int parent, Label menu_name, table<any, string> command_names, Label help_text, table<int, Label> options, function on_click)

Your on_click function will be called with the option's index, the option's value, and click_type as parameters.

int menu.slider_text(int parent, Label menu_name, table<any, string> command_names, Label help_text, table<int, Label> options, function on_click)

Your on_click function will be called with the option's index, the option's value, and click_type as parameters.

void menu.delete(int command)
void menu.focus(int command)
bool menu.is_open()
number, number menu.get_position()

Returns the menu grid origin x & y.

number, number, number, number menu.get_main_view_position_and_size()

Returns x, y, width, & height for the current main view (active list, warning, etc.).

string menu.get_active_list_cursor_text(bool even_when_disabled = false, bool even_when_inappropriate = false)
bool menu.are_tabs_visible()
void menu.show_command_box(string prefill)
void menu.show_command_box_click_based(int click_type, string prefill)
void menu.trigger_commands(string input)
void menu.trigger_command(int command, string arg)
bool menu.command_box_is_open()
number, number, number, number menu.command_box_get_dimensions()

Returns x, y, width, & height.

bool menu.is_in_screenshot_mode()
int menu.on_tick_in_viewport(int command, function callback)
int menu.on_focus(int command, function callback)
int menu.on_blur(int command, function callback)
void menu.remove_handler(int command, int handler_id)
Label menu.get_menu_name(int command)

You might want to use lang.get_string on the return value.

table<int, string> menu.get_command_names(int command)
Label menu.get_help_text(int command)

You might want to use lang.get_string on the return value.

bool menu.get_visible(int command)
int|bool|string menu.get_value(int command)
int menu.get_min_value(int command)
int menu.get_max_value(int command)
int menu.get_step_size(int command)
void menu.set_menu_name(int command, Label menu_name)
void menu.set_command_names(int command, table<any, string> command_names)
void menu.set_help_text(int command, Label help_text)
void menu.set_visible(int command, bool visible)
void menu.set_value(int command, int|bool|string value)
void menu.set_min_value(int command, int min_value)
void menu.set_max_value(int command, int max_value)
void menu.set_step_size(int command, int step_size)
void menu.set_list_action_options(int command, table<int, table<Label, table<any, string>, Label>> options)

Also works for list_select.

void menu.set_action_slider_options(int command, table<int, Label> options)

Also works for slider_text.

void menu.show_warning(int command, int click_type, string message, function proceed_callback, ?function cancel_callback = nil, bool skippable = false)

skippable will not have an effect when "Force Me To Read Warnings" is disabled.

int menu.get_activation_key_hash()

Returns a 32-bit integer derived from the user's activation key. 0 if no activation key.

int menu.get_edition()

Returns a value between 0 and 3 depending on the user's edition.

§ Players Functions

int players.on_join(function callback)

Registers a function to be called when a player joins the session. Your callback will be called with the player id as argument.

Note that although your callback may yield, you should create all player commands in the same tick as you receive the event.

int players.on_leave(function callback)

Registers a function to be called when a player leaves the session. Your callback will be called with the player id and name as arguments.

void players.dispatch_on_join()

Calls your join handler(s) for every player that is already in the session.

bool players.exists(int player_id)

Checks if a player with the given id is in session.

int players.user()

Alternative to the PLAYER.PLAYER_ID native.

int players.user_ped()

Alternative to the PLAYER.PLAYER_PED_ID native.

table<int, int> players.list(bool include_user = true, bool include_friends = true, bool include_strangers = true)

Returns an index-based table with all matching player ids.

int players.get_host()
int players.get_script_host()
string players.get_name(int player_id)
int players.get_rockstar_id(int player_id)

This value might be spoofed by hard RID spoofing.

int players.get_rockstar_id_2(int player_id)

This value might be spoofed by soft RID spoofing.

int players.get_rank(int player_id)
int players.get_rp(int player_id)
int players.get_money(int player_id)
int players.get_wallet(int player_id)
int players.get_bank(int player_id)
number players.get_kd(int player_id)
int players.get_kills(int player_id)
int players.get_deaths(int player_id)
int players.get_language(int player_id)

Returns the same as the LOCALIZATION.GET_CURRENT_LANGUAGE native.

bool players.is_using_controller(int player_id)
string players.get_name_with_tags(int player_id)
string players.get_tags_string(int player_id)
bool players.is_godmode(int player_id)
bool players.is_marked_as_modder(int player_id)
bool players.is_marked_as_attacker(int player_id)
bool players.is_otr(int player_id)
bool players.is_in_interior(int player_id)
string players.get_host_token(int player_id)

Returns the player's host token as a decimal string.

string players.get_host_token_hex(int player_id)

Returns the player's host token as a 16-character padded hex string.

int players.get_boss(int player_id)

Returns -1 if not applicable.

int players.get_org_colour(int player_id)

Returns -1 if not applicable.

string players.clan_get_motto(int player_id)
userdata players.get_position(int player_id)

Works correctly at all distances.

int players.get_vehicle_model(int player_id)

Works at all distances, but best when the user is close to them.

void players.send_sms(int recipient, int sender, string text)

Sender has to differ from recipient. Recipient can't be yourself.

§ Entities Functions

int entities.create_ped(int type, int hash, Vector3 pos, number heading)

A wrapper for the PED.CREATE_PED native.

int entities.create_vehicle(int hash, Vector3 pos, number heading)

A wrapper for the VEHICLE.CREATE_VEHICLE native.

int entities.create_object(int hash, Vector3 pos)

A wrapper for the OBJECT.CREATE_OBJECT_NO_OFFSET native.

int entities.get_user_vehicle_as_handle()

Returns the user's current vehicle, last driven vehicle, or 0.

Shorthand for

local veh = PED.GET_VEHICLE_PED_IS_IN(PLAYER.PLAYER_PED_ID(), false)
if not ENTITY.IS_ENTITY_A_VEHICLE(veh) then
    veh = PED.GET_VEHICLE_PED_IS_IN(PLAYER.PLAYER_PED_ID(), true)
end
if not ENTITY.IS_ENTITY_A_VEHICLE(veh) then
    veh = 0
end
int entities.get_user_vehicle_as_pointer()
int entities.get_user_personal_vehicle_as_handle()
int entities.handle_to_pointer(int handle)

Returns the address of the entity with the given script handle.

int entities.pointer_to_handle(int addr)

Returns a script handle for the entity with the given address. This will force one to be allocated. Note that script handles are a limited resource.

table<int, int> entities.get_all_vehicles_as_handles()

This will force a script handle to be allocated for all vehicles. Note that script handles are a limited resource.

table<int, int> entities.get_all_vehicles_as_pointers()
table<int, int> entities.get_all_peds_as_handles()

This will force a script handle to be allocated for all peds. Note that script handles are a limited resource.

table<int, int> entities.get_all_peds_as_pointers()
table<int, int> entities.get_all_objects_as_handles()

This will force a script handle to be allocated for all objects. Note that script handles are a limited resource.

table<int, int> entities.get_all_objects_as_pointers()
table<int, int> entities.get_all_pickups_as_handles()

This will force a script handle to be allocated for all pickups. Note that script handles are a limited resource.

table<int, int> entities.get_all_pickups_as_pointers()
void entities.delete_by_handle(int handle)
void entities.delete_by_pointer(int addr)
int entities.get_model_hash(int addr)
Vector3 entities.get_position(int addr)

The result might be less precise than the native counterpart.

Vector3 entities.get_rotation(int addr)

The result might be less precise than the native counterpart.

number entities.get_health(int addr)
int entities.get_current_gear(int addr)

Only applicable to vehicles.

void entities.set_current_gear(int addr, int current_gear)

Only applicable to vehicles.

int entities.get_next_gear(int addr)

Only applicable to vehicles.

void entities.set_next_gear(int addr, int next_gear)

Only applicable to vehicles.

number entities.get_rpm(int addr)

Only applicable to vehicles.

number entities.get_gravity(int addr)

Only applicable to vehicles.

number entities.set_gravity(int addr, number gravity)

Only applicable to vehicles.

number entities.set_gravity_multiplier(int addr, number gravity_multiplier)

Only applicable to vehicles.

number entities.get_boost_charge(int addr)

Only applicable to vehicles. Returns a value between 0.0 and 1.25.

int entities.get_draw_handler(int addr)

Returns a pointer or 0.

int entities.vehicle_draw_handler_get_pearlecent_colour(int addr)
int entities.vehicle_draw_handler_get_wheel_colour(int addr)
bool entities.get_vehicle_has_been_owned_by_player(int addr)
int entities.get_player_info(int addr)

Only applicable to peds. Returns a pointer or 0.

int entities.player_info_get_game_state(int addr)

§ Chat Functions

int chat.on_message(function callback)

Registers a function to be called when a chat message is sent by any player in session:

chat.on_message(function(packet_sender, message_sender, text, team_chat)
    -- Do stuff...
end)
void chat.send_message(string text, bool team_chat, bool add_to_local_history, bool networked)

As you might be aware, messages have a limit of 140 UTF-16 characters. However, that is only true for the normal input, as you can use up to 254 UTF-8 characters over the network, and many more for the local history.

void chat.send_targeted_message(int packet_recipient, int message_sender, string text, bool team_chat)
int chat.get_state()

Possible return values:

  • 0 = Closed
  • 1 = Writing in team chat
  • 2 = Writing in all chat
bool chat.is_open()
void chat.open()
void chat.close()
string chat.get_draft()

Returns the message that the user is currently drafting or an empty string if not applicable.

void chat.ensure_open_with_empty_draft(bool team_chat)
void chat.add_to_draft(string appendix)
void chat.remove_from_draft(int characters)

§ DirectX Functions

Any X and Y value must be between 0.0 to 1.0.

The draw functions are in the HUD coordinate space, which is superimposed 1920x1080. You can also append _client to any draw function, e.g. draw_line_client to draw in client coordinate space, which is based on the game window size.

int directx.create_texture(string path)

An absolute path is recommended, e.g. by using filesystem.resources_dir().

void directx.draw_texture(int id, number sizeX, number sizeY, number centerX, number centerY, number posX, number posY, number rotation, Colour colour)
void directx.draw_texture(int id, number sizeX, number sizeY, number centerX, number centerY, number posX, number posY, number rotation, number r, number g, number b, number a)
void directx.draw_text(number x, number y, string text, int alignment, number scale, Colour colour, bool force_in_bounds = false)

alignment can be any of:

  • ALIGN_TOP_LEFT
  • ALIGN_TOP_CENTRE
  • ALIGN_TOP_RIGHT
  • ALIGN_CENTRE_LEFT
  • ALIGN_CENTRE
  • ALIGN_CENTRE_RIGHT
  • ALIGN_BOTTOM_LEFT
  • ALIGN_BOTTOM_CENTRE
  • ALIGN_BOTTOM_RIGHT
void directx.draw_rect(number x, number y, number width, number height, Colour colour)
void directx.draw_line(number x1, number y1, number x2, number y2, Colour colour)
void directx.draw_line(number x1, number y1, number x2, number y2, Colour colour1, Colour colour2)
void directx.draw_triangle(number x1, number y1, number x2, number y2, number x3, number y3, Colour colour)
number, number directx.get_client_size()
number, number directx.get_text_size(string text, number scale = 1.0)

Returns width and height.

number, number directx.pos_hud_to_client(number x, number y)
number, number directx.size_hud_to_client(number x, number y)
number, number directx.pos_client_to_hud(number x, number y)
number, number directx.size_client_to_hud(number x, number y)
int directx.blurrect_new()
void directx.blurrect_free(int instance)

Frees an instance. This is automatically done for all instances your script has allocated but not freed once it finishes.

void directx.blurrect_draw(int instance, number x, number y, number width, number height, int strength)

Prefer to use 1 instance per region, as any draw with a different size requires the buffers to be reallocated.

strength should be around 4 and can't exceed 255.

§ Util Functions

void util.require_natives(int version)

Loads the natives lib with the provided version, installing it from the repository if needed.

void util.execute_in_os_thread(function func)

Executes the given function in an OS thread to avoid holding up the game for expensive tasks like using require on a big file, creating lots of commands, or performing expensive calculations. Note that this will hold up your entire script, and calling natives or certain api functions in this context may lead to instabilities.

void util.require_no_lag(string file)

Like require, but in an OS thread, to avoid holding up the game. Might not work for every library.

void util.create_tick_handler(function func)

Registers the parameter-function to be called every tick until it returns false.

void util.try_run(function func)
void util.keep_running()

Prevents Stand's idle script cleanup.

void util.yield(?int wake_in_ms = nil)

Pauses the execution of the calling thread until the next tick or in wake_in_ms milliseconds.

If you're gonna create a "neverending" loop, don't forget to yield:

while true do
    -- Code that runs every tick...
    util.yield()
end

For simple loops, you should prefer util.create_tick_handler.

void util.create_thread(function thread_func, ...)

Creates the kind of thread that your script gets when it is created, or one of your callbacks is invoked, which is just another coroutine that gets resumed every tick and is expected to yield or return.

void util.stop_thread()

Stops the calling thread.

void util.stop_script()
void util.on_stop(function func)

Called in the final tick of your script. Yielding or creating threads in that context is undefined behaviour.

void util.toast(string message, int bitflags = TOAST_DEFAULT)

Possible bitflags:

  • TOAST_ABOVE_MAP — Uses Stand notifications if enabled
  • TOAST_LOGGER
  • TOAST_WEB
  • TOAST_CHAT
  • TOAST_CHAT_TEAM
  • TOAST_DEFAULT — Equal to (TOAST_ABOVE_MAP | TOAST_WEB)
  • TOAST_ALL — Equal to (TOAST_DEFAULT | TOAST_LOGGER)

Note that the chat flags are mutually exclusive.

void util.log(string message)

Alias for

util.toast(message, TOAST_LOGGER)

void util.draw_debug_text(string text)

Draws the given text at the top left of the screen using the menu colour for the current frame.

void util.show_corner_help(string message)

Shorthand for

util.BEGIN_TEXT_COMMAND_IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(message)
if not HUD.END_TEXT_COMMAND_IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(0) then
    util.BEGIN_TEXT_COMMAND_DISPLAY_HELP(message)
    HUD.END_TEXT_COMMAND_DISPLAY_HELP(0, false, true, -1)
end
void util.replace_corner_help(string message, string replacement_message)

Shorthand for

util.BEGIN_TEXT_COMMAND_IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(message)
if HUD.END_TEXT_COMMAND_IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(0) then
    util.BEGIN_TEXT_COMMAND_DISPLAY_HELP(replacement_message)
    HUD.END_TEXT_COMMAND_DISPLAY_HELP(0, false, true, -1)
end
void util.set_local_player_wanted_level(int wanted_level, bool no_drop = false)

Replacement for

if no_drop then
    PLAYER.SET_PLAYER_WANTED_LEVEL_NO_DROP(PLAYER.PLAYER_ID(), wanted_level, false)
else
    PLAYER.SET_PLAYER_WANTED_LEVEL(PLAYER.PLAYER_ID(), wanted_level, false)
end
PLAYER.SET_PLAYER_WANTED_LEVEL_NOW(PLAYER.PLAYER_ID(), false)

using pointers to avoid potentially tripping anti-cheat.

int util.joaat(string text)

JOAAT stands for Jenkins One At A Time which is the name of the hashing algorithm used pretty much everywhere in GTA.

string util.reverse_joaat(int hash)

Returns an empty string if the given hash is not found in Stand's dictionaries.

bool util.is_this_model_a_blimp(int|string model)
bool util.is_this_model_an_object(int|string model)
bool util.is_this_model_a_submarine(int|string model)
bool util.is_this_model_a_trailer(int|string model)
table<int, table> util.get_vehicles()

Returns an index-based table with a table for each vehicle in the game. The inner tables contain name and manufacturer.

table<int, table> util.get_weapons()

Returns an index-based table with a table for each weapon in the game. The inner tables contain hash, label_key, category, & category_id. Note that the categories are specific to Stand.

void util.BEGIN_TEXT_COMMAND_DISPLAY_TEXT(string message)

Replacement for

HUD.BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
HUD.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(message)

which increases your message's character limit.

void util._BEGIN_TEXT_COMMAND_LINE_COUNT(string message)

Replacement for

HUD._BEGIN_TEXT_COMMAND_LINE_COUNT("STRING")
HUD.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(message)

which increases your message's character limit.

void util.BEGIN_TEXT_COMMAND_IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(string message)

Replacement for

HUD.BEGIN_TEXT_COMMAND_IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("STRING")
HUD.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(message)

which increases your message's character limit.

void util.BEGIN_TEXT_COMMAND_DISPLAY_HELP(string message)

Replacement for

HUD.BEGIN_TEXT_COMMAND_DISPLAY_HELP("STRING")
HUD.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(message)

which increases your message's character limit.

void util._BEGIN_TEXT_COMMAND_GET_WIDTH(string message)

Replacement for

HUD._BEGIN_TEXT_COMMAND_GET_WIDTH("STRING")
HUD.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(message)

which increases your message's character limit.

void util.BEGIN_TEXT_COMMAND_THEFEED_POST(string message)

Replacement for

HUD.BEGIN_TEXT_COMMAND_THEFEED_POST("STRING")
HUD.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(message)

which increases your message's character limit.

int util.get_rp_required_for_rank(int rank)
int util.get_session_players_bitflag()
void util.trigger_script_event(int session_player_bitflags, table<any, int> data)

session_player_bitflags has a bit set to 1 for every player that should receive the script event; you can use util.get_session_players_bitflag() if you intend for everyone to receive the script event or use 1 << player_id to target individual players.

int util.current_time_millis()
int util.current_unix_time_seconds()

Returns how many seconds have passed since the UNIX epoch (00:00:00 UTC on 1 January 1970).

int util.remove_handler(int handler_id)
bool util.is_session_started()
bool util.is_session_transition_active()
int util.get_char_slot()
bool, number util.get_ground_z(number x, number y, number z_hint = 1000.0)

The most precise way to get the ground Z coordinate which respects water.

The ground Z will be below the z_hint.

If the bool return value is true, the number is the ground Z. If not, you should try again next tick. You may want to count the calls you made and abort after a certain amount of calls with the bool being false.

bool util.spoof_script(string|int script, function func)

If the provided script is not running, your function is not called and this returns false.

bool util.remove_blip(int blip)
void util.arspinner_enable()
void util.arspinner_disable()
bool util.is_bigmap_active()
void util.copy_to_clipboard(string text, bool notify = true)
string util.get_clipboard_text()
table<string,string> util.read_colons_and_tabs_file(string file)

Allows you to read a file in the colons and tabs format, which is what Stand uses for profiles, hotkeys, etc.

void util.write_colons_file(string file, table<string,string> data)

Allows you to write a file in the colons and tabs format.

void util.draw_ar_beacon(Vector3 pos)
void util.draw_box(Vector3 pos, Vector3 rot, Vector3 dimensions, int r, int g, int b, int a = 255)

Draws a box with 3d rotation using polys. Note that backfaceculling applies to the inside.

bool util.request_script_host(string|int script)
bool util.register_file(string path)

Registers the given file in the game so it can be used with natives, e.g. util.register_file(filesystem.resources_dir() .. "myscript.ytd") will allow you to use "myscript" as a texture dict for GRAPHICS natives.

string util.get_label_text(string label_name)

Same as HUD._GET_LABEL_TEXT except it will bypass any replacements Stand might be making.

string util.register_label(string text)

Registers a label, such that it can be used with HUD._GET_LABEL_TEXT and other natives.

bool util.is_key_down(int|string vk)

vk int values can be found at https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

vk may also be a string, if it contains a single character and that character is A-Z, 0-9, or a space.

int util.call_foreign_function(int addr, int|userdata|string a1 = 0, int|userdata|string a2 = 0, int|userdata|string a3 = 0, int|userdata|string a4 = 0)
string util.get_rtti_name(int inst_addr)
string util.get_rtti_hierarchy(int inst_addr)
void util.set_particle_fx_asset(int|string hash)
int util.blip_handle_to_pointer(int blip_handle)
int util.get_blip_display(int blip_handle)
int util.teleport_2d(number x, number y)

§ V3 Functions

userdata v3.new(float x, float y, float z)
userdata v3.new(Vector3 pos)
userdata v3.new()

Creates a new v3 instance, which can be used anywhere a Vector3 or Vector3* is accepted.

As an alternative to v3.new(...), you can also use v3(...).

Furthermore, all following functions can be called on a v3 instance using the : syntax.

float, float, float v3.get(userdata|int addr)
float v3.getX(userdata|int addr)
float v3.getY(userdata|int addr)
float v3.getZ(userdata|int addr)
float v3.getHeading(userdata|int addr)
void v3.set(userdata|int addr, float x, float y, float z)
void v3.setX(userdata|int addr, float x)
void v3.setY(userdata|int addr, float y)
void v3.setZ(userdata|int addr, float z)
void v3.reset(userdata|int addr)
void v3.add(userdata|int a, userdata|int b)

Adds b to a.

void v3.sub(userdata|int a, userdata|int b)

Subtracts b from a.

void v3.mul(userdata|int a, number f)

Multiplies a by f.

void v3.div(userdata|int a, number f)

Divides a by f.

bool v3.eq(userdata|int a, userdata|int b)
number v3.magnitude(userdata|int a)

Alternatively, you can use the # syntax on a v3 instance to get its magnitude.

number v3.distance(userdata|int a, int b)
void v3.abs(userdata|int addr)

Ensures that every axis is positive.

void v3.sum(userdata|int addr)
float v3.min(userdata|int addr)

Returns the value of the smallest axis.

float v3.max(userdata|int addr)

Returns the value of the biggest axis.

number v3.dot(userdata|int a, int b)
void v3.normalise(userdata|int addr)
userdata v3.crossProduct(userdata|int a, int b)

The result is a new instance.

userdata v3.toRot(userdata|int addr)

The result is a new instance with rotation data.

userdata v3.lookAt(userdata|int a, int b)

The result is a new instance with rotation data.

userdata v3.toDir(userdata|int addr)

The result is a new instance with direction data. The direction vector will have a magnitude of 1 / it is a unit vector, so you can safely multiply it.

Note that Stand expects/uses what is rotation order 2 for RAGE.

string v3.toString(userdata|int addr)

§ Lang Functions

string lang.get_current()

Returns the current menu language, which could be a 2-letter language code, "en-us", "sex", "uwu", or "hornyuwu".

int lang.register(string text)

Text is assumed to be in English (UK).

void lang.set_translate(string lang_code)

Starts the process of translating labels. lang_code must be a 2-letter language code or "sex".

void lang.translate(int label, string text)
int lang.find(string text, string lang_code = "en")

Finds an existing label using its text. Returns 0 if not found. lang_code must be a 2-letter language code or "sex".

string lang.get_string(Label label, string lang_code = "en")

lang_code must be a 2-letter language code, "en-us", "sex", "uwu", or "hornyuwu".

§ Filesystem Functions

string filesystem.appdata_dir()

Possible return value: C:\Users\John\AppData\Roaming\

string filesystem.stand_dir()

Possible return value: C:\Users\John\AppData\Roaming\Stand\

string filesystem.scripts_dir()

Possible return value: C:\Users\John\AppData\Roaming\Stand\Lua Scripts\

string filesystem.resources_dir()

Possible return value: C:\Users\John\AppData\Roaming\Stand\Lua Scripts\resources\

string filesystem.store_dir()

Possible return value: C:\Users\John\AppData\Roaming\Stand\Lua Scripts\store\

This function also creates the "store" directory if it doesn't exist.

bool filesystem.exists(string path)
bool filesystem.is_regular_file(string path)
bool filesystem.is_dir(string path)
void filesystem.mkdir(string path)
void filesystem.mkdirs(string path)
table<int, string> filesystem.list_files(string path)

Returns an index-based table with all files in the given directory.

for i, path in ipairs(filesystem.list_files(filesystem.scripts_dir())) do
    util.log(path)
end

Note that directories in the resulting table don't end on a \.

§ Async HTTP Functions

void async_http.init(string host, string path, ?function success_func = nil, ?function fail_func = nil)

This will make a GET request unless you use async_http.set_post before calling async_http.dispatch.

On success, your success_func will be called with the response body as a string, if your script is still alive when the request finishes; the lifetimes are independent.

void async_http.dispatch()

Finish building the async http request and carry it out in separate OS thread.

void async_http.set_post(string content_type, string payload)

Changes the request method, adds Content-Type and Content-Length headers, and sets the payload.

Examples of content_type:

  • application/json
  • application/x-www-form-urlencoded; charset=UTF-8
void async_http.add_header(string key, string value)

§ Memory Functions

int memory.script_global(int global)

Returns the address of the given script global.

int memory.script_local(string|int script, int local)

Returns the address of the given script local or 0 if the script was not found.

userdata memory.alloc(int size = 24)

The default size is 24 so it can fit a Vector3.

userdata memory.alloc_int()

Allocates 4 bytes.

int memory.scan(string pattern)

Scans the game's memory for the given IDA-style pattern. This is an expensive call so ideally you'd only ever scan for a pattern once and then use the resulting address until your script finishes.

int memory.rip(int addr)

Follows an offset from the instruction pointer ("RIP") at the given address.

So, whereas in C++ you might do something like this:

memory::scan("4C 8D 05 ? ? ? ? 48 8D 15 ? ? ? ? 48 8B C8 E8 ? ? ? ? 48 8D 15 ? ? ? ? 48 8D 4C 24 20 E8").add(3).rip().as<const char*>();

You'd do this in Lua (with a check for null-pointer because we're smart):

local addr = memory.scan("4C 8D 05 ? ? ? ? 48 8D 15 ? ? ? ? 48 8B C8 E8 ? ? ? ? 48 8D 15 ? ? ? ? 48 8D 4C 24 20 E8")
if addr == 0 then
    util.toast("pattern scan failed")
else
    util.toast(memory.read_string(memory.rip(addr + 3)))
end
int memory.read_byte(int|userdata addr)

Reads an 8-bit integer at the given address.

int memory.read_ubyte(int|userdata addr)

Reads an unsigned 8-bit integer at the given address.

int memory.read_short(int|userdata addr)

Reads a 16-bit integer at the given address.

int memory.read_ushort(int|userdata addr)

Reads an unsigned 16-bit integer at the given address.

int memory.read_int(int|userdata addr)

Reads a 32-bit integer at the given address.

int memory.read_uint(int|userdata addr)

Reads an unsigned 32-bit integer at the given address.

int memory.read_long(int|userdata addr)

Reads a 64-bit integer at the given address.

number memory.read_float(int|userdata addr)
string memory.read_string(int|userdata addr)
void memory.write_byte(int|userdata addr, int value)

Writes an 8-bit integer to the given address.

void memory.write_ubyte(int|userdata addr, int value)

Writes an unsigned 8-bit integer to the given address.

void memory.write_short(int|userdata addr, int value)

Writes a 16-bit integer to the given address.

void memory.write_ushort(int|userdata addr, int value)

Writes an unsigned 16-bit integer to the given address.

void memory.write_int(int|userdata addr, int value)

Writes a 32-bit integer to the given address.

void memory.write_uint(int|userdata addr, int value)

Writes an unsigned 32-bit integer to the given address.

void memory.write_long(int|userdata addr, int value)

Writes a 64-bit integer to the given address.

void memory.write_float(int|userdata addr, number value)
void memory.write_string(int|userdata addr, string value)
void memory.write_vector3(int|userdata addr, Vector3 value)

§ Profiling Functions

void profiling.once(string name, function func)

Executes the given function and prints the time it took to your log.

void profiling.tick(string name, function func)

Executes the given function and shows the time it took via the info text/debug text.