# Table of Contents
- [Home | GameSense Documentation](#home-gamesense-documentation)
- [Blog | GameSense Documentation](#blog-gamesense-documentation)
- [Archive | GameSense Documentation](#archive-gamesense-documentation)
- [Guide: FFI Crash Course | GameSense Documentation](#guide-ffi-crash-course-gamesense-documentation)
- [Tags | GameSense Documentation](#tags-gamesense-documentation)
- [One post tagged with "ffi" | GameSense Documentation](#one-post-tagged-with-ffi-gamesense-documentation)
- [Welcome to the blog! | GameSense Documentation](#welcome-to-the-blog-gamesense-documentation)
- [Search the documentation | GameSense Documentation](#search-the-documentation-gamesense-documentation)
- [One post tagged with "guide" | GameSense Documentation](#one-post-tagged-with-guide-gamesense-documentation)
- [bit.arshift | GameSense Documentation](#bit-arshift-gamesense-documentation)
- [bit.bor | GameSense Documentation](#bit-bor-gamesense-documentation)
- [bit.bnot | GameSense Documentation](#bit-bnot-gamesense-documentation)
- [bit.band | GameSense Documentation](#bit-band-gamesense-documentation)
- [bit.rol | GameSense Documentation](#bit-rol-gamesense-documentation)
- [bit.bswap | GameSense Documentation](#bit-bswap-gamesense-documentation)
- [bit.lshift | GameSense Documentation](#bit-lshift-gamesense-documentation)
- [Getting Started | GameSense Documentation](#getting-started-gamesense-documentation)
- [bit.bxor | GameSense Documentation](#bit-bxor-gamesense-documentation)
- [bit.ror | GameSense Documentation](#bit-ror-gamesense-documentation)
- [bit.rshift | GameSense Documentation](#bit-rshift-gamesense-documentation)
- [bit.tohex | GameSense Documentation](#bit-tohex-gamesense-documentation)
- [bit.tobit | GameSense Documentation](#bit-tobit-gamesense-documentation)
- [client.camera_angles | GameSense Documentation](#client-camera-angles-gamesense-documentation)
- [client.camera_position | GameSense Documentation](#client-camera-position-gamesense-documentation)
- [client.create_interface | GameSense Documentation](#client-create-interface-gamesense-documentation)
- [client.color_log | GameSense Documentation](#client-color-log-gamesense-documentation)
- [bit | GameSense Documentation](#bit-gamesense-documentation)
- [client.current_threat | GameSense Documentation](#client-current-threat-gamesense-documentation)
- [client.delay_call | GameSense Documentation](#client-delay-call-gamesense-documentation)
- [client.error_log | GameSense Documentation](#client-error-log-gamesense-documentation)
- [client.draw_debug_text | GameSense Documentation](#client-draw-debug-text-gamesense-documentation)
- [client.eye_position | GameSense Documentation](#client-eye-position-gamesense-documentation)
- [client.exec | GameSense Documentation](#client-exec-gamesense-documentation)
- [client.draw_hitboxes | GameSense Documentation](#client-draw-hitboxes-gamesense-documentation)
- [client.find_signature | GameSense Documentation](#client-find-signature-gamesense-documentation)
- [client.fire_event | GameSense Documentation](#client-fire-event-gamesense-documentation)
- [client.latency | GameSense Documentation](#client-latency-gamesense-documentation)
- [client.key_state | GameSense Documentation](#client-key-state-gamesense-documentation)
- [client.get_model_name | GameSense Documentation](#client-get-model-name-gamesense-documentation)
- [client.get_cvar | GameSense Documentation](#client-get-cvar-gamesense-documentation)
- [client.random_int | GameSense Documentation](#client-random-int-gamesense-documentation)
- [client.real_latency | GameSense Documentation](#client-real-latency-gamesense-documentation)
- [client.random_float | GameSense Documentation](#client-random-float-gamesense-documentation)
- [client.log | GameSense Documentation](#client-log-gamesense-documentation)
- [client.reload_active_scripts | GameSense Documentation](#client-reload-active-scripts-gamesense-documentation)
- [client.scale_damage | GameSense Documentation](#client-scale-damage-gamesense-documentation)
- [client.screen_size | GameSense Documentation](#client-screen-size-gamesense-documentation)
- [client.request_full_update | GameSense Documentation](#client-request-full-update-gamesense-documentation)
- [client.set_event_callback | GameSense Documentation](#client-set-event-callback-gamesense-documentation)
- [client.register_esp_flag | GameSense Documentation](#client-register-esp-flag-gamesense-documentation)
- [client.timestamp | GameSense Documentation](#client-timestamp-gamesense-documentation)
- [client.system_time | GameSense Documentation](#client-system-time-gamesense-documentation)
- [client.set_clan_tag | GameSense Documentation](#client-set-clan-tag-gamesense-documentation)
- [client.trace_line | GameSense Documentation](#client-trace-line-gamesense-documentation)
- [client.unix_time | GameSense Documentation](#client-unix-time-gamesense-documentation)
- [client.update_player_list | GameSense Documentation](#client-update-player-list-gamesense-documentation)
- [client.unset_event_callback | GameSense Documentation](#client-unset-event-callback-gamesense-documentation)
- [client.userid_to_entindex | GameSense Documentation](#client-userid-to-entindex-gamesense-documentation)
- [client.visible | GameSense Documentation](#client-visible-gamesense-documentation)
- [config.export | GameSense Documentation](#config-export-gamesense-documentation)
- [client | GameSense Documentation](#client-gamesense-documentation)
- [config.load | GameSense Documentation](#config-load-gamesense-documentation)
- [config.import | GameSense Documentation](#config-import-gamesense-documentation)
- [database.flush | GameSense Documentation](#database-flush-gamesense-documentation)
- [database.read | GameSense Documentation](#database-read-gamesense-documentation)
- [database.write | GameSense Documentation](#database-write-gamesense-documentation)
- [entity.get_all | GameSense Documentation](#entity-get-all-gamesense-documentation)
- [config | GameSense Documentation](#config-gamesense-documentation)
- [database | GameSense Documentation](#database-gamesense-documentation)
- [entity.get_esp_data | GameSense Documentation](#entity-get-esp-data-gamesense-documentation)
- [cvar | GameSense Documentation](#cvar-gamesense-documentation)
- [entity.get_classname | GameSense Documentation](#entity-get-classname-gamesense-documentation)
- [entity.get_game_rules | GameSense Documentation](#entity-get-game-rules-gamesense-documentation)
- [client.trace_bullet | GameSense Documentation](#client-trace-bullet-gamesense-documentation)
- [entity.get_origin | GameSense Documentation](#entity-get-origin-gamesense-documentation)
- [entity.get_player_name | GameSense Documentation](#entity-get-player-name-gamesense-documentation)
- [entity.get_player_resource | GameSense Documentation](#entity-get-player-resource-gamesense-documentation)
- [entity.get_local_player | GameSense Documentation](#entity-get-local-player-gamesense-documentation)
- [coroutine | GameSense Documentation](#coroutine-gamesense-documentation)
- [entity.get_prop | GameSense Documentation](#entity-get-prop-gamesense-documentation)
- [entity.get_players | GameSense Documentation](#entity-get-players-gamesense-documentation)
- [entity.get_player_weapon | GameSense Documentation](#entity-get-player-weapon-gamesense-documentation)
- [entity.hitbox_position | GameSense Documentation](#entity-hitbox-position-gamesense-documentation)
- [entity.get_steam64 | GameSense Documentation](#entity-get-steam64-gamesense-documentation)
- [entity.set_prop | GameSense Documentation](#entity-set-prop-gamesense-documentation)
- [entity.is_dormant | GameSense Documentation](#entity-is-dormant-gamesense-documentation)
- [entity.is_enemy | GameSense Documentation](#entity-is-enemy-gamesense-documentation)
- [entity.is_alive | GameSense Documentation](#entity-is-alive-gamesense-documentation)
- [entity.new_prop | GameSense Documentation](#entity-new-prop-gamesense-documentation)
- [collectgarbage | GameSense Documentation](#collectgarbage-gamesense-documentation)
- [defer | GameSense Documentation](#defer-gamesense-documentation)
- [entity | GameSense Documentation](#entity-gamesense-documentation)
- [entity.get_bounding_box | GameSense Documentation](#entity-get-bounding-box-gamesense-documentation)
- [assert | GameSense Documentation](#assert-gamesense-documentation)
- [error | GameSense Documentation](#error-gamesense-documentation)
- [getfenv | GameSense Documentation](#getfenv-gamesense-documentation)
- [ffi | GameSense Documentation](#ffi-gamesense-documentation)
- [next | GameSense Documentation](#next-gamesense-documentation)
- [ipairs | GameSense Documentation](#ipairs-gamesense-documentation)
- [pairs | GameSense Documentation](#pairs-gamesense-documentation)
- [load | GameSense Documentation](#load-gamesense-documentation)
- [print | GameSense Documentation](#print-gamesense-documentation)
- [pcall | GameSense Documentation](#pcall-gamesense-documentation)
- [printf | GameSense Documentation](#printf-gamesense-documentation)
- [getmetatable | GameSense Documentation](#getmetatable-gamesense-documentation)
- [rawequal | GameSense Documentation](#rawequal-gamesense-documentation)
- [rawget | GameSense Documentation](#rawget-gamesense-documentation)
- [rawlen | GameSense Documentation](#rawlen-gamesense-documentation)
- [readfile | GameSense Documentation](#readfile-gamesense-documentation)
- [rawset | GameSense Documentation](#rawset-gamesense-documentation)
- [require | GameSense Documentation](#require-gamesense-documentation)
- [tonumber | GameSense Documentation](#tonumber-gamesense-documentation)
- [select | GameSense Documentation](#select-gamesense-documentation)
- [setfenv | GameSense Documentation](#setfenv-gamesense-documentation)
- [Global Functions | GameSense Documentation](#global-functions-gamesense-documentation)
- [tostring | GameSense Documentation](#tostring-gamesense-documentation)
- [setmetatable | GameSense Documentation](#setmetatable-gamesense-documentation)
- [toticks | GameSense Documentation](#toticks-gamesense-documentation)
- [unpack | GameSense Documentation](#unpack-gamesense-documentation)
- [totime | GameSense Documentation](#totime-gamesense-documentation)
- [type | GameSense Documentation](#type-gamesense-documentation)
- [vtable_thunk | GameSense Documentation](#vtable-thunk-gamesense-documentation)
- [vtable_bind | GameSense Documentation](#vtable-bind-gamesense-documentation)
- [writefile | GameSense Documentation](#writefile-gamesense-documentation)
- [globals.chokedcommands | GameSense Documentation](#globals-chokedcommands-gamesense-documentation)
- [globals.absoluteframetime | GameSense Documentation](#globals-absoluteframetime-gamesense-documentation)
- [globals.commandack | GameSense Documentation](#globals-commandack-gamesense-documentation)
- [xpcall | GameSense Documentation](#xpcall-gamesense-documentation)
- [globals.curtime | GameSense Documentation](#globals-curtime-gamesense-documentation)
- [globals.framecount | GameSense Documentation](#globals-framecount-gamesense-documentation)
- [globals.frametime | GameSense Documentation](#globals-frametime-gamesense-documentation)
- [globals.mapname | GameSense Documentation](#globals-mapname-gamesense-documentation)
- [globals.lastoutgoingcommand | GameSense Documentation](#globals-lastoutgoingcommand-gamesense-documentation)
- [globals | GameSense Documentation](#globals-gamesense-documentation)
- [globals.maxplayers | GameSense Documentation](#globals-maxplayers-gamesense-documentation)
- [globals.realtime | GameSense Documentation](#globals-realtime-gamesense-documentation)
- [globals.oldcommandack | GameSense Documentation](#globals-oldcommandack-gamesense-documentation)
- [globals.servertickcount | GameSense Documentation](#globals-servertickcount-gamesense-documentation)
- [globals.tickinterval | GameSense Documentation](#globals-tickinterval-gamesense-documentation)
- [json.decode_invalid_numbers | GameSense Documentation](#json-decode-invalid-numbers-gamesense-documentation)
- [json.encode_invalid_numbers | GameSense Documentation](#json-encode-invalid-numbers-gamesense-documentation)
- [json.decode_max_depth | GameSense Documentation](#json-decode-max-depth-gamesense-documentation)
- [json.encode_max_depth | GameSense Documentation](#json-encode-max-depth-gamesense-documentation)
- [json.encode_number_precision | GameSense Documentation](#json-encode-number-precision-gamesense-documentation)
- [json | GameSense Documentation](#json-gamesense-documentation)
- [json.encode_sparse_array | GameSense Documentation](#json-encode-sparse-array-gamesense-documentation)
- [json.parse | GameSense Documentation](#json-parse-gamesense-documentation)
- [materialsystem.arms_material | GameSense Documentation](#materialsystem-arms-material-gamesense-documentation)
- [json.stringify | GameSense Documentation](#json-stringify-gamesense-documentation)
- [materialsystem.chams_material | GameSense Documentation](#materialsystem-chams-material-gamesense-documentation)
- [materialsystem.find_material | GameSense Documentation](#materialsystem-find-material-gamesense-documentation)
- [materialsystem | GameSense Documentation](#materialsystem-gamesense-documentation)
- [globals.tickcount | GameSense Documentation](#globals-tickcount-gamesense-documentation)
- [materialsystem.find_materials | GameSense Documentation](#materialsystem-find-materials-gamesense-documentation)
- [materialsystem.find_texture | GameSense Documentation](#materialsystem-find-texture-gamesense-documentation)
- [materialsystem.get_model_materials | GameSense Documentation](#materialsystem-get-model-materials-gamesense-documentation)
- [materialsystem.override_material | GameSense Documentation](#materialsystem-override-material-gamesense-documentation)
- [materialsystem.viewmodel_material | GameSense Documentation](#materialsystem-viewmodel-material-gamesense-documentation)
- [math.abs | GameSense Documentation](#math-abs-gamesense-documentation)
- [math.acos | GameSense Documentation](#math-acos-gamesense-documentation)
- [math.asin | GameSense Documentation](#math-asin-gamesense-documentation)
- [math.atan | GameSense Documentation](#math-atan-gamesense-documentation)
- [math.atan2 | GameSense Documentation](#math-atan2-gamesense-documentation)
- [math.cos | GameSense Documentation](#math-cos-gamesense-documentation)
- [math.cosh | GameSense Documentation](#math-cosh-gamesense-documentation)
- [math | GameSense Documentation](#math-gamesense-documentation)
- [math.deg | GameSense Documentation](#math-deg-gamesense-documentation)
- [math.exp | GameSense Documentation](#math-exp-gamesense-documentation)
- [math.ceil | GameSense Documentation](#math-ceil-gamesense-documentation)
- [math.floor | GameSense Documentation](#math-floor-gamesense-documentation)
- [math.fmod | GameSense Documentation](#math-fmod-gamesense-documentation)
- [math.frexp | GameSense Documentation](#math-frexp-gamesense-documentation)
- [math.log10 | GameSense Documentation](#math-log10-gamesense-documentation)
- [math.log | GameSense Documentation](#math-log-gamesense-documentation)
- [math.ldexp | GameSense Documentation](#math-ldexp-gamesense-documentation)
- [math.min | GameSense Documentation](#math-min-gamesense-documentation)
- [math.max | GameSense Documentation](#math-max-gamesense-documentation)
- [math.modf | GameSense Documentation](#math-modf-gamesense-documentation)
- [math.rad | GameSense Documentation](#math-rad-gamesense-documentation)
- [math.pow | GameSense Documentation](#math-pow-gamesense-documentation)
- [math.random | GameSense Documentation](#math-random-gamesense-documentation)
- [math.randomseed | GameSense Documentation](#math-randomseed-gamesense-documentation)
- [math.sinh | GameSense Documentation](#math-sinh-gamesense-documentation)
- [math.sin | GameSense Documentation](#math-sin-gamesense-documentation)
- [math.tan | GameSense Documentation](#math-tan-gamesense-documentation)
- [math.sqrt | GameSense Documentation](#math-sqrt-gamesense-documentation)
- [math.tanh | GameSense Documentation](#math-tanh-gamesense-documentation)
- [panorama.open | GameSense Documentation](#panorama-open-gamesense-documentation)
- [panorama | GameSense Documentation](#panorama-gamesense-documentation)
- [panorama.loadstring | GameSense Documentation](#panorama-loadstring-gamesense-documentation)
- [plist.set | GameSense Documentation](#plist-set-gamesense-documentation)
- [plist.get | GameSense Documentation](#plist-get-gamesense-documentation)
- [plist | GameSense Documentation](#plist-gamesense-documentation)
- [renderer.load_jpg | GameSense Documentation](#renderer-load-jpg-gamesense-documentation)
- [renderer.gradient | GameSense Documentation](#renderer-gradient-gamesense-documentation)
- [renderer.circle | GameSense Documentation](#renderer-circle-gamesense-documentation)
- [renderer.blur | GameSense Documentation](#renderer-blur-gamesense-documentation)
- [renderer.load_png | GameSense Documentation](#renderer-load-png-gamesense-documentation)
- [renderer.indicator | GameSense Documentation](#renderer-indicator-gamesense-documentation)
- [renderer.line | GameSense Documentation](#renderer-line-gamesense-documentation)
- [renderer.circle_outline | GameSense Documentation](#renderer-circle-outline-gamesense-documentation)
- [renderer.load_rgba | GameSense Documentation](#renderer-load-rgba-gamesense-documentation)
- [renderer.measure_text | GameSense Documentation](#renderer-measure-text-gamesense-documentation)
- [renderer.rectangle | GameSense Documentation](#renderer-rectangle-gamesense-documentation)
- [renderer.load_svg | GameSense Documentation](#renderer-load-svg-gamesense-documentation)
- [renderer.text | GameSense Documentation](#renderer-text-gamesense-documentation)
- [renderer | GameSense Documentation](#renderer-gamesense-documentation)
- [string.byte | GameSense Documentation](#string-byte-gamesense-documentation)
- [renderer.triangle | GameSense Documentation](#renderer-triangle-gamesense-documentation)
- [string.char | GameSense Documentation](#string-char-gamesense-documentation)
- [renderer.texture | GameSense Documentation](#renderer-texture-gamesense-documentation)
- [string.gmatch | GameSense Documentation](#string-gmatch-gamesense-documentation)
- [string.gsub | GameSense Documentation](#string-gsub-gamesense-documentation)
- [string.format | GameSense Documentation](#string-format-gamesense-documentation)
- [string.find | GameSense Documentation](#string-find-gamesense-documentation)
- [renderer.world_to_screen | GameSense Documentation](#renderer-world-to-screen-gamesense-documentation)
- [string.lower | GameSense Documentation](#string-lower-gamesense-documentation)
- [string.len | GameSense Documentation](#string-len-gamesense-documentation)
- [string.match | GameSense Documentation](#string-match-gamesense-documentation)
- [string.reverse | GameSense Documentation](#string-reverse-gamesense-documentation)
- [string.rep | GameSense Documentation](#string-rep-gamesense-documentation)
- [string.sub | GameSense Documentation](#string-sub-gamesense-documentation)
- [ui.is_menu_open | GameSense Documentation](#ui-is-menu-open-gamesense-documentation)
- [string.upper | GameSense Documentation](#string-upper-gamesense-documentation)
- [ui.menu_position | GameSense Documentation](#ui-menu-position-gamesense-documentation)
- [ui.menu_size | GameSense Documentation](#ui-menu-size-gamesense-documentation)
- [ui.mouse_position | GameSense Documentation](#ui-mouse-position-gamesense-documentation)
- [string | GameSense Documentation](#string-gamesense-documentation)
- [ui.new_button | GameSense Documentation](#ui-new-button-gamesense-documentation)
- [ui.new_checkbox | GameSense Documentation](#ui-new-checkbox-gamesense-documentation)
- [ui.new_color_picker | GameSense Documentation](#ui-new-color-picker-gamesense-documentation)
- [ui.new_combobox | GameSense Documentation](#ui-new-combobox-gamesense-documentation)
- [ui.new_multiselect | GameSense Documentation](#ui-new-multiselect-gamesense-documentation)
- [ui.new_listbox | GameSense Documentation](#ui-new-listbox-gamesense-documentation)
- [ui.new_hotkey | GameSense Documentation](#ui-new-hotkey-gamesense-documentation)
- [ui.new_label | GameSense Documentation](#ui-new-label-gamesense-documentation)
- [ui.new_string | GameSense Documentation](#ui-new-string-gamesense-documentation)
- [ui.get | GameSense Documentation](#ui-get-gamesense-documentation)
- [ui.new_textbox | GameSense Documentation](#ui-new-textbox-gamesense-documentation)
- [ui.reference | GameSense Documentation](#ui-reference-gamesense-documentation)
- [ui.new_slider | GameSense Documentation](#ui-new-slider-gamesense-documentation)
- [ui | GameSense Documentation](#ui-gamesense-documentation)
- [ui.set | GameSense Documentation](#ui-set-gamesense-documentation)
- [ui.set_callback | GameSense Documentation](#ui-set-callback-gamesense-documentation)
- [ui.set_enabled | GameSense Documentation](#ui-set-enabled-gamesense-documentation)
- [vector | GameSense Documentation](#vector-gamesense-documentation)
- [ui.update | GameSense Documentation](#ui-update-gamesense-documentation)
- [ui.set_visible | GameSense Documentation](#ui-set-visible-gamesense-documentation)
- [ui.name | GameSense Documentation](#ui-name-gamesense-documentation)
- [ui.type | GameSense Documentation](#ui-type-gamesense-documentation)
---
# Home | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/#docusaurus_skipToContent_fallback)
#### Welcome to the
gamesense docs
==============
Lua API Documentation
[API & Events](https://docs.gamesense.gs/docs/api)
[Code Snippets](https://docs.gamesense.gs/docs/snippets)
223API Functions
27Cheat Events
51Source Engine Events
169CS:GO Events
Maintained by the Lua scripting communityCreated by [sapphyrus](https://github.com/sapphyrus)
& [nex](https://github.com/Nexxed)
---
# Blog | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/blog#docusaurus_skipToContent_fallback)
Welcome to the blog section of the docs!
Here you will find guides and other useful tutorials and posts that can further enhance your understanding of the GameSense API and potentially make you more creative.
**Want to share your knowledge for others to see and read?**
Open a pull request on [GitHub](https://github.com/gamesensical/docs)
with your post in a markdown-formatted file. Use the blog posts that already exist as an example of how to format your markdown files, and how to name them.
Hello! I have decided to write an in-depth FFI crash course to provide a place for anyone regardless of your experience to learn without looking through the dozens of possibly confusing scripts released here on the forum, which are generally undocumented and some are quite complex. This guide will act as a place for you to learn FFI's basics, plus some tips and tricks from me and others to become a more experienced and competent Lua developer.
### A quick explanation[](https://docs.gamesense.gs/blog#a-quick-explanation "Direct link to heading")
Throughout the first section of this guide, I will be providing pseudo-C code snippets, as C comes built in with dedicated methods for certain, very important operations to us and is also the language that FFI provides an interface to, so knowledge of how it operates is completely necessary. The Lua equivalents of these operations require a more abstract thought process, as Lua does not provide explicit operations for the aforementioned functionality. I will be explaining these concepts in pseudo-C and then explaining how the same can be achieved in Lua, while calling back to earlier terminology we will have covered by then.
### What is FFI?[](https://docs.gamesense.gs/blog#what-is-ffi "Direct link to heading")
FFI - Also known (although rarely referred to) as the Foreign Function Interface - is an interface between different languages allowing them to interact with each other. FFI is generally used to create bindings to C/C++/etc libraries to higher level languages such as Python, Ruby but more importantly in our case, Lua. Bindings are just functions in the higher level languages that reach down into the lower level libraries and call their functions.
### FFI in GameSense[](https://docs.gamesense.gs/blog#ffi-in-gamesense "Direct link to heading")
In GameSense, FFI is most commonly used to provide an interface into the CS:GO processes' memory, which allows a Lua developer to interact directly with the game, such as calling functions, without relying on a middleman such as the Lua API to do all the work. Since FFI provides an interface between Lua and C, using FFI requires some knowledge about low-level memory and how low level languages like C interact with it - we will be covering this later.
Memory and how languages interact with it[](https://docs.gamesense.gs/blog#memory-and-how-languages-interact-with-it "Direct link to heading")
------------------------------------------------------------------------------------------------------------------------------------------------
In low-level languages such as C/C++ (I will be focusing on C as C++ provides some extra features for memory/pointer management that are far beyond the scope of this thread), memory can be interacted with directly, and all low-level/system software programming languages must provide us with a feature to do so. C provides us with a feature called pointers, these are essentially memory addresses, but ideally they will point to a specific variable, and this variable can be of any type (integer, long integer, floating point, string, even another pointer) and contain any value.
### The two types of pointers[](https://docs.gamesense.gs/blog#the-two-types-of-pointers "Direct link to heading")
The reason I said ideally in the previous paragraph is because a pointer may not always point to a variable, pointers that do not point to variable or any address are known as null pointers. This is where the divide between the two different types of pointers begins to show, they are known as SAFE and UNSAFE pointers. I will be covering safe pointers first as I find them easier to understand as there is less ambiguity, however when using FFI you will be seeing mostly unsafe pointers, however knowing how safe pointers work will make learning about unsafe pointers much easier. Below is an example of how a safe pointer is created.
float floating_point = 100.f; // Create a variable (randomly chosen float type)float* floating_pointer = &floating_point; // Create a pointer by using the & operator.
The variable floating\_pointer now points to the variable floating\_point (meaning it contains the address of the variable floating\_point). It is called a safe pointer because we can say that the variable floating\_point will always have an address in memory, and that the variable floating\_pointer will always point to that variable.
### Reading memory and dereferencing[](https://docs.gamesense.gs/blog#reading-memory-and-dereferencing "Direct link to heading")
Lets say we only have access to the variable floating\_pointer, yet we want to retrieve its value. This can be done through dereferencing. Dereferencing can be thought of like this, a pointer is a variable that references a value by memory address, and we are dereferencing the pointer to obtain its value. In other words, dereferencing is simply the act of reading the memory at the address stored in the pointer. Lets say that the address of the variable floating\_point in memory was 0x1000, and now our pointer floating\_pointer contains that value. In C we would dereference the variable using the \* operator, placing it before the variable name as such:
float original_value = *floating_pointer;
The variable original\_value will now contain 100.f.
### Unsafe pointers[](https://docs.gamesense.gs/blog#unsafe-pointers "Direct link to heading")
Unsafe pointers are a much more complex subject, hence why they're getting their own subheading. An unsafe pointer is a pointer that we cannot say for sure if it points to a value of a given type. If we were to create a pointer with the type char _(char_ is the type used for strings in C, the pointer points to the address of the first character in the string) and assign it some arbitrary address instead of an address we have retrieved from something that we know has to exist, we cannot say for sure that the address we assigned that pointer actually points to a string as we are able to give this pointer absolutely any numerical value, which may cause instability or a crash if we attempt to read from the pointer by dereferencing. Below is an example of an unsafe pointer in use.
char* our_string = (char*)0x1234;char first_character = *our_string;
This code, if compiled and ran will undoubtedly cause the application to crash as 0x1234 is almost certainly not a valid address. You can also see, that we never use the & operator that was discussed before, it is only used in the creation of safe pointers in C.
### Why unsafe pointers?[](https://docs.gamesense.gs/blog#why-unsafe-pointers "Direct link to heading")
Because of the nature of what we are doing with FFI in GameSense, we only have access to the memory, not the higher level source code abstraction that would allow us to create safe pointers. Unsafe pointers are simply a way of telling our code how to interpret a memory address. Throughout this post I have said variable, but remember that these variables can be of any type (functions, engine defined structures, custom user defined types, and basic integral types). In the Lua API, we are provided with some features that allow us to easily scan memory and retrieve important engine structures and classes, these are client.find\_signature and client.create\_interface and both of these concepts will be explored later in the upcoming section.
### A quick introduction into Memory type punning[](https://docs.gamesense.gs/blog#a-quick-introduction-into-memory-type-punning "Direct link to heading")
Type punning is the act of bypassing the type system that is implemented inside of programming languages. Type punning is more generally talked about in statically typed programming languages, not memory but although we are not dealing with the type system directly, we are dealing with the memory variables once managed by the type system. Look at this snippet from a hex editor, this was taken from a random executable file containing an XML string although this isn't important.

From this snippet, we can clearly see from the ASCII representation on the right-hand-side of the image that it is the beginning of a XML string, however if i wanted to read the first 4 bytes of this string as a 4 byte integer, I could do this:
int* int_pointer = (int*)0x405060;int first_4_bytes = *int_pointer;// This could be tied into one line.int first_4_bytes = *(int*)0x405060;
The value of the variable first\_4\_bytes is now 0x6D783F3C (notice how its just the value of each of the first 4 bytes but going backwards). The brackets and the int type name before the number is whats known as casting, im essentially telling the programming language how to interpret this memory address. This can be used on existing variables as well, given that they are numerical or are already a pointer just of a different type. This will be touched upon further in the next section. Remember! Memory is just a massive sequence of bytes, and it can be represented however you want it to, this is where a lot of the unsafety comes in.
### Pointer arithmetic[](https://docs.gamesense.gs/blog#pointer-arithmetic "Direct link to heading")
Pointer arithmetic is just like normal arithmetic like 1+2, but it takes something else into account. In all programming languages, types have size. This means that each type (byte, boolean, integer, long integer, string, floating point, etc.) have a specific size and some - like strings - can be dynamic in size. Pointer arithmetic simply takes the size of the type of the pointer into account when performing arithmetic operations (+ and -, multiplication and division are not used) on pointers. Here is an example of traversing an array using pointer arithmetic:
int our_array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};int* our_array_ptr = our_array; // Both of these are identical, but im doing this for clarity to show that our_array really is a pointer.int our_1st_value = *(our_array + 1);
You would be right in assuming that the variable our\_1st\_value now contains 1, but theres more going on behind the scenes, let me demonstrate:

This is what our array looks like in memory, notice how each value is takes up 4 bytes. This is because the size of integers in C is 4 bytes, but our numbers are so small that they only use the first byte of the 4 they are given. Remember that our\_array now contains the address 0x14001f068, and you may expect adding one to produce 0x14001f069, but remember that the next value in the array is 4 bytes away, so adding 1 really gives you 0x14001f06C as the size of the type has been taken into account.
Getting practical with FFI[](https://docs.gamesense.gs/blog#getting-practical-with-ffi "Direct link to heading")
------------------------------------------------------------------------------------------------------------------
In this section we will cover actually using FFI and some of the features the GameSense Lua API provides us that makes our lives a lot easier. However, before reading on I must admit that in Lua, since it is not really intended to be a low-level language it does not come built in with some features that I would like which can make things awkward sometimes, but I will be covering ways of how we achieve what we need in the second subsection.
### Getting started[](https://docs.gamesense.gs/blog#getting-started "Direct link to heading")
To actually start using FFI, you must include the library. This is done using the require keyword:
local ffi = require("ffi")
FFI can then be used as ffi.\* throughout your script. I have linked the official Lua FFI documentation, so you can refer to that for some more functionality provided that I will not be covering.
info
**NOTE:** functions such as **ffi.c** have been blocked for security reasons.
### How to achieve things in Lua[](https://docs.gamesense.gs/blog#how-to-achieve-things-in-lua "Direct link to heading")
Lua does not provide us with a dedicated operator for dereferencing pointers like C does, but we're in luck because we can treat our pointer like an array with only one element, because in memory an array is really just a pointer to the first element of the array (like strings are pointers to the first character in C). So if we wish to access the first (and only) element of our "array" we can use... \[0\]! Look at the following example:
byte our_array[5] = {0x74, 0x20, 0x62, 0x65, 0x20};
In the above snippet, we see an array getting declared and initialised with 5 elements, I have provided an example of what it would look like in memory if this was to be stored directly in data (as a global variable in a C program).

You can see that each value has been stored as a single byte, and that our\_array has been given the address 0x400060. Now as I have said before, to us, our\_array is just an array, but what really happens is it is turned into a pointer of type byte\* and trying to do certain things, such as printing this array will instead print the address of the array. Reading from the array using \[n\] simply adds n to the pointer, while taking Pointer Arithmetic into account and dereferencing, so these are all equivalent:
int first_value = *our_array; // Dereferencing will just give the first valueint first_value = our_array[0]; // Same as regular dereferencing, as we are just adding 0.
So we can imagine, that if we have a pointer it is, in memory, identical to an array containing one value, both are variables that contain an address that points to one single value, so we use \[0\] to dereference in Lua.
So now we know how to read from our pointers, but how do we create them? Well, the Lua API provided to us comes with 2 important functions that have been briefly mentioned before.
### Signatures and signature scanning[](https://docs.gamesense.gs/blog#signatures-and-signature-scanning "Direct link to heading")
Signatures are simply sequences of bytes in memory, they consist of a signature and a mask, the mask tells us which values can be wildcards (they can be any value, I'll explain why this is important later) and which must be present. The signature is the actual pattern in memory. They are most commonly represented in 2 ways, raw byte strings and IDA's style, however esoterik decided to be a cretin and use some unloved god-child mix of the two. Below are some examples of each:
IDA Style: 55 8B EC 83 E4 ? ? ? ? 53 56 57 8B F1 E8- The ?'s represent the wildcards.Code Style: \x55\x8B\xEC\x83\xE4\x00\x00\x00\x00\x53\x56\x57\x8B\xF1\xE8, xxxxx????xxxxxx- The ?'s in the second part are the wildcards.GameSense Style: \x55\x8B\xEC\x83\xE4\xCC\xCC\xCC\xCC\x53\x56\x57\x8B\xF1\xE8- The \xCC's represent the wildcards.
For IDA users, this modified version of Aidan Khoury's SigMaker can be used to create GameSense style code signatures: [SigMaker extension by infirms1337](https://gamesense.pub/forums/viewtopic.php?id=22768)
Here is a quick example of how signatures can be used to find a function: In the Source Engine, there is a function in the C\_CSPlayer class called SetAbsAngles. Now the class C\_CSPlayer gets updated a lot so therefore the index of this function (think of functions in classes like an array for now, I'll talk more about this in a future update) may change a lot so I'm going to sig this function. Using IDA or some other means, I can locate the function and use the SigMaker plugin to generate the signature `55 8B EC 83 E4 F8 83 EC 64 53 56 57 8B F1 E8`.
If we are to open client.dll in IDA and use the "search for sequence of bytes" search method and input the that signature - We will see:

This confirms that our signature is correct and will provide us with an address, but you might wonder how does this actually work? Look at this screenshot taken from IDA of the disassembly of that function:

Ignoring the actual disassembly, take a look at the numbers in grey on the left, these are the opcodes of the x86 assembly. What IDA as well as client.find\_signature will do is scan memory for the pattern you provide it, until it matches completely and it will return the address in which the first match was found, which is why you must ensure that either there is only one match for your signature, or all the matches are completely identical.
So for example, we could do this in Lua as such:
-- Specify the DLL that the signature is inside of, as well as handling an error if the signature wasn't found, this is always good practice.local signature_match = client.find_signature("client.dll", "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x64\x53\x56\x57\x8B\xF1\xE8") or error("Signature was not found")-- If everything went to plan, the address we now have in signature_match is a pointer to a function of type void(void*, float*).-- This could also be done by using ffi.cdef, but global typedefs should be avoided.local set_abs_angles = ffi.cast("void(__thiscall*)(void*, float*)", signature_match)-- You can now call set_abs_angles providing it with the correct arguments....
A lot is used here, ffi.cdef and ffi.cast will be talked about in more detail soon.
### Source engine's interface system:[](https://docs.gamesense.gs/blog#source-engines-interface-system "Direct link to heading")
The Source Engine is comprised of many different DLL's that must interact with each other, to do this, the engine has a system called interfaces. Each DLL exposes a function to other modules called CreateInterface. What this allows other modules to do is call that function and give a specific interface name, and be provided with a pointer to that class, containing all the functions it needs. As you can imagine we can do this too as anyone can call these functions. The Lua API has provided us with a quick and easy way to do this, through client.create\_interface. Interface names can be found by looking through the leaked CS:GO source code, specifically file names beginning with i such as [istudiorender.h](https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/istudiorender.h#L260)
. Working with interfaces is arguably more complex than signatures, as the structure of abstract classes is a bit more complex. The structure is as follows:
-- This ffi.cdef is put here purely for readability, still avoid using global typedefs, especially if you plan on having many users.ffi.cdef[[ typedef struct _our_interface { void** virtual_function_table; } our_interface;]]local our_interface = ffi.cast("our_interface*", _client.create_interface(...))-- If you look at the example interface I provided earlier in the Source SDK, you can see many function labelled virtual,-- these functions are stored as pointers in an array which is held in the first member of every interface, to access this-- you can do what I have done and defined a helper struct to make accessing this easier, or cast it to something like-- void** and dereference to get the address of this array.local our_virtual_function_table = our_interface.virtual_function_table-- I have defined the member virtual_function_table as void** because as I mentioned earlier, arrays are represented as pointers in memory,-- so we can access this list of functions like an array, and I have also made it an array of void*, as void* represents any pointer type.-- Lets say index 5 is a function pointer of type void(int) that we want to call.ffi.cast("void(*)(int)", our_virtual_function_table[5])(10)
@sapphyrus has just told be about some undocumented functions that the Lua API also provides to make virtual function table traversal easier, vtable\_bind and vtable\_thunk can be used to quickly attach to a VFT which isn't directly exposed, and retrieve functions from it safely and quickly:
-- Bind to the NetChannelInfo interface, which is retrieved from the GetNetChannelInfo function from the VEngineClient interface.local native_GetNetChannelInfo = vtable_bind("engine.dll", "VEngineClient014", 78, "void*(__thiscall*)(void*)")-- Generate thunks that will call the virtual function at the index provided, with the specified type.local native_GetLatency = vtable_thunk(9, "float(__thiscall*)(void*, int)")local native_GetAvgLatency = vtable_thunk(10, "float(__thiscall*)(void*, int)")-- Since GetLatency is a virtual function inside INetChannelInfo, pass the result of native_GetNetChannelInfo.native_GetLatency(native_GetNetChannelInfo(), ...)...
### Casting[](https://docs.gamesense.gs/blog#casting "Direct link to heading")
Casting is extremely useful and can be achieved through the ffi.cast function. I spoke briefly about casting earlier where I told the programming language that a number was actually meant to be interpreted as a pointer. This is the same in Lua, through the use of FFI, a number retrieved from client.find\_signature or client.create\_interface can be casted into a pointer value, allowing you to read and modify memory as you please. Some examples using ffi.cast are located below and throughout the rest of the post.
#### Some examples[](https://docs.gamesense.gs/blog#some-examples "Direct link to heading")
This example is taken from my Netvar Proxy hooking library, and it shows you how to call a function from an interface received from client.create\_interface.
-- Use client.create_interface to find the exported interface from client.dlllocal chl_client = cast("void***", client.create_interface("client.dll", "VClient018")) or error('ChlClient is nil.')-- Dereference once to get the address of the VFT, which points to the first entry.local chl_client_function_table = chl_client[0]-- Access index 8 into the function table as that is the index of the function I need.local get_all_classes = cast(ffi.typeof("ntv_ClientClass*(__thiscall*)(void*)"), chl_client_function_table[8])-- When calling virtual functions, they will always require the first parameter to be the this pointer, which is just a pointer-- To the class they belong to, like this.local client_class = get_all_classes(chl_client)
Thank you for reading! I hope this helped you to get started with FFI and begin on your journey, I will be updating this post with examples and adding more sections in the future about more complex ideas and abstractions of memory that are commonly used in FFI development with GameSense such as safe pointers in Lua through FFI, as well as independent reverse engineering methods to help you keep yourself up to date, instead of relying on others. Stay tuned!
Further reading[](https://docs.gamesense.gs/blog#further-reading "Direct link to heading")
--------------------------------------------------------------------------------------------
* [C Typedefs](https://en.wikipedia.org/wiki/Typedef)
* [FFI Documentation](https://luajit.org/ext_ffi.html)
* [Official FFI tutorial](https://luajit.org/ext_ffi_tutorial.html)
---
# Archive | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/blog/archive#docusaurus_skipToContent_fallback)
### 2020
* [October 26, 2020 - Guide: FFI Crash Course](https://docs.gamesense.gs/blog/ffi-crash-course)
### 2022
* [December 26, 2022 - Welcome to the blog!](https://docs.gamesense.gs/blog/welcome)
---
# Guide: FFI Crash Course | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/blog/ffi-crash-course#docusaurus_skipToContent_fallback)
Hello! I have decided to write an in-depth FFI crash course to provide a place for anyone regardless of your experience to learn without looking through the dozens of possibly confusing scripts released here on the forum, which are generally undocumented and some are quite complex. This guide will act as a place for you to learn FFI's basics, plus some tips and tricks from me and others to become a more experienced and competent Lua developer.
### A quick explanation[](https://docs.gamesense.gs/blog/ffi-crash-course#a-quick-explanation "Direct link to heading")
Throughout the first section of this guide, I will be providing pseudo-C code snippets, as C comes built in with dedicated methods for certain, very important operations to us and is also the language that FFI provides an interface to, so knowledge of how it operates is completely necessary. The Lua equivalents of these operations require a more abstract thought process, as Lua does not provide explicit operations for the aforementioned functionality. I will be explaining these concepts in pseudo-C and then explaining how the same can be achieved in Lua, while calling back to earlier terminology we will have covered by then.
### What is FFI?[](https://docs.gamesense.gs/blog/ffi-crash-course#what-is-ffi "Direct link to heading")
FFI - Also known (although rarely referred to) as the Foreign Function Interface - is an interface between different languages allowing them to interact with each other. FFI is generally used to create bindings to C/C++/etc libraries to higher level languages such as Python, Ruby but more importantly in our case, Lua. Bindings are just functions in the higher level languages that reach down into the lower level libraries and call their functions.
### FFI in GameSense[](https://docs.gamesense.gs/blog/ffi-crash-course#ffi-in-gamesense "Direct link to heading")
In GameSense, FFI is most commonly used to provide an interface into the CS:GO processes' memory, which allows a Lua developer to interact directly with the game, such as calling functions, without relying on a middleman such as the Lua API to do all the work. Since FFI provides an interface between Lua and C, using FFI requires some knowledge about low-level memory and how low level languages like C interact with it - we will be covering this later.
Memory and how languages interact with it[](https://docs.gamesense.gs/blog/ffi-crash-course#memory-and-how-languages-interact-with-it "Direct link to heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
In low-level languages such as C/C++ (I will be focusing on C as C++ provides some extra features for memory/pointer management that are far beyond the scope of this thread), memory can be interacted with directly, and all low-level/system software programming languages must provide us with a feature to do so. C provides us with a feature called pointers, these are essentially memory addresses, but ideally they will point to a specific variable, and this variable can be of any type (integer, long integer, floating point, string, even another pointer) and contain any value.
### The two types of pointers[](https://docs.gamesense.gs/blog/ffi-crash-course#the-two-types-of-pointers "Direct link to heading")
The reason I said ideally in the previous paragraph is because a pointer may not always point to a variable, pointers that do not point to variable or any address are known as null pointers. This is where the divide between the two different types of pointers begins to show, they are known as SAFE and UNSAFE pointers. I will be covering safe pointers first as I find them easier to understand as there is less ambiguity, however when using FFI you will be seeing mostly unsafe pointers, however knowing how safe pointers work will make learning about unsafe pointers much easier. Below is an example of how a safe pointer is created.
float floating_point = 100.f; // Create a variable (randomly chosen float type)float* floating_pointer = &floating_point; // Create a pointer by using the & operator.
The variable floating\_pointer now points to the variable floating\_point (meaning it contains the address of the variable floating\_point). It is called a safe pointer because we can say that the variable floating\_point will always have an address in memory, and that the variable floating\_pointer will always point to that variable.
### Reading memory and dereferencing[](https://docs.gamesense.gs/blog/ffi-crash-course#reading-memory-and-dereferencing "Direct link to heading")
Lets say we only have access to the variable floating\_pointer, yet we want to retrieve its value. This can be done through dereferencing. Dereferencing can be thought of like this, a pointer is a variable that references a value by memory address, and we are dereferencing the pointer to obtain its value. In other words, dereferencing is simply the act of reading the memory at the address stored in the pointer. Lets say that the address of the variable floating\_point in memory was 0x1000, and now our pointer floating\_pointer contains that value. In C we would dereference the variable using the \* operator, placing it before the variable name as such:
float original_value = *floating_pointer;
The variable original\_value will now contain 100.f.
### Unsafe pointers[](https://docs.gamesense.gs/blog/ffi-crash-course#unsafe-pointers "Direct link to heading")
Unsafe pointers are a much more complex subject, hence why they're getting their own subheading. An unsafe pointer is a pointer that we cannot say for sure if it points to a value of a given type. If we were to create a pointer with the type char _(char_ is the type used for strings in C, the pointer points to the address of the first character in the string) and assign it some arbitrary address instead of an address we have retrieved from something that we know has to exist, we cannot say for sure that the address we assigned that pointer actually points to a string as we are able to give this pointer absolutely any numerical value, which may cause instability or a crash if we attempt to read from the pointer by dereferencing. Below is an example of an unsafe pointer in use.
char* our_string = (char*)0x1234;char first_character = *our_string;
This code, if compiled and ran will undoubtedly cause the application to crash as 0x1234 is almost certainly not a valid address. You can also see, that we never use the & operator that was discussed before, it is only used in the creation of safe pointers in C.
### Why unsafe pointers?[](https://docs.gamesense.gs/blog/ffi-crash-course#why-unsafe-pointers "Direct link to heading")
Because of the nature of what we are doing with FFI in GameSense, we only have access to the memory, not the higher level source code abstraction that would allow us to create safe pointers. Unsafe pointers are simply a way of telling our code how to interpret a memory address. Throughout this post I have said variable, but remember that these variables can be of any type (functions, engine defined structures, custom user defined types, and basic integral types). In the Lua API, we are provided with some features that allow us to easily scan memory and retrieve important engine structures and classes, these are client.find\_signature and client.create\_interface and both of these concepts will be explored later in the upcoming section.
### A quick introduction into Memory type punning[](https://docs.gamesense.gs/blog/ffi-crash-course#a-quick-introduction-into-memory-type-punning "Direct link to heading")
Type punning is the act of bypassing the type system that is implemented inside of programming languages. Type punning is more generally talked about in statically typed programming languages, not memory but although we are not dealing with the type system directly, we are dealing with the memory variables once managed by the type system. Look at this snippet from a hex editor, this was taken from a random executable file containing an XML string although this isn't important.

From this snippet, we can clearly see from the ASCII representation on the right-hand-side of the image that it is the beginning of a XML string, however if i wanted to read the first 4 bytes of this string as a 4 byte integer, I could do this:
int* int_pointer = (int*)0x405060;int first_4_bytes = *int_pointer;// This could be tied into one line.int first_4_bytes = *(int*)0x405060;
The value of the variable first\_4\_bytes is now 0x6D783F3C (notice how its just the value of each of the first 4 bytes but going backwards). The brackets and the int type name before the number is whats known as casting, im essentially telling the programming language how to interpret this memory address. This can be used on existing variables as well, given that they are numerical or are already a pointer just of a different type. This will be touched upon further in the next section. Remember! Memory is just a massive sequence of bytes, and it can be represented however you want it to, this is where a lot of the unsafety comes in.
### Pointer arithmetic[](https://docs.gamesense.gs/blog/ffi-crash-course#pointer-arithmetic "Direct link to heading")
Pointer arithmetic is just like normal arithmetic like 1+2, but it takes something else into account. In all programming languages, types have size. This means that each type (byte, boolean, integer, long integer, string, floating point, etc.) have a specific size and some - like strings - can be dynamic in size. Pointer arithmetic simply takes the size of the type of the pointer into account when performing arithmetic operations (+ and -, multiplication and division are not used) on pointers. Here is an example of traversing an array using pointer arithmetic:
int our_array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};int* our_array_ptr = our_array; // Both of these are identical, but im doing this for clarity to show that our_array really is a pointer.int our_1st_value = *(our_array + 1);
You would be right in assuming that the variable our\_1st\_value now contains 1, but theres more going on behind the scenes, let me demonstrate:

This is what our array looks like in memory, notice how each value is takes up 4 bytes. This is because the size of integers in C is 4 bytes, but our numbers are so small that they only use the first byte of the 4 they are given. Remember that our\_array now contains the address 0x14001f068, and you may expect adding one to produce 0x14001f069, but remember that the next value in the array is 4 bytes away, so adding 1 really gives you 0x14001f06C as the size of the type has been taken into account.
Getting practical with FFI[](https://docs.gamesense.gs/blog/ffi-crash-course#getting-practical-with-ffi "Direct link to heading")
-----------------------------------------------------------------------------------------------------------------------------------
In this section we will cover actually using FFI and some of the features the GameSense Lua API provides us that makes our lives a lot easier. However, before reading on I must admit that in Lua, since it is not really intended to be a low-level language it does not come built in with some features that I would like which can make things awkward sometimes, but I will be covering ways of how we achieve what we need in the second subsection.
### Getting started[](https://docs.gamesense.gs/blog/ffi-crash-course#getting-started "Direct link to heading")
To actually start using FFI, you must include the library. This is done using the require keyword:
local ffi = require("ffi")
FFI can then be used as ffi.\* throughout your script. I have linked the official Lua FFI documentation, so you can refer to that for some more functionality provided that I will not be covering.
info
**NOTE:** functions such as **ffi.c** have been blocked for security reasons.
### How to achieve things in Lua[](https://docs.gamesense.gs/blog/ffi-crash-course#how-to-achieve-things-in-lua "Direct link to heading")
Lua does not provide us with a dedicated operator for dereferencing pointers like C does, but we're in luck because we can treat our pointer like an array with only one element, because in memory an array is really just a pointer to the first element of the array (like strings are pointers to the first character in C). So if we wish to access the first (and only) element of our "array" we can use... \[0\]! Look at the following example:
byte our_array[5] = {0x74, 0x20, 0x62, 0x65, 0x20};
In the above snippet, we see an array getting declared and initialised with 5 elements, I have provided an example of what it would look like in memory if this was to be stored directly in data (as a global variable in a C program).

You can see that each value has been stored as a single byte, and that our\_array has been given the address 0x400060. Now as I have said before, to us, our\_array is just an array, but what really happens is it is turned into a pointer of type byte\* and trying to do certain things, such as printing this array will instead print the address of the array. Reading from the array using \[n\] simply adds n to the pointer, while taking Pointer Arithmetic into account and dereferencing, so these are all equivalent:
int first_value = *our_array; // Dereferencing will just give the first valueint first_value = our_array[0]; // Same as regular dereferencing, as we are just adding 0.
So we can imagine, that if we have a pointer it is, in memory, identical to an array containing one value, both are variables that contain an address that points to one single value, so we use \[0\] to dereference in Lua.
So now we know how to read from our pointers, but how do we create them? Well, the Lua API provided to us comes with 2 important functions that have been briefly mentioned before.
### Signatures and signature scanning[](https://docs.gamesense.gs/blog/ffi-crash-course#signatures-and-signature-scanning "Direct link to heading")
Signatures are simply sequences of bytes in memory, they consist of a signature and a mask, the mask tells us which values can be wildcards (they can be any value, I'll explain why this is important later) and which must be present. The signature is the actual pattern in memory. They are most commonly represented in 2 ways, raw byte strings and IDA's style, however esoterik decided to be a cretin and use some unloved god-child mix of the two. Below are some examples of each:
IDA Style: 55 8B EC 83 E4 ? ? ? ? 53 56 57 8B F1 E8- The ?'s represent the wildcards.Code Style: \x55\x8B\xEC\x83\xE4\x00\x00\x00\x00\x53\x56\x57\x8B\xF1\xE8, xxxxx????xxxxxx- The ?'s in the second part are the wildcards.GameSense Style: \x55\x8B\xEC\x83\xE4\xCC\xCC\xCC\xCC\x53\x56\x57\x8B\xF1\xE8- The \xCC's represent the wildcards.
For IDA users, this modified version of Aidan Khoury's SigMaker can be used to create GameSense style code signatures: [SigMaker extension by infirms1337](https://gamesense.pub/forums/viewtopic.php?id=22768)
Here is a quick example of how signatures can be used to find a function: In the Source Engine, there is a function in the C\_CSPlayer class called SetAbsAngles. Now the class C\_CSPlayer gets updated a lot so therefore the index of this function (think of functions in classes like an array for now, I'll talk more about this in a future update) may change a lot so I'm going to sig this function. Using IDA or some other means, I can locate the function and use the SigMaker plugin to generate the signature `55 8B EC 83 E4 F8 83 EC 64 53 56 57 8B F1 E8`.
If we are to open client.dll in IDA and use the "search for sequence of bytes" search method and input the that signature - We will see:

This confirms that our signature is correct and will provide us with an address, but you might wonder how does this actually work? Look at this screenshot taken from IDA of the disassembly of that function:

Ignoring the actual disassembly, take a look at the numbers in grey on the left, these are the opcodes of the x86 assembly. What IDA as well as client.find\_signature will do is scan memory for the pattern you provide it, until it matches completely and it will return the address in which the first match was found, which is why you must ensure that either there is only one match for your signature, or all the matches are completely identical.
So for example, we could do this in Lua as such:
-- Specify the DLL that the signature is inside of, as well as handling an error if the signature wasn't found, this is always good practice.local signature_match = client.find_signature("client.dll", "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x64\x53\x56\x57\x8B\xF1\xE8") or error("Signature was not found")-- If everything went to plan, the address we now have in signature_match is a pointer to a function of type void(void*, float*).-- This could also be done by using ffi.cdef, but global typedefs should be avoided.local set_abs_angles = ffi.cast("void(__thiscall*)(void*, float*)", signature_match)-- You can now call set_abs_angles providing it with the correct arguments....
A lot is used here, ffi.cdef and ffi.cast will be talked about in more detail soon.
### Source engine's interface system:[](https://docs.gamesense.gs/blog/ffi-crash-course#source-engines-interface-system "Direct link to heading")
The Source Engine is comprised of many different DLL's that must interact with each other, to do this, the engine has a system called interfaces. Each DLL exposes a function to other modules called CreateInterface. What this allows other modules to do is call that function and give a specific interface name, and be provided with a pointer to that class, containing all the functions it needs. As you can imagine we can do this too as anyone can call these functions. The Lua API has provided us with a quick and easy way to do this, through client.create\_interface. Interface names can be found by looking through the leaked CS:GO source code, specifically file names beginning with i such as [istudiorender.h](https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/istudiorender.h#L260)
. Working with interfaces is arguably more complex than signatures, as the structure of abstract classes is a bit more complex. The structure is as follows:
-- This ffi.cdef is put here purely for readability, still avoid using global typedefs, especially if you plan on having many users.ffi.cdef[[ typedef struct _our_interface { void** virtual_function_table; } our_interface;]]local our_interface = ffi.cast("our_interface*", _client.create_interface(...))-- If you look at the example interface I provided earlier in the Source SDK, you can see many function labelled virtual,-- these functions are stored as pointers in an array which is held in the first member of every interface, to access this-- you can do what I have done and defined a helper struct to make accessing this easier, or cast it to something like-- void** and dereference to get the address of this array.local our_virtual_function_table = our_interface.virtual_function_table-- I have defined the member virtual_function_table as void** because as I mentioned earlier, arrays are represented as pointers in memory,-- so we can access this list of functions like an array, and I have also made it an array of void*, as void* represents any pointer type.-- Lets say index 5 is a function pointer of type void(int) that we want to call.ffi.cast("void(*)(int)", our_virtual_function_table[5])(10)
@sapphyrus has just told be about some undocumented functions that the Lua API also provides to make virtual function table traversal easier, vtable\_bind and vtable\_thunk can be used to quickly attach to a VFT which isn't directly exposed, and retrieve functions from it safely and quickly:
-- Bind to the NetChannelInfo interface, which is retrieved from the GetNetChannelInfo function from the VEngineClient interface.local native_GetNetChannelInfo = vtable_bind("engine.dll", "VEngineClient014", 78, "void*(__thiscall*)(void*)")-- Generate thunks that will call the virtual function at the index provided, with the specified type.local native_GetLatency = vtable_thunk(9, "float(__thiscall*)(void*, int)")local native_GetAvgLatency = vtable_thunk(10, "float(__thiscall*)(void*, int)")-- Since GetLatency is a virtual function inside INetChannelInfo, pass the result of native_GetNetChannelInfo.native_GetLatency(native_GetNetChannelInfo(), ...)...
### Casting[](https://docs.gamesense.gs/blog/ffi-crash-course#casting "Direct link to heading")
Casting is extremely useful and can be achieved through the ffi.cast function. I spoke briefly about casting earlier where I told the programming language that a number was actually meant to be interpreted as a pointer. This is the same in Lua, through the use of FFI, a number retrieved from client.find\_signature or client.create\_interface can be casted into a pointer value, allowing you to read and modify memory as you please. Some examples using ffi.cast are located below and throughout the rest of the post.
#### Some examples[](https://docs.gamesense.gs/blog/ffi-crash-course#some-examples "Direct link to heading")
This example is taken from my Netvar Proxy hooking library, and it shows you how to call a function from an interface received from client.create\_interface.
-- Use client.create_interface to find the exported interface from client.dlllocal chl_client = cast("void***", client.create_interface("client.dll", "VClient018")) or error('ChlClient is nil.')-- Dereference once to get the address of the VFT, which points to the first entry.local chl_client_function_table = chl_client[0]-- Access index 8 into the function table as that is the index of the function I need.local get_all_classes = cast(ffi.typeof("ntv_ClientClass*(__thiscall*)(void*)"), chl_client_function_table[8])-- When calling virtual functions, they will always require the first parameter to be the this pointer, which is just a pointer-- To the class they belong to, like this.local client_class = get_all_classes(chl_client)
Thank you for reading! I hope this helped you to get started with FFI and begin on your journey, I will be updating this post with examples and adding more sections in the future about more complex ideas and abstractions of memory that are commonly used in FFI development with GameSense such as safe pointers in Lua through FFI, as well as independent reverse engineering methods to help you keep yourself up to date, instead of relying on others. Stay tuned!
Further reading[](https://docs.gamesense.gs/blog/ffi-crash-course#further-reading "Direct link to heading")
-------------------------------------------------------------------------------------------------------------
* [C Typedefs](https://en.wikipedia.org/wiki/Typedef)
* [FFI Documentation](https://luajit.org/ext_ffi.html)
* [Official FFI tutorial](https://luajit.org/ext_ffi_tutorial.html)
* [A quick explanation](https://docs.gamesense.gs/blog/ffi-crash-course#a-quick-explanation)
* [What is FFI?](https://docs.gamesense.gs/blog/ffi-crash-course#what-is-ffi)
* [FFI in GameSense](https://docs.gamesense.gs/blog/ffi-crash-course#ffi-in-gamesense)
* [Memory and how languages interact with it](https://docs.gamesense.gs/blog/ffi-crash-course#memory-and-how-languages-interact-with-it)
* [The two types of pointers](https://docs.gamesense.gs/blog/ffi-crash-course#the-two-types-of-pointers)
* [Reading memory and dereferencing](https://docs.gamesense.gs/blog/ffi-crash-course#reading-memory-and-dereferencing)
* [Unsafe pointers](https://docs.gamesense.gs/blog/ffi-crash-course#unsafe-pointers)
* [Why unsafe pointers?](https://docs.gamesense.gs/blog/ffi-crash-course#why-unsafe-pointers)
* [A quick introduction into Memory type punning](https://docs.gamesense.gs/blog/ffi-crash-course#a-quick-introduction-into-memory-type-punning)
* [Pointer arithmetic](https://docs.gamesense.gs/blog/ffi-crash-course#pointer-arithmetic)
* [Getting practical with FFI](https://docs.gamesense.gs/blog/ffi-crash-course#getting-practical-with-ffi)
* [Getting started](https://docs.gamesense.gs/blog/ffi-crash-course#getting-started)
* [How to achieve things in Lua](https://docs.gamesense.gs/blog/ffi-crash-course#how-to-achieve-things-in-lua)
* [Signatures and signature scanning](https://docs.gamesense.gs/blog/ffi-crash-course#signatures-and-signature-scanning)
* [Source engine's interface system:](https://docs.gamesense.gs/blog/ffi-crash-course#source-engines-interface-system)
* [Casting](https://docs.gamesense.gs/blog/ffi-crash-course#casting)
* [Further reading](https://docs.gamesense.gs/blog/ffi-crash-course#further-reading)
---
# Tags | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/blog/tags/#docusaurus_skipToContent_fallback)
Tags
====
F
-
* [ffi1](https://docs.gamesense.gs/blog/tags/ffi)
* * *
G
-
* [guide1](https://docs.gamesense.gs/blog/tags/guide)
* * *
---
# One post tagged with "ffi" | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/blog/tags/ffi/#docusaurus_skipToContent_fallback)
Hello! I have decided to write an in-depth FFI crash course to provide a place for anyone regardless of your experience to learn without looking through the dozens of possibly confusing scripts released here on the forum, which are generally undocumented and some are quite complex. This guide will act as a place for you to learn FFI's basics, plus some tips and tricks from me and others to become a more experienced and competent Lua developer.
### A quick explanation[](https://docs.gamesense.gs/blog/tags/ffi/#a-quick-explanation "Direct link to heading")
Throughout the first section of this guide, I will be providing pseudo-C code snippets, as C comes built in with dedicated methods for certain, very important operations to us and is also the language that FFI provides an interface to, so knowledge of how it operates is completely necessary. The Lua equivalents of these operations require a more abstract thought process, as Lua does not provide explicit operations for the aforementioned functionality. I will be explaining these concepts in pseudo-C and then explaining how the same can be achieved in Lua, while calling back to earlier terminology we will have covered by then.
### What is FFI?[](https://docs.gamesense.gs/blog/tags/ffi/#what-is-ffi "Direct link to heading")
FFI - Also known (although rarely referred to) as the Foreign Function Interface - is an interface between different languages allowing them to interact with each other. FFI is generally used to create bindings to C/C++/etc libraries to higher level languages such as Python, Ruby but more importantly in our case, Lua. Bindings are just functions in the higher level languages that reach down into the lower level libraries and call their functions.
### FFI in GameSense[](https://docs.gamesense.gs/blog/tags/ffi/#ffi-in-gamesense "Direct link to heading")
In GameSense, FFI is most commonly used to provide an interface into the CS:GO processes' memory, which allows a Lua developer to interact directly with the game, such as calling functions, without relying on a middleman such as the Lua API to do all the work. Since FFI provides an interface between Lua and C, using FFI requires some knowledge about low-level memory and how low level languages like C interact with it - we will be covering this later.
Memory and how languages interact with it[](https://docs.gamesense.gs/blog/tags/ffi/#memory-and-how-languages-interact-with-it "Direct link to heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
In low-level languages such as C/C++ (I will be focusing on C as C++ provides some extra features for memory/pointer management that are far beyond the scope of this thread), memory can be interacted with directly, and all low-level/system software programming languages must provide us with a feature to do so. C provides us with a feature called pointers, these are essentially memory addresses, but ideally they will point to a specific variable, and this variable can be of any type (integer, long integer, floating point, string, even another pointer) and contain any value.
### The two types of pointers[](https://docs.gamesense.gs/blog/tags/ffi/#the-two-types-of-pointers "Direct link to heading")
The reason I said ideally in the previous paragraph is because a pointer may not always point to a variable, pointers that do not point to variable or any address are known as null pointers. This is where the divide between the two different types of pointers begins to show, they are known as SAFE and UNSAFE pointers. I will be covering safe pointers first as I find them easier to understand as there is less ambiguity, however when using FFI you will be seeing mostly unsafe pointers, however knowing how safe pointers work will make learning about unsafe pointers much easier. Below is an example of how a safe pointer is created.
float floating_point = 100.f; // Create a variable (randomly chosen float type)float* floating_pointer = &floating_point; // Create a pointer by using the & operator.
The variable floating\_pointer now points to the variable floating\_point (meaning it contains the address of the variable floating\_point). It is called a safe pointer because we can say that the variable floating\_point will always have an address in memory, and that the variable floating\_pointer will always point to that variable.
### Reading memory and dereferencing[](https://docs.gamesense.gs/blog/tags/ffi/#reading-memory-and-dereferencing "Direct link to heading")
Lets say we only have access to the variable floating\_pointer, yet we want to retrieve its value. This can be done through dereferencing. Dereferencing can be thought of like this, a pointer is a variable that references a value by memory address, and we are dereferencing the pointer to obtain its value. In other words, dereferencing is simply the act of reading the memory at the address stored in the pointer. Lets say that the address of the variable floating\_point in memory was 0x1000, and now our pointer floating\_pointer contains that value. In C we would dereference the variable using the \* operator, placing it before the variable name as such:
float original_value = *floating_pointer;
The variable original\_value will now contain 100.f.
### Unsafe pointers[](https://docs.gamesense.gs/blog/tags/ffi/#unsafe-pointers "Direct link to heading")
Unsafe pointers are a much more complex subject, hence why they're getting their own subheading. An unsafe pointer is a pointer that we cannot say for sure if it points to a value of a given type. If we were to create a pointer with the type char _(char_ is the type used for strings in C, the pointer points to the address of the first character in the string) and assign it some arbitrary address instead of an address we have retrieved from something that we know has to exist, we cannot say for sure that the address we assigned that pointer actually points to a string as we are able to give this pointer absolutely any numerical value, which may cause instability or a crash if we attempt to read from the pointer by dereferencing. Below is an example of an unsafe pointer in use.
char* our_string = (char*)0x1234;char first_character = *our_string;
This code, if compiled and ran will undoubtedly cause the application to crash as 0x1234 is almost certainly not a valid address. You can also see, that we never use the & operator that was discussed before, it is only used in the creation of safe pointers in C.
### Why unsafe pointers?[](https://docs.gamesense.gs/blog/tags/ffi/#why-unsafe-pointers "Direct link to heading")
Because of the nature of what we are doing with FFI in GameSense, we only have access to the memory, not the higher level source code abstraction that would allow us to create safe pointers. Unsafe pointers are simply a way of telling our code how to interpret a memory address. Throughout this post I have said variable, but remember that these variables can be of any type (functions, engine defined structures, custom user defined types, and basic integral types). In the Lua API, we are provided with some features that allow us to easily scan memory and retrieve important engine structures and classes, these are client.find\_signature and client.create\_interface and both of these concepts will be explored later in the upcoming section.
### A quick introduction into Memory type punning[](https://docs.gamesense.gs/blog/tags/ffi/#a-quick-introduction-into-memory-type-punning "Direct link to heading")
Type punning is the act of bypassing the type system that is implemented inside of programming languages. Type punning is more generally talked about in statically typed programming languages, not memory but although we are not dealing with the type system directly, we are dealing with the memory variables once managed by the type system. Look at this snippet from a hex editor, this was taken from a random executable file containing an XML string although this isn't important.

From this snippet, we can clearly see from the ASCII representation on the right-hand-side of the image that it is the beginning of a XML string, however if i wanted to read the first 4 bytes of this string as a 4 byte integer, I could do this:
int* int_pointer = (int*)0x405060;int first_4_bytes = *int_pointer;// This could be tied into one line.int first_4_bytes = *(int*)0x405060;
The value of the variable first\_4\_bytes is now 0x6D783F3C (notice how its just the value of each of the first 4 bytes but going backwards). The brackets and the int type name before the number is whats known as casting, im essentially telling the programming language how to interpret this memory address. This can be used on existing variables as well, given that they are numerical or are already a pointer just of a different type. This will be touched upon further in the next section. Remember! Memory is just a massive sequence of bytes, and it can be represented however you want it to, this is where a lot of the unsafety comes in.
### Pointer arithmetic[](https://docs.gamesense.gs/blog/tags/ffi/#pointer-arithmetic "Direct link to heading")
Pointer arithmetic is just like normal arithmetic like 1+2, but it takes something else into account. In all programming languages, types have size. This means that each type (byte, boolean, integer, long integer, string, floating point, etc.) have a specific size and some - like strings - can be dynamic in size. Pointer arithmetic simply takes the size of the type of the pointer into account when performing arithmetic operations (+ and -, multiplication and division are not used) on pointers. Here is an example of traversing an array using pointer arithmetic:
int our_array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};int* our_array_ptr = our_array; // Both of these are identical, but im doing this for clarity to show that our_array really is a pointer.int our_1st_value = *(our_array + 1);
You would be right in assuming that the variable our\_1st\_value now contains 1, but theres more going on behind the scenes, let me demonstrate:

This is what our array looks like in memory, notice how each value is takes up 4 bytes. This is because the size of integers in C is 4 bytes, but our numbers are so small that they only use the first byte of the 4 they are given. Remember that our\_array now contains the address 0x14001f068, and you may expect adding one to produce 0x14001f069, but remember that the next value in the array is 4 bytes away, so adding 1 really gives you 0x14001f06C as the size of the type has been taken into account.
Getting practical with FFI[](https://docs.gamesense.gs/blog/tags/ffi/#getting-practical-with-ffi "Direct link to heading")
----------------------------------------------------------------------------------------------------------------------------
In this section we will cover actually using FFI and some of the features the GameSense Lua API provides us that makes our lives a lot easier. However, before reading on I must admit that in Lua, since it is not really intended to be a low-level language it does not come built in with some features that I would like which can make things awkward sometimes, but I will be covering ways of how we achieve what we need in the second subsection.
### Getting started[](https://docs.gamesense.gs/blog/tags/ffi/#getting-started "Direct link to heading")
To actually start using FFI, you must include the library. This is done using the require keyword:
local ffi = require("ffi")
FFI can then be used as ffi.\* throughout your script. I have linked the official Lua FFI documentation, so you can refer to that for some more functionality provided that I will not be covering.
info
**NOTE:** functions such as **ffi.c** have been blocked for security reasons.
### How to achieve things in Lua[](https://docs.gamesense.gs/blog/tags/ffi/#how-to-achieve-things-in-lua "Direct link to heading")
Lua does not provide us with a dedicated operator for dereferencing pointers like C does, but we're in luck because we can treat our pointer like an array with only one element, because in memory an array is really just a pointer to the first element of the array (like strings are pointers to the first character in C). So if we wish to access the first (and only) element of our "array" we can use... \[0\]! Look at the following example:
byte our_array[5] = {0x74, 0x20, 0x62, 0x65, 0x20};
In the above snippet, we see an array getting declared and initialised with 5 elements, I have provided an example of what it would look like in memory if this was to be stored directly in data (as a global variable in a C program).

You can see that each value has been stored as a single byte, and that our\_array has been given the address 0x400060. Now as I have said before, to us, our\_array is just an array, but what really happens is it is turned into a pointer of type byte\* and trying to do certain things, such as printing this array will instead print the address of the array. Reading from the array using \[n\] simply adds n to the pointer, while taking Pointer Arithmetic into account and dereferencing, so these are all equivalent:
int first_value = *our_array; // Dereferencing will just give the first valueint first_value = our_array[0]; // Same as regular dereferencing, as we are just adding 0.
So we can imagine, that if we have a pointer it is, in memory, identical to an array containing one value, both are variables that contain an address that points to one single value, so we use \[0\] to dereference in Lua.
So now we know how to read from our pointers, but how do we create them? Well, the Lua API provided to us comes with 2 important functions that have been briefly mentioned before.
### Signatures and signature scanning[](https://docs.gamesense.gs/blog/tags/ffi/#signatures-and-signature-scanning "Direct link to heading")
Signatures are simply sequences of bytes in memory, they consist of a signature and a mask, the mask tells us which values can be wildcards (they can be any value, I'll explain why this is important later) and which must be present. The signature is the actual pattern in memory. They are most commonly represented in 2 ways, raw byte strings and IDA's style, however esoterik decided to be a cretin and use some unloved god-child mix of the two. Below are some examples of each:
IDA Style: 55 8B EC 83 E4 ? ? ? ? 53 56 57 8B F1 E8- The ?'s represent the wildcards.Code Style: \x55\x8B\xEC\x83\xE4\x00\x00\x00\x00\x53\x56\x57\x8B\xF1\xE8, xxxxx????xxxxxx- The ?'s in the second part are the wildcards.GameSense Style: \x55\x8B\xEC\x83\xE4\xCC\xCC\xCC\xCC\x53\x56\x57\x8B\xF1\xE8- The \xCC's represent the wildcards.
For IDA users, this modified version of Aidan Khoury's SigMaker can be used to create GameSense style code signatures: [SigMaker extension by infirms1337](https://gamesense.pub/forums/viewtopic.php?id=22768)
Here is a quick example of how signatures can be used to find a function: In the Source Engine, there is a function in the C\_CSPlayer class called SetAbsAngles. Now the class C\_CSPlayer gets updated a lot so therefore the index of this function (think of functions in classes like an array for now, I'll talk more about this in a future update) may change a lot so I'm going to sig this function. Using IDA or some other means, I can locate the function and use the SigMaker plugin to generate the signature `55 8B EC 83 E4 F8 83 EC 64 53 56 57 8B F1 E8`.
If we are to open client.dll in IDA and use the "search for sequence of bytes" search method and input the that signature - We will see:

This confirms that our signature is correct and will provide us with an address, but you might wonder how does this actually work? Look at this screenshot taken from IDA of the disassembly of that function:

Ignoring the actual disassembly, take a look at the numbers in grey on the left, these are the opcodes of the x86 assembly. What IDA as well as client.find\_signature will do is scan memory for the pattern you provide it, until it matches completely and it will return the address in which the first match was found, which is why you must ensure that either there is only one match for your signature, or all the matches are completely identical.
So for example, we could do this in Lua as such:
-- Specify the DLL that the signature is inside of, as well as handling an error if the signature wasn't found, this is always good practice.local signature_match = client.find_signature("client.dll", "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x64\x53\x56\x57\x8B\xF1\xE8") or error("Signature was not found")-- If everything went to plan, the address we now have in signature_match is a pointer to a function of type void(void*, float*).-- This could also be done by using ffi.cdef, but global typedefs should be avoided.local set_abs_angles = ffi.cast("void(__thiscall*)(void*, float*)", signature_match)-- You can now call set_abs_angles providing it with the correct arguments....
A lot is used here, ffi.cdef and ffi.cast will be talked about in more detail soon.
### Source engine's interface system:[](https://docs.gamesense.gs/blog/tags/ffi/#source-engines-interface-system "Direct link to heading")
The Source Engine is comprised of many different DLL's that must interact with each other, to do this, the engine has a system called interfaces. Each DLL exposes a function to other modules called CreateInterface. What this allows other modules to do is call that function and give a specific interface name, and be provided with a pointer to that class, containing all the functions it needs. As you can imagine we can do this too as anyone can call these functions. The Lua API has provided us with a quick and easy way to do this, through client.create\_interface. Interface names can be found by looking through the leaked CS:GO source code, specifically file names beginning with i such as [istudiorender.h](https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/istudiorender.h#L260)
. Working with interfaces is arguably more complex than signatures, as the structure of abstract classes is a bit more complex. The structure is as follows:
-- This ffi.cdef is put here purely for readability, still avoid using global typedefs, especially if you plan on having many users.ffi.cdef[[ typedef struct _our_interface { void** virtual_function_table; } our_interface;]]local our_interface = ffi.cast("our_interface*", _client.create_interface(...))-- If you look at the example interface I provided earlier in the Source SDK, you can see many function labelled virtual,-- these functions are stored as pointers in an array which is held in the first member of every interface, to access this-- you can do what I have done and defined a helper struct to make accessing this easier, or cast it to something like-- void** and dereference to get the address of this array.local our_virtual_function_table = our_interface.virtual_function_table-- I have defined the member virtual_function_table as void** because as I mentioned earlier, arrays are represented as pointers in memory,-- so we can access this list of functions like an array, and I have also made it an array of void*, as void* represents any pointer type.-- Lets say index 5 is a function pointer of type void(int) that we want to call.ffi.cast("void(*)(int)", our_virtual_function_table[5])(10)
@sapphyrus has just told be about some undocumented functions that the Lua API also provides to make virtual function table traversal easier, vtable\_bind and vtable\_thunk can be used to quickly attach to a VFT which isn't directly exposed, and retrieve functions from it safely and quickly:
-- Bind to the NetChannelInfo interface, which is retrieved from the GetNetChannelInfo function from the VEngineClient interface.local native_GetNetChannelInfo = vtable_bind("engine.dll", "VEngineClient014", 78, "void*(__thiscall*)(void*)")-- Generate thunks that will call the virtual function at the index provided, with the specified type.local native_GetLatency = vtable_thunk(9, "float(__thiscall*)(void*, int)")local native_GetAvgLatency = vtable_thunk(10, "float(__thiscall*)(void*, int)")-- Since GetLatency is a virtual function inside INetChannelInfo, pass the result of native_GetNetChannelInfo.native_GetLatency(native_GetNetChannelInfo(), ...)...
### Casting[](https://docs.gamesense.gs/blog/tags/ffi/#casting "Direct link to heading")
Casting is extremely useful and can be achieved through the ffi.cast function. I spoke briefly about casting earlier where I told the programming language that a number was actually meant to be interpreted as a pointer. This is the same in Lua, through the use of FFI, a number retrieved from client.find\_signature or client.create\_interface can be casted into a pointer value, allowing you to read and modify memory as you please. Some examples using ffi.cast are located below and throughout the rest of the post.
#### Some examples[](https://docs.gamesense.gs/blog/tags/ffi/#some-examples "Direct link to heading")
This example is taken from my Netvar Proxy hooking library, and it shows you how to call a function from an interface received from client.create\_interface.
-- Use client.create_interface to find the exported interface from client.dlllocal chl_client = cast("void***", client.create_interface("client.dll", "VClient018")) or error('ChlClient is nil.')-- Dereference once to get the address of the VFT, which points to the first entry.local chl_client_function_table = chl_client[0]-- Access index 8 into the function table as that is the index of the function I need.local get_all_classes = cast(ffi.typeof("ntv_ClientClass*(__thiscall*)(void*)"), chl_client_function_table[8])-- When calling virtual functions, they will always require the first parameter to be the this pointer, which is just a pointer-- To the class they belong to, like this.local client_class = get_all_classes(chl_client)
Thank you for reading! I hope this helped you to get started with FFI and begin on your journey, I will be updating this post with examples and adding more sections in the future about more complex ideas and abstractions of memory that are commonly used in FFI development with GameSense such as safe pointers in Lua through FFI, as well as independent reverse engineering methods to help you keep yourself up to date, instead of relying on others. Stay tuned!
Further reading[](https://docs.gamesense.gs/blog/tags/ffi/#further-reading "Direct link to heading")
------------------------------------------------------------------------------------------------------
* [C Typedefs](https://en.wikipedia.org/wiki/Typedef)
* [FFI Documentation](https://luajit.org/ext_ffi.html)
* [Official FFI tutorial](https://luajit.org/ext_ffi_tutorial.html)
---
# Welcome to the blog! | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/blog/welcome/#docusaurus_skipToContent_fallback)
Welcome to the blog section of the docs!
Here you will find guides and other useful tutorials and posts that can further enhance your understanding of the GameSense API and potentially make you more creative.
**Want to share your knowledge for others to see and read?**
Open a pull request on [GitHub](https://github.com/gamesensical/docs)
with your post in a markdown-formatted file. Use the blog posts that already exist as an example of how to format your markdown files, and how to name them.
---
# Search the documentation | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/search/#docusaurus_skipToContent_fallback)
Search the documentation
========================
[](https://www.algolia.com/)
---
# One post tagged with "guide" | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/blog/tags/guide/#docusaurus_skipToContent_fallback)
Hello! I have decided to write an in-depth FFI crash course to provide a place for anyone regardless of your experience to learn without looking through the dozens of possibly confusing scripts released here on the forum, which are generally undocumented and some are quite complex. This guide will act as a place for you to learn FFI's basics, plus some tips and tricks from me and others to become a more experienced and competent Lua developer.
### A quick explanation[](https://docs.gamesense.gs/blog/tags/guide/#a-quick-explanation "Direct link to heading")
Throughout the first section of this guide, I will be providing pseudo-C code snippets, as C comes built in with dedicated methods for certain, very important operations to us and is also the language that FFI provides an interface to, so knowledge of how it operates is completely necessary. The Lua equivalents of these operations require a more abstract thought process, as Lua does not provide explicit operations for the aforementioned functionality. I will be explaining these concepts in pseudo-C and then explaining how the same can be achieved in Lua, while calling back to earlier terminology we will have covered by then.
### What is FFI?[](https://docs.gamesense.gs/blog/tags/guide/#what-is-ffi "Direct link to heading")
FFI - Also known (although rarely referred to) as the Foreign Function Interface - is an interface between different languages allowing them to interact with each other. FFI is generally used to create bindings to C/C++/etc libraries to higher level languages such as Python, Ruby but more importantly in our case, Lua. Bindings are just functions in the higher level languages that reach down into the lower level libraries and call their functions.
### FFI in GameSense[](https://docs.gamesense.gs/blog/tags/guide/#ffi-in-gamesense "Direct link to heading")
In GameSense, FFI is most commonly used to provide an interface into the CS:GO processes' memory, which allows a Lua developer to interact directly with the game, such as calling functions, without relying on a middleman such as the Lua API to do all the work. Since FFI provides an interface between Lua and C, using FFI requires some knowledge about low-level memory and how low level languages like C interact with it - we will be covering this later.
Memory and how languages interact with it[](https://docs.gamesense.gs/blog/tags/guide/#memory-and-how-languages-interact-with-it "Direct link to heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
In low-level languages such as C/C++ (I will be focusing on C as C++ provides some extra features for memory/pointer management that are far beyond the scope of this thread), memory can be interacted with directly, and all low-level/system software programming languages must provide us with a feature to do so. C provides us with a feature called pointers, these are essentially memory addresses, but ideally they will point to a specific variable, and this variable can be of any type (integer, long integer, floating point, string, even another pointer) and contain any value.
### The two types of pointers[](https://docs.gamesense.gs/blog/tags/guide/#the-two-types-of-pointers "Direct link to heading")
The reason I said ideally in the previous paragraph is because a pointer may not always point to a variable, pointers that do not point to variable or any address are known as null pointers. This is where the divide between the two different types of pointers begins to show, they are known as SAFE and UNSAFE pointers. I will be covering safe pointers first as I find them easier to understand as there is less ambiguity, however when using FFI you will be seeing mostly unsafe pointers, however knowing how safe pointers work will make learning about unsafe pointers much easier. Below is an example of how a safe pointer is created.
float floating_point = 100.f; // Create a variable (randomly chosen float type)float* floating_pointer = &floating_point; // Create a pointer by using the & operator.
The variable floating\_pointer now points to the variable floating\_point (meaning it contains the address of the variable floating\_point). It is called a safe pointer because we can say that the variable floating\_point will always have an address in memory, and that the variable floating\_pointer will always point to that variable.
### Reading memory and dereferencing[](https://docs.gamesense.gs/blog/tags/guide/#reading-memory-and-dereferencing "Direct link to heading")
Lets say we only have access to the variable floating\_pointer, yet we want to retrieve its value. This can be done through dereferencing. Dereferencing can be thought of like this, a pointer is a variable that references a value by memory address, and we are dereferencing the pointer to obtain its value. In other words, dereferencing is simply the act of reading the memory at the address stored in the pointer. Lets say that the address of the variable floating\_point in memory was 0x1000, and now our pointer floating\_pointer contains that value. In C we would dereference the variable using the \* operator, placing it before the variable name as such:
float original_value = *floating_pointer;
The variable original\_value will now contain 100.f.
### Unsafe pointers[](https://docs.gamesense.gs/blog/tags/guide/#unsafe-pointers "Direct link to heading")
Unsafe pointers are a much more complex subject, hence why they're getting their own subheading. An unsafe pointer is a pointer that we cannot say for sure if it points to a value of a given type. If we were to create a pointer with the type char _(char_ is the type used for strings in C, the pointer points to the address of the first character in the string) and assign it some arbitrary address instead of an address we have retrieved from something that we know has to exist, we cannot say for sure that the address we assigned that pointer actually points to a string as we are able to give this pointer absolutely any numerical value, which may cause instability or a crash if we attempt to read from the pointer by dereferencing. Below is an example of an unsafe pointer in use.
char* our_string = (char*)0x1234;char first_character = *our_string;
This code, if compiled and ran will undoubtedly cause the application to crash as 0x1234 is almost certainly not a valid address. You can also see, that we never use the & operator that was discussed before, it is only used in the creation of safe pointers in C.
### Why unsafe pointers?[](https://docs.gamesense.gs/blog/tags/guide/#why-unsafe-pointers "Direct link to heading")
Because of the nature of what we are doing with FFI in GameSense, we only have access to the memory, not the higher level source code abstraction that would allow us to create safe pointers. Unsafe pointers are simply a way of telling our code how to interpret a memory address. Throughout this post I have said variable, but remember that these variables can be of any type (functions, engine defined structures, custom user defined types, and basic integral types). In the Lua API, we are provided with some features that allow us to easily scan memory and retrieve important engine structures and classes, these are client.find\_signature and client.create\_interface and both of these concepts will be explored later in the upcoming section.
### A quick introduction into Memory type punning[](https://docs.gamesense.gs/blog/tags/guide/#a-quick-introduction-into-memory-type-punning "Direct link to heading")
Type punning is the act of bypassing the type system that is implemented inside of programming languages. Type punning is more generally talked about in statically typed programming languages, not memory but although we are not dealing with the type system directly, we are dealing with the memory variables once managed by the type system. Look at this snippet from a hex editor, this was taken from a random executable file containing an XML string although this isn't important.

From this snippet, we can clearly see from the ASCII representation on the right-hand-side of the image that it is the beginning of a XML string, however if i wanted to read the first 4 bytes of this string as a 4 byte integer, I could do this:
int* int_pointer = (int*)0x405060;int first_4_bytes = *int_pointer;// This could be tied into one line.int first_4_bytes = *(int*)0x405060;
The value of the variable first\_4\_bytes is now 0x6D783F3C (notice how its just the value of each of the first 4 bytes but going backwards). The brackets and the int type name before the number is whats known as casting, im essentially telling the programming language how to interpret this memory address. This can be used on existing variables as well, given that they are numerical or are already a pointer just of a different type. This will be touched upon further in the next section. Remember! Memory is just a massive sequence of bytes, and it can be represented however you want it to, this is where a lot of the unsafety comes in.
### Pointer arithmetic[](https://docs.gamesense.gs/blog/tags/guide/#pointer-arithmetic "Direct link to heading")
Pointer arithmetic is just like normal arithmetic like 1+2, but it takes something else into account. In all programming languages, types have size. This means that each type (byte, boolean, integer, long integer, string, floating point, etc.) have a specific size and some - like strings - can be dynamic in size. Pointer arithmetic simply takes the size of the type of the pointer into account when performing arithmetic operations (+ and -, multiplication and division are not used) on pointers. Here is an example of traversing an array using pointer arithmetic:
int our_array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};int* our_array_ptr = our_array; // Both of these are identical, but im doing this for clarity to show that our_array really is a pointer.int our_1st_value = *(our_array + 1);
You would be right in assuming that the variable our\_1st\_value now contains 1, but theres more going on behind the scenes, let me demonstrate:

This is what our array looks like in memory, notice how each value is takes up 4 bytes. This is because the size of integers in C is 4 bytes, but our numbers are so small that they only use the first byte of the 4 they are given. Remember that our\_array now contains the address 0x14001f068, and you may expect adding one to produce 0x14001f069, but remember that the next value in the array is 4 bytes away, so adding 1 really gives you 0x14001f06C as the size of the type has been taken into account.
Getting practical with FFI[](https://docs.gamesense.gs/blog/tags/guide/#getting-practical-with-ffi "Direct link to heading")
------------------------------------------------------------------------------------------------------------------------------
In this section we will cover actually using FFI and some of the features the GameSense Lua API provides us that makes our lives a lot easier. However, before reading on I must admit that in Lua, since it is not really intended to be a low-level language it does not come built in with some features that I would like which can make things awkward sometimes, but I will be covering ways of how we achieve what we need in the second subsection.
### Getting started[](https://docs.gamesense.gs/blog/tags/guide/#getting-started "Direct link to heading")
To actually start using FFI, you must include the library. This is done using the require keyword:
local ffi = require("ffi")
FFI can then be used as ffi.\* throughout your script. I have linked the official Lua FFI documentation, so you can refer to that for some more functionality provided that I will not be covering.
info
**NOTE:** functions such as **ffi.c** have been blocked for security reasons.
### How to achieve things in Lua[](https://docs.gamesense.gs/blog/tags/guide/#how-to-achieve-things-in-lua "Direct link to heading")
Lua does not provide us with a dedicated operator for dereferencing pointers like C does, but we're in luck because we can treat our pointer like an array with only one element, because in memory an array is really just a pointer to the first element of the array (like strings are pointers to the first character in C). So if we wish to access the first (and only) element of our "array" we can use... \[0\]! Look at the following example:
byte our_array[5] = {0x74, 0x20, 0x62, 0x65, 0x20};
In the above snippet, we see an array getting declared and initialised with 5 elements, I have provided an example of what it would look like in memory if this was to be stored directly in data (as a global variable in a C program).

You can see that each value has been stored as a single byte, and that our\_array has been given the address 0x400060. Now as I have said before, to us, our\_array is just an array, but what really happens is it is turned into a pointer of type byte\* and trying to do certain things, such as printing this array will instead print the address of the array. Reading from the array using \[n\] simply adds n to the pointer, while taking Pointer Arithmetic into account and dereferencing, so these are all equivalent:
int first_value = *our_array; // Dereferencing will just give the first valueint first_value = our_array[0]; // Same as regular dereferencing, as we are just adding 0.
So we can imagine, that if we have a pointer it is, in memory, identical to an array containing one value, both are variables that contain an address that points to one single value, so we use \[0\] to dereference in Lua.
So now we know how to read from our pointers, but how do we create them? Well, the Lua API provided to us comes with 2 important functions that have been briefly mentioned before.
### Signatures and signature scanning[](https://docs.gamesense.gs/blog/tags/guide/#signatures-and-signature-scanning "Direct link to heading")
Signatures are simply sequences of bytes in memory, they consist of a signature and a mask, the mask tells us which values can be wildcards (they can be any value, I'll explain why this is important later) and which must be present. The signature is the actual pattern in memory. They are most commonly represented in 2 ways, raw byte strings and IDA's style, however esoterik decided to be a cretin and use some unloved god-child mix of the two. Below are some examples of each:
IDA Style: 55 8B EC 83 E4 ? ? ? ? 53 56 57 8B F1 E8- The ?'s represent the wildcards.Code Style: \x55\x8B\xEC\x83\xE4\x00\x00\x00\x00\x53\x56\x57\x8B\xF1\xE8, xxxxx????xxxxxx- The ?'s in the second part are the wildcards.GameSense Style: \x55\x8B\xEC\x83\xE4\xCC\xCC\xCC\xCC\x53\x56\x57\x8B\xF1\xE8- The \xCC's represent the wildcards.
For IDA users, this modified version of Aidan Khoury's SigMaker can be used to create GameSense style code signatures: [SigMaker extension by infirms1337](https://gamesense.pub/forums/viewtopic.php?id=22768)
Here is a quick example of how signatures can be used to find a function: In the Source Engine, there is a function in the C\_CSPlayer class called SetAbsAngles. Now the class C\_CSPlayer gets updated a lot so therefore the index of this function (think of functions in classes like an array for now, I'll talk more about this in a future update) may change a lot so I'm going to sig this function. Using IDA or some other means, I can locate the function and use the SigMaker plugin to generate the signature `55 8B EC 83 E4 F8 83 EC 64 53 56 57 8B F1 E8`.
If we are to open client.dll in IDA and use the "search for sequence of bytes" search method and input the that signature - We will see:

This confirms that our signature is correct and will provide us with an address, but you might wonder how does this actually work? Look at this screenshot taken from IDA of the disassembly of that function:

Ignoring the actual disassembly, take a look at the numbers in grey on the left, these are the opcodes of the x86 assembly. What IDA as well as client.find\_signature will do is scan memory for the pattern you provide it, until it matches completely and it will return the address in which the first match was found, which is why you must ensure that either there is only one match for your signature, or all the matches are completely identical.
So for example, we could do this in Lua as such:
-- Specify the DLL that the signature is inside of, as well as handling an error if the signature wasn't found, this is always good practice.local signature_match = client.find_signature("client.dll", "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x64\x53\x56\x57\x8B\xF1\xE8") or error("Signature was not found")-- If everything went to plan, the address we now have in signature_match is a pointer to a function of type void(void*, float*).-- This could also be done by using ffi.cdef, but global typedefs should be avoided.local set_abs_angles = ffi.cast("void(__thiscall*)(void*, float*)", signature_match)-- You can now call set_abs_angles providing it with the correct arguments....
A lot is used here, ffi.cdef and ffi.cast will be talked about in more detail soon.
### Source engine's interface system:[](https://docs.gamesense.gs/blog/tags/guide/#source-engines-interface-system "Direct link to heading")
The Source Engine is comprised of many different DLL's that must interact with each other, to do this, the engine has a system called interfaces. Each DLL exposes a function to other modules called CreateInterface. What this allows other modules to do is call that function and give a specific interface name, and be provided with a pointer to that class, containing all the functions it needs. As you can imagine we can do this too as anyone can call these functions. The Lua API has provided us with a quick and easy way to do this, through client.create\_interface. Interface names can be found by looking through the leaked CS:GO source code, specifically file names beginning with i such as [istudiorender.h](https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/istudiorender.h#L260)
. Working with interfaces is arguably more complex than signatures, as the structure of abstract classes is a bit more complex. The structure is as follows:
-- This ffi.cdef is put here purely for readability, still avoid using global typedefs, especially if you plan on having many users.ffi.cdef[[ typedef struct _our_interface { void** virtual_function_table; } our_interface;]]local our_interface = ffi.cast("our_interface*", _client.create_interface(...))-- If you look at the example interface I provided earlier in the Source SDK, you can see many function labelled virtual,-- these functions are stored as pointers in an array which is held in the first member of every interface, to access this-- you can do what I have done and defined a helper struct to make accessing this easier, or cast it to something like-- void** and dereference to get the address of this array.local our_virtual_function_table = our_interface.virtual_function_table-- I have defined the member virtual_function_table as void** because as I mentioned earlier, arrays are represented as pointers in memory,-- so we can access this list of functions like an array, and I have also made it an array of void*, as void* represents any pointer type.-- Lets say index 5 is a function pointer of type void(int) that we want to call.ffi.cast("void(*)(int)", our_virtual_function_table[5])(10)
@sapphyrus has just told be about some undocumented functions that the Lua API also provides to make virtual function table traversal easier, vtable\_bind and vtable\_thunk can be used to quickly attach to a VFT which isn't directly exposed, and retrieve functions from it safely and quickly:
-- Bind to the NetChannelInfo interface, which is retrieved from the GetNetChannelInfo function from the VEngineClient interface.local native_GetNetChannelInfo = vtable_bind("engine.dll", "VEngineClient014", 78, "void*(__thiscall*)(void*)")-- Generate thunks that will call the virtual function at the index provided, with the specified type.local native_GetLatency = vtable_thunk(9, "float(__thiscall*)(void*, int)")local native_GetAvgLatency = vtable_thunk(10, "float(__thiscall*)(void*, int)")-- Since GetLatency is a virtual function inside INetChannelInfo, pass the result of native_GetNetChannelInfo.native_GetLatency(native_GetNetChannelInfo(), ...)...
### Casting[](https://docs.gamesense.gs/blog/tags/guide/#casting "Direct link to heading")
Casting is extremely useful and can be achieved through the ffi.cast function. I spoke briefly about casting earlier where I told the programming language that a number was actually meant to be interpreted as a pointer. This is the same in Lua, through the use of FFI, a number retrieved from client.find\_signature or client.create\_interface can be casted into a pointer value, allowing you to read and modify memory as you please. Some examples using ffi.cast are located below and throughout the rest of the post.
#### Some examples[](https://docs.gamesense.gs/blog/tags/guide/#some-examples "Direct link to heading")
This example is taken from my Netvar Proxy hooking library, and it shows you how to call a function from an interface received from client.create\_interface.
-- Use client.create_interface to find the exported interface from client.dlllocal chl_client = cast("void***", client.create_interface("client.dll", "VClient018")) or error('ChlClient is nil.')-- Dereference once to get the address of the VFT, which points to the first entry.local chl_client_function_table = chl_client[0]-- Access index 8 into the function table as that is the index of the function I need.local get_all_classes = cast(ffi.typeof("ntv_ClientClass*(__thiscall*)(void*)"), chl_client_function_table[8])-- When calling virtual functions, they will always require the first parameter to be the this pointer, which is just a pointer-- To the class they belong to, like this.local client_class = get_all_classes(chl_client)
Thank you for reading! I hope this helped you to get started with FFI and begin on your journey, I will be updating this post with examples and adding more sections in the future about more complex ideas and abstractions of memory that are commonly used in FFI development with GameSense such as safe pointers in Lua through FFI, as well as independent reverse engineering methods to help you keep yourself up to date, instead of relying on others. Stay tuned!
Further reading[](https://docs.gamesense.gs/blog/tags/guide/#further-reading "Direct link to heading")
--------------------------------------------------------------------------------------------------------
* [C Typedefs](https://en.wikipedia.org/wiki/Typedef)
* [FFI Documentation](https://luajit.org/ext_ffi.html)
* [Official FFI tutorial](https://luajit.org/ext_ffi_tutorial.html)
---
# bit.arshift | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/arshift/#docusaurus_skipToContent_fallback)
On this page
bit.arshift
===========
Returns the bitwise arithmetic right-shift of its first argument by the number of bits given by the second argument. Arithmetic right-shift treats the most-significant bit as a sign bit and replicates it. Only the lower 5 bits of the shift count are used (reduces to the range \[0..31\]).
bit.arshift(x: number, n: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/arshift/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Value | number |
| n | Number of bits to shift by | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/arshift/#arguments)
---
# bit.bor | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/bor/#docusaurus_skipToContent_fallback)
On this page
bit.bor
=======
Returns the bitwise or of all of its arguments. Note that more than two arguments are allowed.
bit.bor(x1: number, ...): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/bor/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x1 | N/A | number |
| x2 | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/bor/#arguments)
---
# bit.bnot | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/bnot/#docusaurus_skipToContent_fallback)
On this page
bit.bnot
========
Returns the bitwise not of its argument (all bits flipped).
bit.bnot(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/bnot/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/bnot/#arguments)
---
# bit.band | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/band/#docusaurus_skipToContent_fallback)
On this page
bit.band
========
Returns the bitwise and of all of its arguments. Note that more than two arguments are allowed.
bit.band(x1: number, ...): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/band/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x1 | N/A | number |
| x2 | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/band/#arguments)
---
# bit.rol | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/rol/#docusaurus_skipToContent_fallback)
On this page
bit.rol
=======
Returns the bitwise left rotation of its first argument by the number of bits given by the second argument. Bits shifted out on one side are shifted back in on the other side. Only the lower 5 bits of the rotate count are used (reduces to the range \[0..31\]).
bit.rol(x: number, n: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/rol/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Value | number |
| n | Number of bits to rotate by | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/rol/#arguments)
---
# bit.bswap | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/bswap/#docusaurus_skipToContent_fallback)
On this page
bit.bswap
=========
Swaps the bytes of its argument and returns it. This can be used to convert little-endian 32 bit numbers to big-endian 32 bit numbers or vice versa.
bit.bswap(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/bswap/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/bswap/#arguments)
---
# bit.lshift | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/lshift/#docusaurus_skipToContent_fallback)
On this page
bit.lshift
==========
Returns the bitwise logical left-shift of its first argument by the number of bits given by the second argument. Logical shifts treat the first argument as an unsigned number and shift in 0-bits. Only the lower 5 bits of the shift count are used (reduces to the range \[0..31\]).
bit.lshift(x: number, n: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/lshift/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Value | number |
| n | Number of bits to shift by | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/lshift/#arguments)
---
# Getting Started | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/#docusaurus_skipToContent_fallback)
Getting Started
===============
The API comes with the following namespaces. You can think of them as categories for functions.
* [Global Functions](https://docs.gamesense.gs/docs/api/globalFuncs)
- API functions that don't belong to any namespaces
* [bit](https://docs.gamesense.gs/docs/api/bit)
- LuaJIT library for bitwise operations
* [client](https://docs.gamesense.gs/docs/api/client)
- General game and cheat-related functions
* [config](https://docs.gamesense.gs/docs/api/config)
- GameSense configuration functions
* [cvar](https://docs.gamesense.gs/docs/api/cvar)
- Utilities for working with game cvars
* [database](https://docs.gamesense.gs/docs/api/database)
- A persistent storage engine that lets you store values between reloads and injects
* [entity](https://docs.gamesense.gs/docs/api/entity)
- Functions for interacting with game entities
* [globals](https://docs.gamesense.gs/docs/api/globals)
- Functions for getting game and cheat-related globals
* [json](https://docs.gamesense.gs/docs/api/json)
- Utilities for working with JSON data, based on lua-cjson
* [materialsystem](https://docs.gamesense.gs/docs/api/materialsystem)
- Functions controlling the games material system, such as modulation, swapping, removing and setting
* [panorama](https://docs.gamesense.gs/docs/api/panorama)
- Functions for interacting with the game engine "Panorama" UI
* [plist](https://docs.gamesense.gs/docs/api/plist)
- Functions for interacting with the player list
* [renderer](https://docs.gamesense.gs/docs/api/renderer)
- A library of functions for drawing and interacting with rendered visuals
* [ui](https://docs.gamesense.gs/docs/api/ui)
- Functions for interfacing with the GameSense user interface
* [vector](https://docs.gamesense.gs/docs/api/vector)
- A built-in vector library
---
# bit.bxor | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/bxor/#docusaurus_skipToContent_fallback)
On this page
bit.bxor
========
Returns the bitwise xor of all of its arguments. Note that more than two arguments are allowed.
bit.bxor(x1: number, ...): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/bxor/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x1 | N/A | number |
| x2 | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/bxor/#arguments)
---
# bit.ror | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/ror/#docusaurus_skipToContent_fallback)
On this page
bit.ror
=======
Returns the bitwise right rotation of its first argument by the number of bits given by the second argument. Bits shifted out on one side are shifted back in on the other side. Only the lower 5 bits of the rotate count are used (reduces to the range \[0..31\]).
bit.ror(x: number, n: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/ror/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Value | number |
| n | Number of bits to rotate by | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/ror/#arguments)
---
# bit.rshift | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/rshift/#docusaurus_skipToContent_fallback)
On this page
bit.rshift
==========
Returns the bitwise logical right-shift of its first argument by the number of bits given by the second argument. Logical shifts treat the first argument as an unsigned number and shift in 0-bits. Only the lower 5 bits of the shift count are used (reduces to the range \[0..31\]).
bit.rshift(x: number, n: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/rshift/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Value | number |
| n | Number of bits to shift by | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/rshift/#arguments)
---
# bit.tohex | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/tohex/#docusaurus_skipToContent_fallback)
On this page
bit.tohex
=========
Converts its first argument to a hex string. The number of hex digits is given by the absolute value of the optional second argument. Positive numbers between 1 and 8 generate lowercase hex digits. Negative numbers generate uppercase hex digits. Only the least-significant 4\*|n| bits are used. The default is to generate 8 lowercase hex digits.
bit.tohex(x: number, n: number): string
Arguments[](https://docs.gamesense.gs/docs/api/bit/tohex/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Value to convert | number |
| n | Amount of hex digits to return | number |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/tohex/#arguments)
---
# bit.tobit | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/tobit/#docusaurus_skipToContent_fallback)
On this page
bit.tobit
=========
Normalizes a number to the numeric range for bit operations and returns it. This function is usually not needed since all bit operations already normalize all of their input arguments.
bit.tobit(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/bit/tobit/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/bit/tobit/#arguments)
---
# client.camera_angles | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/cameraangles/#docusaurus_skipToContent_fallback)
On this page
client.camera\_angles
=====================
Get or set camera angles. Pass no arguments to get the current camera angles.
client.camera_angles(pitch: number, yaw: number): number, number
Arguments[](https://docs.gamesense.gs/docs/api/client/cameraangles/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| pitch | Pitch angle in degrees (-90 to 90) | number |
| yaw | Yaw angle in degrees (-180 to 180) | number |
Returns `pitch: number, yaw: number`
* [Arguments](https://docs.gamesense.gs/docs/api/client/cameraangles/#arguments)
---
# client.camera_position | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/cameraposition/#docusaurus_skipToContent_fallback)
client.camera\_position
=======================
Returns x, y, z world coordinates of the game's camera position.
client.camera_position(): number, number, number
Returns `x: number, y: number, z: number`
---
# client.create_interface | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/createinterface/#docusaurus_skipToContent_fallback)
On this page
client.create\_interface
========================
Returns a pointer to the interface, or nil on failure.
client.create_interface(module_name: string, interface_name: string): userdata
Arguments[](https://docs.gamesense.gs/docs/api/client/createinterface/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| module\_name | Filename of the module that contains the interface | string |
| interface\_name | Name of the interface | string |
Returns `interface: userdata`
* [Arguments](https://docs.gamesense.gs/docs/api/client/createinterface/#arguments)
---
# client.color_log | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/colorlog/#docusaurus_skipToContent_fallback)
On this page
client.color\_log
=================
Logs a colored message to console. End the string with \\0 to prevent it from adding a newline.
client.color_log(r: number, g: number, b: number, ...)
Arguments[](https://docs.gamesense.gs/docs/api/client/colorlog/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| msg | The message to be logged. Pass additional arguments to concatenate them to the message. | string |
* [Arguments](https://docs.gamesense.gs/docs/api/client/colorlog/#arguments)
---
# bit | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/bit/#docusaurus_skipToContent_fallback)
On this page
bit
===
Description[](https://docs.gamesense.gs/docs/api/bit/#description "Direct link to heading")
---------------------------------------------------------------------------------------------
LuaJIT library for bitwise operations
Functions[](https://docs.gamesense.gs/docs/api/bit/#functions "Direct link to heading")
-----------------------------------------------------------------------------------------
### arshift[](https://docs.gamesense.gs/docs/api/bit/#arshift "Direct link to heading")
[bit.arshift(x: number, n: number): number](https://docs.gamesense.gs/docs/api/bit/arshift)
> Returns the bitwise arithmetic right-shift of its first argument by the number of bits given by the second argument. Arithmetic right-shift treats the most-significant bit as a sign bit and replicates it. Only the lower 5 bits of the shift count are used (reduces to the range \[0..31\]).
### band[](https://docs.gamesense.gs/docs/api/bit/#band "Direct link to heading")
[bit.band(x1: number, ...): number](https://docs.gamesense.gs/docs/api/bit/band)
> Returns the bitwise and of all of its arguments. Note that more than two arguments are allowed.
### bnot[](https://docs.gamesense.gs/docs/api/bit/#bnot "Direct link to heading")
[bit.bnot(x: number): number](https://docs.gamesense.gs/docs/api/bit/bnot)
> Returns the bitwise not of its argument (all bits flipped).
### bor[](https://docs.gamesense.gs/docs/api/bit/#bor "Direct link to heading")
[bit.bor(x1: number, ...): number](https://docs.gamesense.gs/docs/api/bit/bor)
> Returns the bitwise or of all of its arguments. Note that more than two arguments are allowed.
### bswap[](https://docs.gamesense.gs/docs/api/bit/#bswap "Direct link to heading")
[bit.bswap(x: number): number](https://docs.gamesense.gs/docs/api/bit/bswap)
> Swaps the bytes of its argument and returns it. This can be used to convert little-endian 32 bit numbers to big-endian 32 bit numbers or vice versa.
### bxor[](https://docs.gamesense.gs/docs/api/bit/#bxor "Direct link to heading")
[bit.bxor(x1: number, ...): number](https://docs.gamesense.gs/docs/api/bit/bxor)
> Returns the bitwise xor of all of its arguments. Note that more than two arguments are allowed.
### lshift[](https://docs.gamesense.gs/docs/api/bit/#lshift "Direct link to heading")
[bit.lshift(x: number, n: number): number](https://docs.gamesense.gs/docs/api/bit/lshift)
> Returns the bitwise logical left-shift of its first argument by the number of bits given by the second argument. Logical shifts treat the first argument as an unsigned number and shift in 0-bits. Only the lower 5 bits of the shift count are used (reduces to the range \[0..31\]).
### rol[](https://docs.gamesense.gs/docs/api/bit/#rol "Direct link to heading")
[bit.rol(x: number, n: number): number](https://docs.gamesense.gs/docs/api/bit/rol)
> Returns the bitwise left rotation of its first argument by the number of bits given by the second argument. Bits shifted out on one side are shifted back in on the other side. Only the lower 5 bits of the rotate count are used (reduces to the range \[0..31\]).
### ror[](https://docs.gamesense.gs/docs/api/bit/#ror "Direct link to heading")
[bit.ror(x: number, n: number): number](https://docs.gamesense.gs/docs/api/bit/ror)
> Returns the bitwise right rotation of its first argument by the number of bits given by the second argument. Bits shifted out on one side are shifted back in on the other side. Only the lower 5 bits of the rotate count are used (reduces to the range \[0..31\]).
### rshift[](https://docs.gamesense.gs/docs/api/bit/#rshift "Direct link to heading")
[bit.rshift(x: number, n: number): number](https://docs.gamesense.gs/docs/api/bit/rshift)
> Returns the bitwise logical right-shift of its first argument by the number of bits given by the second argument. Logical shifts treat the first argument as an unsigned number and shift in 0-bits. Only the lower 5 bits of the shift count are used (reduces to the range \[0..31\]).
### tobit[](https://docs.gamesense.gs/docs/api/bit/#tobit "Direct link to heading")
[bit.tobit(x: number): number](https://docs.gamesense.gs/docs/api/bit/tobit)
> Normalizes a number to the numeric range for bit operations and returns it. This function is usually not needed since all bit operations already normalize all of their input arguments.
### tohex[](https://docs.gamesense.gs/docs/api/bit/#tohex "Direct link to heading")
[bit.tohex(x: number, n: number): string](https://docs.gamesense.gs/docs/api/bit/tohex)
> Converts its first argument to a hex string. The number of hex digits is given by the absolute value of the optional second argument. Positive numbers between 1 and 8 generate lowercase hex digits. Negative numbers generate uppercase hex digits. Only the least-significant 4\*|n| bits are used. The default is to generate 8 lowercase hex digits.
* [Description](https://docs.gamesense.gs/docs/api/bit/#description)
* [Functions](https://docs.gamesense.gs/docs/api/bit/#functions)
* [arshift](https://docs.gamesense.gs/docs/api/bit/#arshift)
* [band](https://docs.gamesense.gs/docs/api/bit/#band)
* [bnot](https://docs.gamesense.gs/docs/api/bit/#bnot)
* [bor](https://docs.gamesense.gs/docs/api/bit/#bor)
* [bswap](https://docs.gamesense.gs/docs/api/bit/#bswap)
* [bxor](https://docs.gamesense.gs/docs/api/bit/#bxor)
* [lshift](https://docs.gamesense.gs/docs/api/bit/#lshift)
* [rol](https://docs.gamesense.gs/docs/api/bit/#rol)
* [ror](https://docs.gamesense.gs/docs/api/bit/#ror)
* [rshift](https://docs.gamesense.gs/docs/api/bit/#rshift)
* [tobit](https://docs.gamesense.gs/docs/api/bit/#tobit)
* [tohex](https://docs.gamesense.gs/docs/api/bit/#tohex)
---
# client.current_threat | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/currentthreat/#docusaurus_skipToContent_fallback)
client.current\_threat
======================
Returns the entindex of the 'current threat', i.e. the enemy that is currently being used for 'At targets' anti-aim.
client.current_threat(): number
Returns `number`
---
# client.delay_call | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/delaycall/#docusaurus_skipToContent_fallback)
On this page
client.delay\_call
==================
Executes the callback after delay seconds, passing the arguments to it.
client.delay_call(delay: number, callback, ...)
Arguments[](https://docs.gamesense.gs/docs/api/client/delaycall/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| delay | Time in seconds to wait before calling callback. | number |
| callback | The lua function that will be called after delay seconds. | function |
| args | Arguments that will be passed to the callback. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/client/delaycall/#arguments)
---
# client.error_log | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/errorlog/#docusaurus_skipToContent_fallback)
On this page
client.error\_log
=================
Prints an error to the console and plays a sound.
client.error_log(msg: string)
Arguments[](https://docs.gamesense.gs/docs/api/client/errorlog/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| msg | The error message | string |
* [Arguments](https://docs.gamesense.gs/docs/api/client/errorlog/#arguments)
---
# client.draw_debug_text | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/drawdebugtext/#docusaurus_skipToContent_fallback)
On this page
client.draw\_debug\_text
========================
Draws a DebugOverlay text at the specified 3d position. Avoid calling this during the paint event.
client.draw_debug_text(x: number, y: number, z: number, line_offset: number, duration: number, r: number, g: number, b: number, a: number, ...)
Arguments[](https://docs.gamesense.gs/docs/api/client/drawdebugtext/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | X coordinate | number |
| y | Y coordinate | number |
| z | Z coordinate | number |
| line\_offset | Used for vertical alignment, use 0 for the first line. | number |
| duration | Time in seconds that the text will remain on the screen. | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
| text | The text that will be drawn | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/client/drawdebugtext/#arguments)
---
# client.eye_position | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/eyeposition/#docusaurus_skipToContent_fallback)
client.eye\_position
====================
Returns x, y, z world coordinates of the local player's eye position.
client.eye_position(): number, number, number
Returns `x: number, y: number, z: number`
---
# client.exec | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/exec/#docusaurus_skipToContent_fallback)
On this page
client.exec
===========
Executes a console command. Multiple commands can be combined with ';'. Be careful when passing user input (including player names) to it.
client.exec(...)
Arguments[](https://docs.gamesense.gs/docs/api/client/exec/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| cmd | The console command(s) to execute. Additional arguments will be concatenated. | string |
* [Arguments](https://docs.gamesense.gs/docs/api/client/exec/#arguments)
---
# client.draw_hitboxes | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/drawhitboxes/#docusaurus_skipToContent_fallback)
On this page
client.draw\_hitboxes
=====================
Draws hitbox overlays. Avoid calling this during the paint event.
client.draw_hitboxes(entindex: number, duration: number, hitboxes: number, r: number, g: number, b: number, a: number, tick: number)
Arguments[](https://docs.gamesense.gs/docs/api/client/drawhitboxes/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| entindex | Entity index of the player | number |
| duration | Time in seconds | number |
| hitboxes | Either the [hitbox index](https://docs.gamesense.gs/constants/hitboxes)
or 19 for all hitboxes | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
| tick | Tick to draw the hitboxes for | number |
* [Arguments](https://docs.gamesense.gs/docs/api/client/drawhitboxes/#arguments)
---
# client.find_signature | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/findsignature/#docusaurus_skipToContent_fallback)
On this page
client.find\_signature
======================
Finds the specified pattern and returns a pointer to it, or nil if not found.
client.find_signature(module_name: string, pattern: string): userdata
Arguments[](https://docs.gamesense.gs/docs/api/client/findsignature/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| module\_name | Filename of the module that contains the interface | string |
| pattern | String of the signature. Escape with `\x`, replace wildcards with `\xCC`. | string |
Returns `match: userdata`
* [Arguments](https://docs.gamesense.gs/docs/api/client/findsignature/#arguments)
---
# client.fire_event | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/fireevent/#docusaurus_skipToContent_fallback)
On this page
client.fire\_event
==================
Fires a custom event that other scripts can listen to using [client.set\_event\_callback](https://docs.gamesense.gs/api/docs/client/set_event_callback)
.
client.fire_event(event_name: string, ...)
Arguments[](https://docs.gamesense.gs/docs/api/client/fireevent/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| event\_name | Name of the custom event. | string |
| args | Arguments that will be passed to the event callbacks. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/client/fireevent/#arguments)
---
# client.latency | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/latency/#docusaurus_skipToContent_fallback)
client.latency
==============
Returns your latency in seconds.
client.latency(): number
Returns `latency: number`
---
# client.key_state | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/keystate/#docusaurus_skipToContent_fallback)
On this page
client.key\_state
=================
Returns true if the key is pressed, or nil on failure
client.key_state(key: number): boolean
Arguments[](https://docs.gamesense.gs/docs/api/client/keystate/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| key | Virtual key code of the key as integer. [List of virtual key codes](https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes) | number |
Returns `boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/client/keystate/#arguments)
---
# client.get_model_name | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/getmodelname/#docusaurus_skipToContent_fallback)
On this page
client.get\_model\_name
=======================
Returns model name, or nil on failure.
client.get_model_name(model_index: number): string
Arguments[](https://docs.gamesense.gs/docs/api/client/getmodelname/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| model\_index | Model index | number |
Returns `model_name: string`
* [Arguments](https://docs.gamesense.gs/docs/api/client/getmodelname/#arguments)
---
# client.get_cvar | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/getcvar/#docusaurus_skipToContent_fallback)
On this page
info
In most cases using the [cvar API](https://docs.gamesense.gs/docs/api/cvar)
is preferred over this function.
client.get\_cvar
================
Returns the value of a console variable.
client.get_cvar(cvar_name: string): string
Arguments[](https://docs.gamesense.gs/docs/api/client/getcvar/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| cvar\_name | Name of the convar. | string |
Returns `value: string`
* [Arguments](https://docs.gamesense.gs/docs/api/client/getcvar/#arguments)
---
# client.random_int | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/randomint/#docusaurus_skipToContent_fallback)
On this page
client.random\_int
==================
Returns a random integer between minimum and maximum.
client.random_int(minimum: number, maximum: number): number
Arguments[](https://docs.gamesense.gs/docs/api/client/randomint/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| minimum | Lowest possible result | number |
| maximum | Highest possible result | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/client/randomint/#arguments)
---
# client.real_latency | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/reallatency/#docusaurus_skipToContent_fallback)
client.real\_latency
====================
Returns your real latency, regardless of ping spike.
client.real_latency(): number
Returns `number`
---
# client.random_float | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/randomfloat/#docusaurus_skipToContent_fallback)
On this page
client.random\_float
====================
Returns a random float between minimum and maximum.
client.random_float(minimum: number, maximum: number): number
Arguments[](https://docs.gamesense.gs/docs/api/client/randomfloat/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| minimum | Lowest possible result | number |
| maximum | Highest possible result | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/client/randomfloat/#arguments)
---
# client.log | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/log/#docusaurus_skipToContent_fallback)
On this page
client.log
==========
Logs a message to the console.
client.log(...)
Arguments[](https://docs.gamesense.gs/docs/api/client/log/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| msg | The text to log. Additional arguments will be concatenated. | string |
* [Arguments](https://docs.gamesense.gs/docs/api/client/log/#arguments)
---
# client.reload_active_scripts | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/reloadactivescripts/#docusaurus_skipToContent_fallback)
client.reload\_active\_scripts
==============================
Reloads all scripts the following frame.
client.reload_active_scripts()
---
# client.scale_damage | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/scaledamage/#docusaurus_skipToContent_fallback)
On this page
client.scale\_damage
====================
Returns adjusted damage for the specified hitgroup
client.scale_damage(entindex: number, hitgroup: number, damage: number): number
Arguments[](https://docs.gamesense.gs/docs/api/client/scaledamage/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| entindex | Player entity index | number |
| hitgroup | Hit group index | number |
| damage | Damage | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/client/scaledamage/#arguments)
---
# client.screen_size | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/screensize/#docusaurus_skipToContent_fallback)
client.screen\_size
===================
Returns the size of the screen in pixels.
client.screen_size(): number, number
Returns `width: number, height: number`
---
# client.request_full_update | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/requestfullupdate/#docusaurus_skipToContent_fallback)
danger
Full updates are slow, especially on high ping servers. Use sparingly.
client.request\_full\_update
============================
Requests a full update from the server, refreshing things like skins, player models and modified netvars.
client.request_full_update()
---
# client.set_event_callback | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/seteventcallback/#docusaurus_skipToContent_fallback)
On this page
client.set\_event\_callback
===========================
Registers the function as a callback for the specified event. It can be removed later using [client.unset\_event\_callback](https://docs.gamesense.gs/docs/api/client/seteventcallback/#unset_event_callback)
.
client.set_event_callback(event_name: string, callback)
Arguments[](https://docs.gamesense.gs/docs/api/client/seteventcallback/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| event\_name | Name of the event. | string |
| callback | Lua function to call when this event occurs. | function |
* [Arguments](https://docs.gamesense.gs/docs/api/client/seteventcallback/#arguments)
---
# client.register_esp_flag | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/registerespflag/#docusaurus_skipToContent_fallback)
On this page
info
Refer to [client.register\_esp\_flag example](https://docs.gamesense.gs/examples/register_esp_flag)
for how to use this function.
client.register\_esp\_flag
==========================
Requires "Flags" in Player ESP to be enabled.
client.register_esp_flag(flag: string, r: number, g: number, b: number, callback)
Arguments[](https://docs.gamesense.gs/docs/api/client/registerespflag/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| flag | String of text that will be shown when callback returns true | string |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| callback | Function that will be called for each entity when esp is drawn. If you return true here, the flag will be shown. You can optionally return a 2nd value to override the text that is drawn. | function |
* [Arguments](https://docs.gamesense.gs/docs/api/client/registerespflag/#arguments)
---
# client.timestamp | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/timestamp/#docusaurus_skipToContent_fallback)
client.timestamp
================
Returns high precision timestamp in milliseconds. This can be used for benchmarking code
client.timestamp(): number
Returns `number`
---
# client.system_time | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/systemtime/#docusaurus_skipToContent_fallback)
client.system\_time
===================
Returns the user's windows time.
client.system_time(): number, number, number, number
Returns `hours: number, minutes: number, seconds: number, milliseconds: number`
---
# client.set_clan_tag | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/setclantag/#docusaurus_skipToContent_fallback)
On this page
danger
Calling this every frame can lead to your game becoming laggy. Refer to [this](https://docs.gamesense.gs/examples/custom_clan_tag)
for how to properly use this function.
client.set\_clan\_tag
=====================
Sets the player's clan tag. The clan tag is removed if no argument is passed or if it is an empty string. Additional arguments will be concatenated.
client.set_clan_tag(...)
Arguments[](https://docs.gamesense.gs/docs/api/client/setclantag/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| clan\_tag | N/A | string |
* [Arguments](https://docs.gamesense.gs/docs/api/client/setclantag/#arguments)
---
# client.trace_line | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/traceline/#docusaurus_skipToContent_fallback)
On this page
client.trace\_line
==================
Returns fraction, entindex. fraction is a percentage in the range \[0.0, 1.0\] that tells you how far the trace went before hitting something, so 1.0 means nothing was hit. entindex is the entity index that hit, or -1 if no entity was hit.
client.trace_line(skip_entindex: number, from_x: number, from_y: number, from_z: number, to_x: number, to_y: number, to_z: number): number, number
Arguments[](https://docs.gamesense.gs/docs/api/client/traceline/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| skip\_entindex | Ignore this entity while tracing | number |
| from\_x | X coordinate of the start of the trace | number |
| from\_y | Y coordinate of the start of the trace | number |
| from\_z | Z coordinate of the start of the trace | number |
| to\_x | X coordinate of the end of the trace | number |
| to\_y | Y coordinate of the end of the trace | number |
| to\_z | Z coordinate of the end of the trace | number |
Returns `fraction: number, entindex: number`
* [Arguments](https://docs.gamesense.gs/docs/api/client/traceline/#arguments)
---
# client.unix_time | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/unixtime/#docusaurus_skipToContent_fallback)
client.unix\_time
=================
Returns the current system time as [unix time](https://en.wikipedia.org/wiki/Unix_time)
client.unix_time(): number
Returns `number`
---
# client.update_player_list | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/updateplayerlist/#docusaurus_skipToContent_fallback)
client.update\_player\_list
===========================
Updates the player list tab without having to open it.
client.update_player_list()
---
# client.unset_event_callback | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/unseteventcallback/#docusaurus_skipToContent_fallback)
On this page
client.unset\_event\_callback
=============================
Removes a callback that was previously set using [client.set\_event\_callback](https://docs.gamesense.gs/docs/api/client/unseteventcallback/#set_event_callback)
.
client.unset_event_callback(event_name: string, callback)
Arguments[](https://docs.gamesense.gs/docs/api/client/unseteventcallback/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| event\_name | Name of the event | string |
| callback | Lua function that was passed to set\_event\_callback | function |
* [Arguments](https://docs.gamesense.gs/docs/api/client/unseteventcallback/#arguments)
---
# client.userid_to_entindex | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/useridtoentindex/#docusaurus_skipToContent_fallback)
On this page
client.userid\_to\_entindex
===========================
Converts a User ID (from game events, for example) to the entity index.
client.userid_to_entindex(userid: number): number
Arguments[](https://docs.gamesense.gs/docs/api/client/useridtoentindex/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| userid | This is given by some game events. | number |
Returns `entindex: number`
* [Arguments](https://docs.gamesense.gs/docs/api/client/useridtoentindex/#arguments)
---
# client.visible | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/visible/#docusaurus_skipToContent_fallback)
On this page
client.visible
==============
Returns true if the position is visible from the local player eye position. For more advanced ray tracing use [client.trace\_line](https://docs.gamesense.gs/docs/api/client/visible/#trace_line)
.
client.visible(x: number, y: number, z: number): boolean
Arguments[](https://docs.gamesense.gs/docs/api/client/visible/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | X coordinate of the position | number |
| y | Y coordinate of the position | number |
| z | Z coordinate of the position | number |
Returns `boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/client/visible/#arguments)
---
# config.export | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/config/export/#docusaurus_skipToContent_fallback)
config.export
=============
Returns the current config in the export format
config.export(): string
Returns `string`
---
# client | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/#docusaurus_skipToContent_fallback)
On this page
client
======
Description[](https://docs.gamesense.gs/docs/api/client/#description "Direct link to heading")
------------------------------------------------------------------------------------------------
General game- and cheat-related functions
Functions[](https://docs.gamesense.gs/docs/api/client/#functions "Direct link to heading")
--------------------------------------------------------------------------------------------
### camera\_angles[](https://docs.gamesense.gs/docs/api/client/#camera_angles "Direct link to heading")
[client.camera_angles(pitch: number, yaw: number): number, number](https://docs.gamesense.gs/docs/api/client/cameraangles)
> Get or set camera angles. Pass no arguments to get the current camera angles.
### camera\_position[](https://docs.gamesense.gs/docs/api/client/#camera_position "Direct link to heading")
[client.camera_position(): number, number, number](https://docs.gamesense.gs/docs/api/client/cameraposition)
> Returns x, y, z world coordinates of the game's camera position.
### color\_log[](https://docs.gamesense.gs/docs/api/client/#color_log "Direct link to heading")
[client.color_log(r: number, g: number, b: number, ...)](https://docs.gamesense.gs/docs/api/client/colorlog)
> Logs a colored message to console. End the string with \\0 to prevent it from adding a newline.
### create\_interface[](https://docs.gamesense.gs/docs/api/client/#create_interface "Direct link to heading")
[client.create_interface(module_name: string, interface_name: string): userdata](https://docs.gamesense.gs/docs/api/client/createinterface)
> Returns a pointer to the interface, or nil on failure.
### current\_threat[](https://docs.gamesense.gs/docs/api/client/#current_threat "Direct link to heading")
[client.current_threat(): number](https://docs.gamesense.gs/docs/api/client/currentthreat)
> Returns the entindex of the 'current threat', i.e. the enemy that is currently being used for 'At targets' anti-aim.
### delay\_call[](https://docs.gamesense.gs/docs/api/client/#delay_call "Direct link to heading")
[client.delay_call(delay: number, callback, ...)](https://docs.gamesense.gs/docs/api/client/delaycall)
> Executes the callback after delay seconds, passing the arguments to it.
### draw\_debug\_text[](https://docs.gamesense.gs/docs/api/client/#draw_debug_text "Direct link to heading")
[client.draw_debug_text(x: number, y: number, z: number, line_offset: number, duration: number, r: number, g: number, b: number, a: number, ...)](https://docs.gamesense.gs/docs/api/client/drawdebugtext)
> Draws a DebugOverlay text at the specified 3d position. Avoid calling this during the paint event.
### draw\_hitboxes[](https://docs.gamesense.gs/docs/api/client/#draw_hitboxes "Direct link to heading")
[client.draw_hitboxes(entindex: number, duration: number, hitboxes: number, r: number, g: number, b: number, a: number, tick: number)](https://docs.gamesense.gs/docs/api/client/drawhitboxes)
> Draws hitbox overlays. Avoid calling this during the paint event.
### error\_log[](https://docs.gamesense.gs/docs/api/client/#error_log "Direct link to heading")
[client.error_log(msg: string)](https://docs.gamesense.gs/docs/api/client/errorlog)
> Prints an error to the console and plays a sound.
### exec[](https://docs.gamesense.gs/docs/api/client/#exec "Direct link to heading")
[client.exec(...)](https://docs.gamesense.gs/docs/api/client/exec)
> Executes a console command. Multiple commands can be combined with ';'. Be careful when passing user input (including player names) to it.
### eye\_position[](https://docs.gamesense.gs/docs/api/client/#eye_position "Direct link to heading")
[client.eye_position(): number, number, number](https://docs.gamesense.gs/docs/api/client/eyeposition)
> Returns x, y, z world coordinates of the local player's eye position.
### find\_signature[](https://docs.gamesense.gs/docs/api/client/#find_signature "Direct link to heading")
[client.find_signature(module_name: string, pattern: string): userdata](https://docs.gamesense.gs/docs/api/client/findsignature)
> Finds the specified pattern and returns a pointer to it, or nil if not found.
### fire\_event[](https://docs.gamesense.gs/docs/api/client/#fire_event "Direct link to heading")
[client.fire_event(event_name: string, ...)](https://docs.gamesense.gs/docs/api/client/fireevent)
> Fires a custom event that other scripts can listen to using [client.set\_event\_callback](https://docs.gamesense.gs/api/docs/client/set_event_callback)
> .
### get\_cvar[](https://docs.gamesense.gs/docs/api/client/#get_cvar "Direct link to heading")
[client.get_cvar(cvar_name: string): string](https://docs.gamesense.gs/docs/api/client/getcvar)
> Returns the value of a console variable.
### get\_model\_name[](https://docs.gamesense.gs/docs/api/client/#get_model_name "Direct link to heading")
[client.get_model_name(model_index: number): string](https://docs.gamesense.gs/docs/api/client/getmodelname)
> Returns model name, or nil on failure.
### key\_state[](https://docs.gamesense.gs/docs/api/client/#key_state "Direct link to heading")
[client.key_state(key: number): boolean](https://docs.gamesense.gs/docs/api/client/keystate)
> Returns true if the key is pressed, or nil on failure
### latency[](https://docs.gamesense.gs/docs/api/client/#latency "Direct link to heading")
[client.latency(): number](https://docs.gamesense.gs/docs/api/client/latency)
> Returns your latency in seconds.
### log[](https://docs.gamesense.gs/docs/api/client/#log "Direct link to heading")
[client.log(...)](https://docs.gamesense.gs/docs/api/client/log)
> Logs a message to the console.
### random\_float[](https://docs.gamesense.gs/docs/api/client/#random_float "Direct link to heading")
[client.random_float(minimum: number, maximum: number): number](https://docs.gamesense.gs/docs/api/client/randomfloat)
> Returns a random float between minimum and maximum.
### random\_int[](https://docs.gamesense.gs/docs/api/client/#random_int "Direct link to heading")
[client.random_int(minimum: number, maximum: number): number](https://docs.gamesense.gs/docs/api/client/randomint)
> Returns a random integer between minimum and maximum.
### real\_latency[](https://docs.gamesense.gs/docs/api/client/#real_latency "Direct link to heading")
[client.real_latency(): number](https://docs.gamesense.gs/docs/api/client/reallatency)
> Returns your real latency, regardless of ping spike.
### register\_esp\_flag[](https://docs.gamesense.gs/docs/api/client/#register_esp_flag "Direct link to heading")
[client.register_esp_flag(flag: string, r: number, g: number, b: number, callback)](https://docs.gamesense.gs/docs/api/client/registerespflag)
> Requires "Flags" in Player ESP to be enabled.
### reload\_active\_scripts[](https://docs.gamesense.gs/docs/api/client/#reload_active_scripts "Direct link to heading")
[client.reload_active_scripts()](https://docs.gamesense.gs/docs/api/client/reloadactivescripts)
> Reloads all scripts the following frame.
### request\_full\_update[](https://docs.gamesense.gs/docs/api/client/#request_full_update "Direct link to heading")
[client.request_full_update()](https://docs.gamesense.gs/docs/api/client/requestfullupdate)
> Requests a full update from the server, refreshing things like skins, player models and modified netvars.
### scale\_damage[](https://docs.gamesense.gs/docs/api/client/#scale_damage "Direct link to heading")
[client.scale_damage(entindex: number, hitgroup: number, damage: number): number](https://docs.gamesense.gs/docs/api/client/scaledamage)
> Returns adjusted damage for the specified hitgroup
### screen\_size[](https://docs.gamesense.gs/docs/api/client/#screen_size "Direct link to heading")
[client.screen_size(): number, number](https://docs.gamesense.gs/docs/api/client/screensize)
> Returns the size of the screen in pixels.
### set\_clan\_tag[](https://docs.gamesense.gs/docs/api/client/#set_clan_tag "Direct link to heading")
[client.set_clan_tag(...)](https://docs.gamesense.gs/docs/api/client/setclantag)
> Sets the player's clan tag. The clan tag is removed if no argument is passed or if it is an empty string. Additional arguments will be concatenated.
### set\_event\_callback[](https://docs.gamesense.gs/docs/api/client/#set_event_callback "Direct link to heading")
[client.set_event_callback(event_name: string, callback)](https://docs.gamesense.gs/docs/api/client/seteventcallback)
> Registers the function as a callback for the specified event. It can be removed later using [client.unset\_event\_callback](https://docs.gamesense.gs/docs/api/client/#unset_event_callback)
> .
### system\_time[](https://docs.gamesense.gs/docs/api/client/#system_time "Direct link to heading")
[client.system_time(): number, number, number, number](https://docs.gamesense.gs/docs/api/client/systemtime)
> Returns the user's windows time.
### timestamp[](https://docs.gamesense.gs/docs/api/client/#timestamp "Direct link to heading")
[client.timestamp(): number](https://docs.gamesense.gs/docs/api/client/timestamp)
> Returns high precision timestamp in milliseconds. This can be used for benchmarking code
### trace\_bullet[](https://docs.gamesense.gs/docs/api/client/#trace_bullet "Direct link to heading")
[client.trace_bullet(from_player: number, from_x: number, from_y: number, from_z: number, to_x: number, to_y: number, to_z: number, skip_players: boolean): number, number](https://docs.gamesense.gs/docs/api/client/tracebullet)
> Returns entindex, damage. Entindex is nil when no player is hit or if players are skipped.
### trace\_line[](https://docs.gamesense.gs/docs/api/client/#trace_line "Direct link to heading")
[client.trace_line(skip_entindex: number, from_x: number, from_y: number, from_z: number, to_x: number, to_y: number, to_z: number): number, number](https://docs.gamesense.gs/docs/api/client/traceline)
> Returns fraction, entindex. fraction is a percentage in the range \[0.0, 1.0\] that tells you how far the trace went before hitting something, so 1.0 means nothing was hit. entindex is the entity index that hit, or -1 if no entity was hit.
### unix\_time[](https://docs.gamesense.gs/docs/api/client/#unix_time "Direct link to heading")
[client.unix_time(): number](https://docs.gamesense.gs/docs/api/client/unixtime)
> Returns the current system time as [unix time](https://en.wikipedia.org/wiki/Unix_time)
### unset\_event\_callback[](https://docs.gamesense.gs/docs/api/client/#unset_event_callback "Direct link to heading")
[client.unset_event_callback(event_name: string, callback)](https://docs.gamesense.gs/docs/api/client/unseteventcallback)
> Removes a callback that was previously set using [client.set\_event\_callback](https://docs.gamesense.gs/docs/api/client/#set_event_callback)
> .
### update\_player\_list[](https://docs.gamesense.gs/docs/api/client/#update_player_list "Direct link to heading")
[client.update_player_list()](https://docs.gamesense.gs/docs/api/client/updateplayerlist)
> Updates the player list tab without having to open it.
### userid\_to\_entindex[](https://docs.gamesense.gs/docs/api/client/#userid_to_entindex "Direct link to heading")
[client.userid_to_entindex(userid: number): number](https://docs.gamesense.gs/docs/api/client/useridtoentindex)
> Converts a User ID (from game events, for example) to the entity index.
### visible[](https://docs.gamesense.gs/docs/api/client/#visible "Direct link to heading")
[client.visible(x: number, y: number, z: number): boolean](https://docs.gamesense.gs/docs/api/client/visible)
> Returns true if the position is visible from the local player eye position. For more advanced ray tracing use [client.trace\_line](https://docs.gamesense.gs/docs/api/client/#trace_line)
> .
* [Description](https://docs.gamesense.gs/docs/api/client/#description)
* [Functions](https://docs.gamesense.gs/docs/api/client/#functions)
* [camera\_angles](https://docs.gamesense.gs/docs/api/client/#camera_angles)
* [camera\_position](https://docs.gamesense.gs/docs/api/client/#camera_position)
* [color\_log](https://docs.gamesense.gs/docs/api/client/#color_log)
* [create\_interface](https://docs.gamesense.gs/docs/api/client/#create_interface)
* [current\_threat](https://docs.gamesense.gs/docs/api/client/#current_threat)
* [delay\_call](https://docs.gamesense.gs/docs/api/client/#delay_call)
* [draw\_debug\_text](https://docs.gamesense.gs/docs/api/client/#draw_debug_text)
* [draw\_hitboxes](https://docs.gamesense.gs/docs/api/client/#draw_hitboxes)
* [error\_log](https://docs.gamesense.gs/docs/api/client/#error_log)
* [exec](https://docs.gamesense.gs/docs/api/client/#exec)
* [eye\_position](https://docs.gamesense.gs/docs/api/client/#eye_position)
* [find\_signature](https://docs.gamesense.gs/docs/api/client/#find_signature)
* [fire\_event](https://docs.gamesense.gs/docs/api/client/#fire_event)
* [get\_cvar](https://docs.gamesense.gs/docs/api/client/#get_cvar)
* [get\_model\_name](https://docs.gamesense.gs/docs/api/client/#get_model_name)
* [key\_state](https://docs.gamesense.gs/docs/api/client/#key_state)
* [latency](https://docs.gamesense.gs/docs/api/client/#latency)
* [log](https://docs.gamesense.gs/docs/api/client/#log)
* [random\_float](https://docs.gamesense.gs/docs/api/client/#random_float)
* [random\_int](https://docs.gamesense.gs/docs/api/client/#random_int)
* [real\_latency](https://docs.gamesense.gs/docs/api/client/#real_latency)
* [register\_esp\_flag](https://docs.gamesense.gs/docs/api/client/#register_esp_flag)
* [reload\_active\_scripts](https://docs.gamesense.gs/docs/api/client/#reload_active_scripts)
* [request\_full\_update](https://docs.gamesense.gs/docs/api/client/#request_full_update)
* [scale\_damage](https://docs.gamesense.gs/docs/api/client/#scale_damage)
* [screen\_size](https://docs.gamesense.gs/docs/api/client/#screen_size)
* [set\_clan\_tag](https://docs.gamesense.gs/docs/api/client/#set_clan_tag)
* [set\_event\_callback](https://docs.gamesense.gs/docs/api/client/#set_event_callback)
* [system\_time](https://docs.gamesense.gs/docs/api/client/#system_time)
* [timestamp](https://docs.gamesense.gs/docs/api/client/#timestamp)
* [trace\_bullet](https://docs.gamesense.gs/docs/api/client/#trace_bullet)
* [trace\_line](https://docs.gamesense.gs/docs/api/client/#trace_line)
* [unix\_time](https://docs.gamesense.gs/docs/api/client/#unix_time)
* [unset\_event\_callback](https://docs.gamesense.gs/docs/api/client/#unset_event_callback)
* [update\_player\_list](https://docs.gamesense.gs/docs/api/client/#update_player_list)
* [userid\_to\_entindex](https://docs.gamesense.gs/docs/api/client/#userid_to_entindex)
* [visible](https://docs.gamesense.gs/docs/api/client/#visible)
---
# config.load | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/config/load/#docusaurus_skipToContent_fallback)
On this page
config.load
===========
Loads an existing config. To load the specified config: config.load('Config name here') To load a tab from the specified config: config.load('Config name here', 'Tab name here') To load a container from the specified config: config.load('Config name here', 'Tab name here', 'Container name here')
config.load(name: string, tab_name: string, container_name: string)
Arguments[](https://docs.gamesense.gs/docs/api/config/load/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| name | N/A | string |
| tab\_name | N/A | string |
| container\_name | N/A | string |
* [Arguments](https://docs.gamesense.gs/docs/api/config/load/#arguments)
---
# config.import | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/config/import/#docusaurus_skipToContent_fallback)
On this page
config.import
=============
Imports a config in the export format
config.import(config: string)
Arguments[](https://docs.gamesense.gs/docs/api/config/import/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| config | N/A | string |
* [Arguments](https://docs.gamesense.gs/docs/api/config/import/#arguments)
---
# database.flush | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/database/flush/#docusaurus_skipToContent_fallback)
danger
This function is slow and performs disk IO. Do not call it too often.
database.flush
==============
Flushes the database to disk. This is automatically called when the script is reloaded, but you can call it manually if you want to force a flush.
database.flush()
---
# database.read | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/database/read/#docusaurus_skipToContent_fallback)
On this page
database.read
=============
Gets a value from the database
database.read(key_name: string):
Arguments[](https://docs.gamesense.gs/docs/api/database/read/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| key\_name | String used as a name of the key. | string |
Returns `value: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/database/read/#arguments)
---
# database.write | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/database/write/#docusaurus_skipToContent_fallback)
On this page
info
Make sure to use unique names for your DB keys to avoid conflicts with other scripts. For example, prefer `"gamesense_watermark_position"` over something generic like `"position"`
database.write
==============
Writes a value to the database. Avoid calling this often. For example, call read at script load, then call write during the 'shutdown' event
database.write(key_name: string, value)
Arguments[](https://docs.gamesense.gs/docs/api/database/write/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| key\_name | String used as a name of the key. | string |
| value | Value the key should be set to. This can be anything that can be sanitized (no functions, userdata). Tables are allowed and encouraged to reduce the amount of database keys your script needs. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/database/write/#arguments)
---
# entity.get_all | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getall/#docusaurus_skipToContent_fallback)
On this page
entity.get\_all
===============
Returns an array of entity indices matching the classname. Pass no arguments for all entities. Dormant entities are not returned.
entity.get_all(classname: string): table
Arguments[](https://docs.gamesense.gs/docs/api/entity/getall/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| classname | String that specifies the class name of entities that will be added to the list, for example `"CCSPlayer"`. | string |
Returns `entities: table`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getall/#arguments)
---
# config | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/config/#docusaurus_skipToContent_fallback)
On this page
config
======
Description[](https://docs.gamesense.gs/docs/api/config/#description "Direct link to heading")
------------------------------------------------------------------------------------------------
Configuration related lua functions
Functions[](https://docs.gamesense.gs/docs/api/config/#functions "Direct link to heading")
--------------------------------------------------------------------------------------------
### export[](https://docs.gamesense.gs/docs/api/config/#export "Direct link to heading")
[config.export(): string](https://docs.gamesense.gs/docs/api/config/export)
> Returns the current config in the export format
### import[](https://docs.gamesense.gs/docs/api/config/#import "Direct link to heading")
[config.import(config: string)](https://docs.gamesense.gs/docs/api/config/import)
> Imports a config in the export format
### load[](https://docs.gamesense.gs/docs/api/config/#load "Direct link to heading")
[config.load(name: string, tab_name: string, container_name: string)](https://docs.gamesense.gs/docs/api/config/load)
> Loads an existing config. To load the specified config: config.load('Config name here') To load a tab from the specified config: config.load('Config name here', 'Tab name here') To load a container from the specified config: config.load('Config name here', 'Tab name here', 'Container name here')
* [Description](https://docs.gamesense.gs/docs/api/config/#description)
* [Functions](https://docs.gamesense.gs/docs/api/config/#functions)
* [export](https://docs.gamesense.gs/docs/api/config/#export)
* [import](https://docs.gamesense.gs/docs/api/config/#import)
* [load](https://docs.gamesense.gs/docs/api/config/#load)
---
# database | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/database/#docusaurus_skipToContent_fallback)
On this page
database
========
Description[](https://docs.gamesense.gs/docs/api/database/#description "Direct link to heading")
--------------------------------------------------------------------------------------------------
Persistent storage that lets you store lua values (including tables) between script / cheat reloads.
Functions[](https://docs.gamesense.gs/docs/api/database/#functions "Direct link to heading")
----------------------------------------------------------------------------------------------
### flush[](https://docs.gamesense.gs/docs/api/database/#flush "Direct link to heading")
[database.flush()](https://docs.gamesense.gs/docs/api/database/flush)
> Flushes the database to disk. This is automatically called when the script is reloaded, but you can call it manually if you want to force a flush.
### read[](https://docs.gamesense.gs/docs/api/database/#read "Direct link to heading")
[database.read(key_name: string):](https://docs.gamesense.gs/docs/api/database/read)
> Gets a value from the database
### write[](https://docs.gamesense.gs/docs/api/database/#write "Direct link to heading")
[database.write(key_name: string, value)](https://docs.gamesense.gs/docs/api/database/write)
> Writes a value to the database. Avoid calling this often. For example, call read at script load, then call write during the 'shutdown' event
* [Description](https://docs.gamesense.gs/docs/api/database/#description)
* [Functions](https://docs.gamesense.gs/docs/api/database/#functions)
* [flush](https://docs.gamesense.gs/docs/api/database/#flush)
* [read](https://docs.gamesense.gs/docs/api/database/#read)
* [write](https://docs.gamesense.gs/docs/api/database/#write)
---
# entity.get_esp_data | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getespdata/#docusaurus_skipToContent_fallback)
On this page
entity.get\_esp\_data
=====================
Returns a table containing alpha, health, flags, and weapon\_id, or nil on failure.
entity.get_esp_data(player: number): table
Arguments[](https://docs.gamesense.gs/docs/api/entity/getespdata/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| player | Player entity index. | number |
Returns `table`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getespdata/#arguments)
---
# cvar | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/cvar/#docusaurus_skipToContent_fallback)
On this page
cvar
====
Description[](https://docs.gamesense.gs/docs/api/cvar/#description "Direct link to heading")
----------------------------------------------------------------------------------------------
A table letting you get and set the value of cvars and invoke the callbacks of concommands.
-- localize the cvar objectlocal cl_fullupdate = cvar.cl_fullupdate-- invoke a callback to the command as if you entered the command in the consolecl_fullupdate:invoke_callback()
--localize the cvar objectlocal cl_downloadfilter = cvar.cl_downloadfilter-- print the current value of the cvarclient.log(cl_downloadfilter:get_string())-- set the cvars valuecl_downloadfilter:set_string("none")-- print it againclient.log(cl_downloadfilter:get_string()) -- "none"
info
The documentation for the `cvar` type is unfinished as it relies on types that aren't in the docs yet.
Functions[](https://docs.gamesense.gs/docs/api/cvar/#functions "Direct link to heading")
------------------------------------------------------------------------------------------
### \_\_index[](https://docs.gamesense.gs/docs/api/cvar/#__index "Direct link to heading")
[cvar.__index(name: string): cvar](https://docs.gamesense.gs/docs/api/cvar/index)
> Finds a cvar by name and returns a [cvar object](https://docs.gamesense.gs/docs/api/types/cvar)
> for it, or nil if it doesn't exist or is blocked for security reasons.
* [Description](https://docs.gamesense.gs/docs/api/cvar/#description)
* [Functions](https://docs.gamesense.gs/docs/api/cvar/#functions)
* [\_\_index](https://docs.gamesense.gs/docs/api/cvar/#__index)
---
# entity.get_classname | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getclassname/#docusaurus_skipToContent_fallback)
On this page
entity.get\_classname
=====================
Returns the name of the entity's class.
entity.get_classname(ent: number): string
Arguments[](https://docs.gamesense.gs/docs/api/entity/getclassname/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Entity index. | number |
Returns `classname: string`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getclassname/#arguments)
---
# entity.get_game_rules | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getgamerules/#docusaurus_skipToContent_fallback)
entity.get\_game\_rules
=======================
Returns the entity index of the `CCSGameRulesProxy` instance, or nil if none exists.
entity.get_game_rules(): number
Returns `number`
---
# client.trace_bullet | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/client/tracebullet/#docusaurus_skipToContent_fallback)
On this page
client.trace\_bullet
====================
Returns entindex, damage. Entindex is nil when no player is hit or if players are skipped.
client.trace_bullet(from_player: number, from_x: number, from_y: number, from_z: number, to_x: number, to_y: number, to_z: number, skip_players: boolean): number, number
Arguments[](https://docs.gamesense.gs/docs/api/client/tracebullet/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| from\_player | Entity index of the player whose weapon will be used for this trace | number |
| from\_x | X coordinate of the start of the trace | number |
| from\_y | Y coordinate of the start of the trace | number |
| from\_z | Z coordinate of the start of the trace | number |
| to\_x | X coordinate of the end of the trace | number |
| to\_y | Y coordinate of the end of the trace | number |
| to\_z | Z coordinate of the end of the trace | number |
| skip\_players | Pass true to skip expensive hitbox checks. | boolean |
Returns `entindex: number, damage: number`
* [Arguments](https://docs.gamesense.gs/docs/api/client/tracebullet/#arguments)
---
# entity.get_origin | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getorigin/#docusaurus_skipToContent_fallback)
On this page
entity.get\_origin
==================
Returns x, y, z world coordinates of the entity's origin, or nil if the entity is dormant and dormant ESP information is not available.
entity.get_origin(ent: number): number, number, number
Arguments[](https://docs.gamesense.gs/docs/api/entity/getorigin/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Entity index. | number |
Returns `x: number, y: number, z: number`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getorigin/#arguments)
---
# entity.get_player_name | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getplayername/#docusaurus_skipToContent_fallback)
On this page
entity.get\_player\_name
========================
Returns the player's name, or the string "unknown" on failure.
entity.get_player_name(player: number): string
Arguments[](https://docs.gamesense.gs/docs/api/entity/getplayername/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| player | The player index. | number |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getplayername/#arguments)
---
# entity.get_player_resource | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getplayerresource/#docusaurus_skipToContent_fallback)
entity.get\_player\_resource
============================
Returns the entity index of the `CCSPlayerResource` instance, or nil if none exists.
entity.get_player_resource(): number
Returns `number`
---
# entity.get_local_player | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getlocalplayer/#docusaurus_skipToContent_fallback)
entity.get\_local\_player
=========================
Returns the entity index for the local player, or nil on failure.
entity.get_local_player(): number
Returns `number`
---
# coroutine | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/coroutine/#docusaurus_skipToContent_fallback)
On this page
coroutine
=========
Description[](https://docs.gamesense.gs/docs/api/coroutine/#description "Direct link to heading")
---------------------------------------------------------------------------------------------------
A coroutine is a function that can be suspended and resumed at a later time, enabling asynchronous execution of synchronous code.
* [Description](https://docs.gamesense.gs/docs/api/coroutine/#description)
---
# entity.get_prop | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getprop/#docusaurus_skipToContent_fallback)
On this page
entity.get\_prop
================
Returns the value of the property, or nil on failure. For vectors or angles, this returns three values.
entity.get_prop(ent: number, prop: string, array_index: number):
Arguments[](https://docs.gamesense.gs/docs/api/entity/getprop/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Entity index. | number |
| prop | Property name. | string |
| array\_index | If propname is an array, the value at this array index will be returned. | number |
Returns `netprop value: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getprop/#arguments)
---
# entity.get_players | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getplayers/#docusaurus_skipToContent_fallback)
On this page
entity.get\_players
===================
Returns an array of player entity indices. Dormant and dead players will not be added to the list.
entity.get_players(enemies_only: boolean): table
Arguments[](https://docs.gamesense.gs/docs/api/entity/getplayers/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| enemies\_only | If true then the local player and teammates will not be added to the list. | boolean |
Returns `table`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getplayers/#arguments)
---
# entity.get_player_weapon | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getplayerweapon/#docusaurus_skipToContent_fallback)
On this page
entity.get\_player\_weapon
==========================
Returns the entity index of the player's active weapon, or nil if the player is not alive, dormant, etc.
entity.get_player_weapon(player: number): number
Arguments[](https://docs.gamesense.gs/docs/api/entity/getplayerweapon/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| player | The player index to get the weapon of. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getplayerweapon/#arguments)
---
# entity.hitbox_position | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/hitboxposition/#docusaurus_skipToContent_fallback)
On this page
entity.hitbox\_position
=======================
Returns world coordinates of the hitboxes, or nil on failure.
entity.hitbox_position(player: number, hitbox: number): number, number, number
Arguments[](https://docs.gamesense.gs/docs/api/entity/hitboxposition/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| player | The player index. | number |
| hitbox | The hitbox index. Alternatively, a hitbox name (string) can be used. | number |
Returns `x: number, y: number, z: number`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/hitboxposition/#arguments)
---
# entity.get_steam64 | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getsteam64/#docusaurus_skipToContent_fallback)
On this page
entity.get\_steam64
===================
Returns the player's SteamID3, or nil on failure.
entity.get_steam64(player: number): number
Arguments[](https://docs.gamesense.gs/docs/api/entity/getsteam64/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| player | Player entity index. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getsteam64/#arguments)
---
# entity.set_prop | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/setprop/#docusaurus_skipToContent_fallback)
On this page
entity.set\_prop
================
Sets the value of the property. For vectors or angles, pass three values.
entity.set_prop(ent: number, prop: string, ..., array_index: number)
Arguments[](https://docs.gamesense.gs/docs/api/entity/setprop/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Entity index. | number |
| prop | Property name. | string |
| value | The property will be set to this value. | unknown |
| array\_index | If propname is an array, the value at this array index will be returned. | number |
* [Arguments](https://docs.gamesense.gs/docs/api/entity/setprop/#arguments)
---
# entity.is_dormant | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/isdormant/#docusaurus_skipToContent_fallback)
On this page
entity.is\_dormant
==================
Returns true if the entity is dormant.
entity.is_dormant(ent: number): boolean
Arguments[](https://docs.gamesense.gs/docs/api/entity/isdormant/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Entity index. | number |
Returns `boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/isdormant/#arguments)
---
# entity.is_enemy | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/isenemy/#docusaurus_skipToContent_fallback)
On this page
entity.is\_enemy
================
Returns true if the entity is on the opposing team.
entity.is_enemy(ent: number): boolean
Arguments[](https://docs.gamesense.gs/docs/api/entity/isenemy/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Entity index. | number |
Returns `boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/isenemy/#arguments)
---
# entity.is_alive | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/isalive/#docusaurus_skipToContent_fallback)
On this page
entity.is\_alive
================
Returns true if the player is not dead.
entity.is_alive(ent: number): boolean
Arguments[](https://docs.gamesense.gs/docs/api/entity/isalive/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Player entity index. | number |
Returns `boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/isalive/#arguments)
---
# entity.new_prop | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/newprop/#docusaurus_skipToContent_fallback)
On this page
entity.new\_prop
================
Creates a new entity prop that can then be read and modified with [entity.get\_prop](https://docs.gamesense.gs/docs/api/entity/newprop/#get_prop)
/ [entity.set\_prop](https://docs.gamesense.gs/docs/api/entity/newprop/#set_prop)
.
entity.new_prop(propname: string, offset: number, type: number, array_type: number, array_element_size: number, array_count: number)
Arguments[](https://docs.gamesense.gs/docs/api/entity/newprop/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| propname | N/A | string |
| offset | N/A | number |
| type | N/A | number |
| array\_type | N/A | number |
| array\_element\_size | N/A | number |
| array\_count | N/A | number |
* [Arguments](https://docs.gamesense.gs/docs/api/entity/newprop/#arguments)
---
# collectgarbage | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/collectgarbage/#docusaurus_skipToContent_fallback)
On this page
collectgarbage
==============
This function is a generic interface to the garbage collector. It performs different functions according to its first argument, opt:
* `"collect"`: performs a full garbage-collection cycle. This is the default option.
* `"stop"`: stops the garbage collector.
* `"restart"`: restarts the garbage collector.
* `"count"`: returns the total memory in use by Lua (in Kbytes).
* `"step"`: performs a garbage-collection step. The step `"size"` is controlled by arg (larger values mean more steps) in a non-specified way. If you want to control the step size you must experimentally tune the value of arg. Returns **true** if the step finished a collection cycle.
* `"setpause"`: sets arg as the new value for the pause of the collector (see [§2.10](https://www.lua.org/manual/5.1/manual.html#2.10)
). Returns the previous value for pause.
* `"setstepmul"`: sets arg as the new value for the step multiplier of the collector (see [§2.10](https://www.lua.org/manual/5.1/manual.html#2.10)
). Returns the previous value for step.
**Modifying garbage collector settings is generally not recommended, unless you know what you are doing.**
collectgarbage(opt: string, arg)
Arguments[](https://docs.gamesense.gs/docs/api/G/collectgarbage/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| opt | The operation to perform. | string |
| arg | Additional arguments for the operation. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/G/collectgarbage/#arguments)
---
# defer | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/defer/#docusaurus_skipToContent_fallback)
On this page
defer
=====
Registers a function to be called at lua shutdown/reload, equivalent to `client.set_event_callback("shutdown", callback)`.
defer(callback)
Arguments[](https://docs.gamesense.gs/docs/api/G/defer/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| callback | The function to execute on shutdown. | function |
* [Arguments](https://docs.gamesense.gs/docs/api/G/defer/#arguments)
---
# entity | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/#docusaurus_skipToContent_fallback)
On this page
entity
======
Description[](https://docs.gamesense.gs/docs/api/entity/#description "Direct link to heading")
------------------------------------------------------------------------------------------------
Entity related functions such as iterating them, getting and modifying netvars, etc.
Functions[](https://docs.gamesense.gs/docs/api/entity/#functions "Direct link to heading")
--------------------------------------------------------------------------------------------
### get\_all[](https://docs.gamesense.gs/docs/api/entity/#get_all "Direct link to heading")
[entity.get_all(classname: string): table](https://docs.gamesense.gs/docs/api/entity/getall)
> Returns an array of entity indices matching the classname. Pass no arguments for all entities. Dormant entities are not returned.
### get\_bounding\_box[](https://docs.gamesense.gs/docs/api/entity/#get_bounding_box "Direct link to heading")
[entity.get_bounding_box(ent: number): number, number, number, number, number](https://docs.gamesense.gs/docs/api/entity/getboundingbox)
> Returns the 2D bounding box and alpha multiplier (dormant esp). The contents of x1, y1, x2, y2 must be ignored when alpha\_multiplier is zero, which indicates that the bounding box is invalid and should not be drawn.
### get\_classname[](https://docs.gamesense.gs/docs/api/entity/#get_classname "Direct link to heading")
[entity.get_classname(ent: number): string](https://docs.gamesense.gs/docs/api/entity/getclassname)
> Returns the name of the entity's class.
### get\_esp\_data[](https://docs.gamesense.gs/docs/api/entity/#get_esp_data "Direct link to heading")
[entity.get_esp_data(player: number): table](https://docs.gamesense.gs/docs/api/entity/getespdata)
> Returns a table containing alpha, health, flags, and weapon\_id, or nil on failure.
### get\_game\_rules[](https://docs.gamesense.gs/docs/api/entity/#get_game_rules "Direct link to heading")
[entity.get_game_rules(): number](https://docs.gamesense.gs/docs/api/entity/getgamerules)
> Returns the entity index of the `CCSGameRulesProxy` instance, or nil if none exists.
### get\_local\_player[](https://docs.gamesense.gs/docs/api/entity/#get_local_player "Direct link to heading")
[entity.get_local_player(): number](https://docs.gamesense.gs/docs/api/entity/getlocalplayer)
> Returns the entity index for the local player, or nil on failure.
### get\_origin[](https://docs.gamesense.gs/docs/api/entity/#get_origin "Direct link to heading")
[entity.get_origin(ent: number): number, number, number](https://docs.gamesense.gs/docs/api/entity/getorigin)
> Returns x, y, z world coordinates of the entity's origin, or nil if the entity is dormant and dormant ESP information is not available.
### get\_player\_name[](https://docs.gamesense.gs/docs/api/entity/#get_player_name "Direct link to heading")
[entity.get_player_name(player: number): string](https://docs.gamesense.gs/docs/api/entity/getplayername)
> Returns the player's name, or the string "unknown" on failure.
### get\_player\_resource[](https://docs.gamesense.gs/docs/api/entity/#get_player_resource "Direct link to heading")
[entity.get_player_resource(): number](https://docs.gamesense.gs/docs/api/entity/getplayerresource)
> Returns the entity index of the `CCSPlayerResource` instance, or nil if none exists.
### get\_player\_weapon[](https://docs.gamesense.gs/docs/api/entity/#get_player_weapon "Direct link to heading")
[entity.get_player_weapon(player: number): number](https://docs.gamesense.gs/docs/api/entity/getplayerweapon)
> Returns the entity index of the player's active weapon, or nil if the player is not alive, dormant, etc.
### get\_players[](https://docs.gamesense.gs/docs/api/entity/#get_players "Direct link to heading")
[entity.get_players(enemies_only: boolean): table](https://docs.gamesense.gs/docs/api/entity/getplayers)
> Returns an array of player entity indices. Dormant and dead players will not be added to the list.
### get\_prop[](https://docs.gamesense.gs/docs/api/entity/#get_prop "Direct link to heading")
[entity.get_prop(ent: number, prop: string, array_index: number):](https://docs.gamesense.gs/docs/api/entity/getprop)
> Returns the value of the property, or nil on failure. For vectors or angles, this returns three values.
### get\_steam64[](https://docs.gamesense.gs/docs/api/entity/#get_steam64 "Direct link to heading")
[entity.get_steam64(player: number): number](https://docs.gamesense.gs/docs/api/entity/getsteam64)
> Returns the player's SteamID3, or nil on failure.
### hitbox\_position[](https://docs.gamesense.gs/docs/api/entity/#hitbox_position "Direct link to heading")
[entity.hitbox_position(player: number, hitbox: number): number, number, number](https://docs.gamesense.gs/docs/api/entity/hitboxposition)
> Returns world coordinates of the hitboxes, or nil on failure.
### is\_alive[](https://docs.gamesense.gs/docs/api/entity/#is_alive "Direct link to heading")
[entity.is_alive(ent: number): boolean](https://docs.gamesense.gs/docs/api/entity/isalive)
> Returns true if the player is not dead.
### is\_dormant[](https://docs.gamesense.gs/docs/api/entity/#is_dormant "Direct link to heading")
[entity.is_dormant(ent: number): boolean](https://docs.gamesense.gs/docs/api/entity/isdormant)
> Returns true if the entity is dormant.
### is\_enemy[](https://docs.gamesense.gs/docs/api/entity/#is_enemy "Direct link to heading")
[entity.is_enemy(ent: number): boolean](https://docs.gamesense.gs/docs/api/entity/isenemy)
> Returns true if the entity is on the opposing team.
### new\_prop[](https://docs.gamesense.gs/docs/api/entity/#new_prop "Direct link to heading")
[entity.new_prop(propname: string, offset: number, type: number, array_type: number, array_element_size: number, array_count: number)](https://docs.gamesense.gs/docs/api/entity/newprop)
> Creates a new entity prop that can then be read and modified with [entity.get\_prop](https://docs.gamesense.gs/docs/api/entity/#get_prop)
> / [entity.set\_prop](https://docs.gamesense.gs/docs/api/entity/#set_prop)
> .
### set\_prop[](https://docs.gamesense.gs/docs/api/entity/#set_prop "Direct link to heading")
[entity.set_prop(ent: number, prop: string, ..., array_index: number)](https://docs.gamesense.gs/docs/api/entity/setprop)
> Sets the value of the property. For vectors or angles, pass three values.
* [Description](https://docs.gamesense.gs/docs/api/entity/#description)
* [Functions](https://docs.gamesense.gs/docs/api/entity/#functions)
* [get\_all](https://docs.gamesense.gs/docs/api/entity/#get_all)
* [get\_bounding\_box](https://docs.gamesense.gs/docs/api/entity/#get_bounding_box)
* [get\_classname](https://docs.gamesense.gs/docs/api/entity/#get_classname)
* [get\_esp\_data](https://docs.gamesense.gs/docs/api/entity/#get_esp_data)
* [get\_game\_rules](https://docs.gamesense.gs/docs/api/entity/#get_game_rules)
* [get\_local\_player](https://docs.gamesense.gs/docs/api/entity/#get_local_player)
* [get\_origin](https://docs.gamesense.gs/docs/api/entity/#get_origin)
* [get\_player\_name](https://docs.gamesense.gs/docs/api/entity/#get_player_name)
* [get\_player\_resource](https://docs.gamesense.gs/docs/api/entity/#get_player_resource)
* [get\_player\_weapon](https://docs.gamesense.gs/docs/api/entity/#get_player_weapon)
* [get\_players](https://docs.gamesense.gs/docs/api/entity/#get_players)
* [get\_prop](https://docs.gamesense.gs/docs/api/entity/#get_prop)
* [get\_steam64](https://docs.gamesense.gs/docs/api/entity/#get_steam64)
* [hitbox\_position](https://docs.gamesense.gs/docs/api/entity/#hitbox_position)
* [is\_alive](https://docs.gamesense.gs/docs/api/entity/#is_alive)
* [is\_dormant](https://docs.gamesense.gs/docs/api/entity/#is_dormant)
* [is\_enemy](https://docs.gamesense.gs/docs/api/entity/#is_enemy)
* [new\_prop](https://docs.gamesense.gs/docs/api/entity/#new_prop)
* [set\_prop](https://docs.gamesense.gs/docs/api/entity/#set_prop)
---
# entity.get_bounding_box | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/entity/getboundingbox/#docusaurus_skipToContent_fallback)
On this page
entity.get\_bounding\_box
=========================
Returns the 2D bounding box and alpha multiplier (dormant esp). The contents of x1, y1, x2, y2 must be ignored when alpha\_multiplier is zero, which indicates that the bounding box is invalid and should not be drawn.
entity.get_bounding_box(ent: number): number, number, number, number, number
Arguments[](https://docs.gamesense.gs/docs/api/entity/getboundingbox/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ent | Player entity index. | number |
Returns `x1: number, y1: number, x2: number, y2: number, alpha_multiplier: number`
* [Arguments](https://docs.gamesense.gs/docs/api/entity/getboundingbox/#arguments)
---
# assert | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/assert/#docusaurus_skipToContent_fallback)
On this page
assert
======
If the the first argument is `false` or `nil`, an error is thrown with the second argument as the message. Otherwise all the arguments are returned.
assert(expression, message: string)
Arguments[](https://docs.gamesense.gs/docs/api/G/assert/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| expression | If this is `false` or `nil`, an error is thrown. | unknown |
| message | The error message to throw. | string |
* [Arguments](https://docs.gamesense.gs/docs/api/G/assert/#arguments)
---
# error | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/error/#docusaurus_skipToContent_fallback)
On this page
error
=====
Terminates the last protected function called and outputs message as an error message. If the function containing the error is not called in a protected function (pcall), then the script which called the function will terminate. The error function itself never returns and acts like a script error. The level argument specifies how to get the error position. With level 1 (the default), the error position is where the error function was called. Level 2 points the error to where the function that called error was called; and so on. Passing a level 0 avoids the addition of error position information to the message.
error(message: string, level: number)
Arguments[](https://docs.gamesense.gs/docs/api/G/error/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| message | The error message to throw. | string |
| level | The stack level of the error. Defaults to 1. | number |
* [Arguments](https://docs.gamesense.gs/docs/api/G/error/#arguments)
---
# getfenv | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/getfenv/#docusaurus_skipToContent_fallback)
On this page
getfenv
=======
Returns the environment of the function or stack level passed to it.
getfenv(stack): table
Arguments[](https://docs.gamesense.gs/docs/api/G/getfenv/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| stack | The function to get the enviroment from. Can also be a number that specifies the function at that stack level: Level 1 is the function calling it. | function |
Returns `table`
* [Arguments](https://docs.gamesense.gs/docs/api/G/getfenv/#arguments)
---
# ffi | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ffi/#docusaurus_skipToContent_fallback)
On this page
ffi
===
Description[](https://docs.gamesense.gs/docs/api/ffi/#description "Direct link to heading")
---------------------------------------------------------------------------------------------
The FFI (foreign function interface) allows calling external C functions and using C data structures from pure Lua code.
The FFI library largely obviates the need to write tedious manual Lua/C bindings in C. No need to learn a separate binding language — **it parses plain C declarations!** These can be cut-n-pasted from C header files or reference manuals. It's up to the task of binding large libraries without the need for dealing with fragile binding generators.
The FFI library is tightly integrated into LuaJIT (it's not available as a separate module). The code generated by the JIT-compiler for accesses to C data structures from Lua code is on par with the code a C compiler would generate. Calls to C functions can be inlined in JIT-compiled code, unlike calls to functions bound via the classic Lua/C API.
caution
**No hand-holding!** The FFI library has been designed as a low-level library. The goal is to interface with C code and C data types with a minimum of overhead. This means you can do anything you can do from C: access all memory, overwrite anything in memory, call machine code at any memory address and so on. The FFI library provides no memory safety, unlike regular Lua code. It will happily allow you to dereference a `NULL` pointer, to access arrays out of bounds or to misdeclare C functions. If you make a mistake, the game might crash, just like equivalent C code would. It needs to be used with care, but it's flexibility and performance often outweigh this concern.
* [Description](https://docs.gamesense.gs/docs/api/ffi/#description)
---
# next | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/next/#docusaurus_skipToContent_fallback)
On this page
next
====
Returns the first key/value pair in the `t` table. If a key argument was specified then returns the next element in the table based on the key provided.
If the table is empty or the specified key was the last key in the array, it returns nil. This means that you can use `next(t)` to check whether a table is empty.
The order in which the indices are enumerated is not specified, even for numeric indices. To traverse an array-like table in order, use a numerical for loop or [ipairs](https://docs.gamesense.gs/docs/api/G/ipairs)
.
next(t: table, key: any): , value
Arguments[](https://docs.gamesense.gs/docs/api/G/next/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| t | The table to traverse. | table |
| key | The key to use as the start point for the traversal. If absent, the traversal starts at the first key in the table. | any |
Returns `next_key: undefined, value`
* [Arguments](https://docs.gamesense.gs/docs/api/G/next/#arguments)
---
# ipairs | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/ipairs/#docusaurus_skipToContent_fallback)
On this page
ipairs
======
Returns three values: an iterator function, the table `tbl` and the number `0`. Each time the iterator function is called, it returns the next _numerical index-value pair_ in the table.
When used in a generic for-in-loop, the return values can be used to iterate over each numerical index in the table.
ipairs(tbl: table): function, table, number
Arguments[](https://docs.gamesense.gs/docs/api/G/ipairs/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The array-like table to iterate over. | table |
Returns `function, table, number`
* [Arguments](https://docs.gamesense.gs/docs/api/G/ipairs/#arguments)
---
# pairs | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/pairs/#docusaurus_skipToContent_fallback)
On this page
pairs
=====
Returns three values: an iterator function, the table `tbl` and `nil`. Each time the iterator function is called, it returns the next _key-value pair_ in the table.
When used in a generic for-in-loop, the return values can be used to iterate over all key-value pairs in the table. The iteration order is not specified and tables do not keep their insertion order.
pairs(tbl: table): function, table, number
Arguments[](https://docs.gamesense.gs/docs/api/G/pairs/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The array-like table to iterate over. | table |
Returns `function, table, number`
* [Arguments](https://docs.gamesense.gs/docs/api/G/pairs/#arguments)
---
# load | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/load/#docusaurus_skipToContent_fallback)
On this page
load
====
Loads a chunk of Lua source code from a string or a "reader" function.
If there are no syntactic errors, returns the compiled chunk as a function; otherwise, returns `nil` plus the error message.
If chunk is a function, load calls it repeatedly to get the chunk pieces. Each call to chunk must return a string that concatenates with previous results. A return of an empty string, nil, or no value signals the end of the chunk.
load(chunk: string, chunkname: string, mode: string, env: table): function, string
Arguments[](https://docs.gamesense.gs/docs/api/G/load/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| chunk | The chunk of Lua source code to load. | string |
| chunkname | The name to associate with the chunk, used for error messages and debug information. When absent, it defaults to `chunk`, if chunk is a string, or to "=(load)" otherwise. | string |
| mode | Controls whether the chunk can be text or binary (that is, a precompiled chunk). It may be the string `"b"` (only binary chunks), `"t"` (only text chunks), or `"bt"` (both binary and text). The default is `"bt"`. | string |
| env | The environment to use for the chunk. Defaults to the current environment. | table |
Returns `function, error: string`
* [Arguments](https://docs.gamesense.gs/docs/api/G/load/#arguments)
---
# print | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/print/#docusaurus_skipToContent_fallback)
On this page
print
=====
Logs a message to the console. Equivalent to [client.log](https://docs.gamesense.gs/docs/api/client/log)
.
print(...)
Arguments[](https://docs.gamesense.gs/docs/api/G/print/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| msg | The text to log. Additional arguments will be concatenated. | string |
* [Arguments](https://docs.gamesense.gs/docs/api/G/print/#arguments)
---
# pcall | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/pcall/#docusaurus_skipToContent_fallback)
On this page
pcall
=====
Calls the function `func` in "protected mode". This means that any error inside func is not propagated; instead, pcall catches the error and returns back to the caller. If the first return value is true, the function call succeeded with no errors and the other return values will be the return values from the function. If the first return value is false, the second one will be the error message.
pcall(func, ...): boolean,
Arguments[](https://docs.gamesense.gs/docs/api/G/pcall/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| func | The function to call. | function |
| args | The arguments to pass to `func`. | unknown |
Returns `boolean, result: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/G/pcall/#arguments)
---
# printf | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/printf/#docusaurus_skipToContent_fallback)
On this page
printf
======
Logs a formatted message to the console. It accepts the same parameters as [string.format](https://www.lua.org/manual/5.1/manual.html#pdf-string.format)
printf(fmt: string, ...)
Arguments[](https://docs.gamesense.gs/docs/api/G/printf/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| fmt | Format template string | string |
| args | Arguments, depending on the format string used. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/G/printf/#arguments)
---
# getmetatable | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/getmetatable/#docusaurus_skipToContent_fallback)
On this page
getmetatable
============
Returns the metatable of the given table if it has one, otherwise returns `nil`. If t does have a metatable, and the `__metatable` metamethod is set, it returns that value instead.
getmetatable(tbl: table): table
Arguments[](https://docs.gamesense.gs/docs/api/G/getmetatable/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The table to get the metatable from. | table |
Returns `table`
* [Arguments](https://docs.gamesense.gs/docs/api/G/getmetatable/#arguments)
---
# rawequal | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/rawequal/#docusaurus_skipToContent_fallback)
On this page
rawequal
========
Checks whether `v1` is equal to `v2`, without invoking any metamethod.
rawequal(v1: any, v2: any): boolean
Arguments[](https://docs.gamesense.gs/docs/api/G/rawequal/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| v1 | The first value to compare. | any |
| v2 | The second value to compare. | any |
Returns `boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/G/rawequal/#arguments)
---
# rawget | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/rawget/#docusaurus_skipToContent_fallback)
On this page
rawget
======
Gets the raw value of a table field, without invoking any `__index` metamethod.
rawget(tbl: table, key):
Arguments[](https://docs.gamesense.gs/docs/api/G/rawget/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The table to get the field from. | table |
| key | The key to get from the table. | unknown |
Returns `value: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/G/rawget/#arguments)
---
# rawlen | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/rawlen/#docusaurus_skipToContent_fallback)
On this page
rawlen
======
Gets the raw length of a table, without invoking the `__len` metamethod.
rawlen(tbl: table): number
Arguments[](https://docs.gamesense.gs/docs/api/G/rawlen/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The table to get the length of. | table |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/G/rawlen/#arguments)
---
# readfile | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/readfile/#docusaurus_skipToContent_fallback)
On this page
readfile
========
Returns the contents of the file, or nil if the file doesn't exist.
readfile(filename: string): string
Arguments[](https://docs.gamesense.gs/docs/api/G/readfile/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| filename | The filename relative to the CS:GO directory. | string |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/G/readfile/#arguments)
---
# rawset | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/rawset/#docusaurus_skipToContent_fallback)
On this page
rawset
======
Sets the raw value of a table field, without invoking any `__newindex` metamethod.
rawset(tbl: table, key, value)
Arguments[](https://docs.gamesense.gs/docs/api/G/rawset/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The table to modify. | table |
| key | The key to set on the table. | unknown |
| value | The value to set the table key to. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/G/rawset/#arguments)
---
# require | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/require/#docusaurus_skipToContent_fallback)
On this page
require
=======
Loads a Lua module. The `package.path` is searched for the module, and the first file found is loaded. If the module returns a value, that value is returned by require, otherwise `true` is returned. Workshop libraries can be loaded using `require "gamesense/"`, if you are subscribed to them.
require(modname: string):
Arguments[](https://docs.gamesense.gs/docs/api/G/require/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| modname | The name of the module to load. | string |
Returns `module: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/G/require/#arguments)
---
# tonumber | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/tonumber/#docusaurus_skipToContent_fallback)
On this page
tonumber
========
Tries to convert its argument to a number. If the argument is a number, a string or a number cdata object convertible to a number, then `tonumber` returns this number; otherwise, it returns `nil`.
tonumber(value, base: number)
Arguments[](https://docs.gamesense.gs/docs/api/G/tonumber/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| value | The argument to convert to a number. | unknown |
| base | The base to use when converting the number. | number |
* [Arguments](https://docs.gamesense.gs/docs/api/G/tonumber/#arguments)
---
# select | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/select/#docusaurus_skipToContent_fallback)
On this page
select
======
Returns all the arguments passed to it after the index. Alternatively, if the string `"#"` is passed as the first argument, it returns the total number of arguments passed to it (including `nil`s).
select(index: number, ...)
Arguments[](https://docs.gamesense.gs/docs/api/G/select/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| index | The index of the first element, or alternatively the string `"#"`.\` | number |
| args | The arguments to select from. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/G/select/#arguments)
---
# setfenv | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/setfenv/#docusaurus_skipToContent_fallback)
On this page
setfenv
=======
Sets the environment of the given function to the given table.
setfenv(stack, env: table): function
Arguments[](https://docs.gamesense.gs/docs/api/G/setfenv/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| stack | The function to set the enviroment of. Can also be a number that specifies the function at that stack level: Level 1 is the function calling it. | function |
| env | The new environment of the function. | table |
Returns `function`
* [Arguments](https://docs.gamesense.gs/docs/api/G/setfenv/#arguments)
---
# Global Functions | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/#docusaurus_skipToContent_fallback)
On this page
Global Functions
================
Description[](https://docs.gamesense.gs/docs/api/G/#description "Direct link to heading")
-------------------------------------------------------------------------------------------
Global Lua standard library functions and miscellaneous extensions to them.
Functions[](https://docs.gamesense.gs/docs/api/G/#functions "Direct link to heading")
---------------------------------------------------------------------------------------
### assert[](https://docs.gamesense.gs/docs/api/G/#assert "Direct link to heading")
[assert(expression, message: string)](https://docs.gamesense.gs/docs/api/G/assert)
> If the the first argument is `false` or `nil`, an error is thrown with the second argument as the message. Otherwise all the arguments are returned.
### collectgarbage[](https://docs.gamesense.gs/docs/api/G/#collectgarbage "Direct link to heading")
[collectgarbage(opt: string, arg)](https://docs.gamesense.gs/docs/api/G/collectgarbage)
> This function is a generic interface to the garbage collector. It performs different functions according to its first argument, opt:
>
> * `"collect"`: performs a full garbage-collection cycle. This is the default option.
> * `"stop"`: stops the garbage collector.
> * `"restart"`: restarts the garbage collector.
> * `"count"`: returns the total memory in use by Lua (in Kbytes).
> * `"step"`: performs a garbage-collection step. The step `"size"` is controlled by arg (larger values mean more steps) in a non-specified way. If you want to control the step size you must experimentally tune the value of arg. Returns **true** if the step finished a collection cycle.
> * `"setpause"`: sets arg as the new value for the pause of the collector (see [§2.10](https://www.lua.org/manual/5.1/manual.html#2.10)
> ). Returns the previous value for pause.
> * `"setstepmul"`: sets arg as the new value for the step multiplier of the collector (see [§2.10](https://www.lua.org/manual/5.1/manual.html#2.10)
> ). Returns the previous value for step.
**Modifying garbage collector settings is generally not recommended, unless you know what you are doing.**
### defer[](https://docs.gamesense.gs/docs/api/G/#defer "Direct link to heading")
[defer(callback)](https://docs.gamesense.gs/docs/api/G/defer)
> Registers a function to be called at lua shutdown/reload, equivalent to `client.set_event_callback("shutdown", callback)`.
### error[](https://docs.gamesense.gs/docs/api/G/#error "Direct link to heading")
[error(message: string, level: number)](https://docs.gamesense.gs/docs/api/G/error)
> Terminates the last protected function called and outputs message as an error message. If the function containing the error is not called in a protected function (pcall), then the script which called the function will terminate. The error function itself never returns and acts like a script error. The level argument specifies how to get the error position. With level 1 (the default), the error position is where the error function was called. Level 2 points the error to where the function that called error was called; and so on. Passing a level 0 avoids the addition of error position information to the message.
### getfenv[](https://docs.gamesense.gs/docs/api/G/#getfenv "Direct link to heading")
[getfenv(stack): table](https://docs.gamesense.gs/docs/api/G/getfenv)
> Returns the environment of the function or stack level passed to it.
### getmetatable[](https://docs.gamesense.gs/docs/api/G/#getmetatable "Direct link to heading")
[getmetatable(tbl: table): table](https://docs.gamesense.gs/docs/api/G/getmetatable)
> Returns the metatable of the given table if it has one, otherwise returns `nil`. If t does have a metatable, and the `__metatable` metamethod is set, it returns that value instead.
### ipairs[](https://docs.gamesense.gs/docs/api/G/#ipairs "Direct link to heading")
[ipairs(tbl: table): function, table, number](https://docs.gamesense.gs/docs/api/G/ipairs)
> Returns three values: an iterator function, the table `tbl` and the number `0`. Each time the iterator function is called, it returns the next _numerical index-value pair_ in the table.
When used in a generic for-in-loop, the return values can be used to iterate over each numerical index in the table.
### load[](https://docs.gamesense.gs/docs/api/G/#load "Direct link to heading")
[load(chunk: string, chunkname: string, mode: string, env: table): function, string](https://docs.gamesense.gs/docs/api/G/load)
> Loads a chunk of Lua source code from a string or a "reader" function.
If there are no syntactic errors, returns the compiled chunk as a function; otherwise, returns `nil` plus the error message.
If chunk is a function, load calls it repeatedly to get the chunk pieces. Each call to chunk must return a string that concatenates with previous results. A return of an empty string, nil, or no value signals the end of the chunk.
### next[](https://docs.gamesense.gs/docs/api/G/#next "Direct link to heading")
[next(t: table, key: any): , value](https://docs.gamesense.gs/docs/api/G/next)
> Returns the first key/value pair in the `t` table. If a key argument was specified then returns the next element in the table based on the key provided.
If the table is empty or the specified key was the last key in the array, it returns nil. This means that you can use `next(t)` to check whether a table is empty.
The order in which the indices are enumerated is not specified, even for numeric indices. To traverse an array-like table in order, use a numerical for loop or [ipairs](https://docs.gamesense.gs/docs/api/G/ipairs)
.
### pairs[](https://docs.gamesense.gs/docs/api/G/#pairs "Direct link to heading")
[pairs(tbl: table): function, table, number](https://docs.gamesense.gs/docs/api/G/pairs)
> Returns three values: an iterator function, the table `tbl` and `nil`. Each time the iterator function is called, it returns the next _key-value pair_ in the table.
When used in a generic for-in-loop, the return values can be used to iterate over all key-value pairs in the table. The iteration order is not specified and tables do not keep their insertion order.
### pcall[](https://docs.gamesense.gs/docs/api/G/#pcall "Direct link to heading")
[pcall(func, ...): boolean,](https://docs.gamesense.gs/docs/api/G/pcall)
> Calls the function `func` in "protected mode". This means that any error inside func is not propagated; instead, pcall catches the error and returns back to the caller. If the first return value is true, the function call succeeded with no errors and the other return values will be the return values from the function. If the first return value is false, the second one will be the error message.
### print[](https://docs.gamesense.gs/docs/api/G/#print "Direct link to heading")
[print(...)](https://docs.gamesense.gs/docs/api/G/print)
> Logs a message to the console. Equivalent to [client.log](https://docs.gamesense.gs/docs/api/client/log)
> .
### printf[](https://docs.gamesense.gs/docs/api/G/#printf "Direct link to heading")
[printf(fmt: string, ...)](https://docs.gamesense.gs/docs/api/G/printf)
> Logs a formatted message to the console. It accepts the same parameters as [string.format](https://www.lua.org/manual/5.1/manual.html#pdf-string.format)
### rawequal[](https://docs.gamesense.gs/docs/api/G/#rawequal "Direct link to heading")
[rawequal(v1: any, v2: any): boolean](https://docs.gamesense.gs/docs/api/G/rawequal)
> Checks whether `v1` is equal to `v2`, without invoking any metamethod.
### rawget[](https://docs.gamesense.gs/docs/api/G/#rawget "Direct link to heading")
[rawget(tbl: table, key):](https://docs.gamesense.gs/docs/api/G/rawget)
> Gets the raw value of a table field, without invoking any `__index` metamethod.
### rawlen[](https://docs.gamesense.gs/docs/api/G/#rawlen "Direct link to heading")
[rawlen(tbl: table): number](https://docs.gamesense.gs/docs/api/G/rawlen)
> Gets the raw length of a table, without invoking the `__len` metamethod.
### rawset[](https://docs.gamesense.gs/docs/api/G/#rawset "Direct link to heading")
[rawset(tbl: table, key, value)](https://docs.gamesense.gs/docs/api/G/rawset)
> Sets the raw value of a table field, without invoking any `__newindex` metamethod.
### readfile[](https://docs.gamesense.gs/docs/api/G/#readfile "Direct link to heading")
[readfile(filename: string): string](https://docs.gamesense.gs/docs/api/G/readfile)
> Returns the contents of the file, or nil if the file doesn't exist.
### require[](https://docs.gamesense.gs/docs/api/G/#require "Direct link to heading")
[require(modname: string):](https://docs.gamesense.gs/docs/api/G/require)
> Loads a Lua module. The `package.path` is searched for the module, and the first file found is loaded. If the module returns a value, that value is returned by require, otherwise `true` is returned. Workshop libraries can be loaded using `require "gamesense/"`, if you are subscribed to them.
### select[](https://docs.gamesense.gs/docs/api/G/#select "Direct link to heading")
[select(index: number, ...)](https://docs.gamesense.gs/docs/api/G/select)
> Returns all the arguments passed to it after the index. Alternatively, if the string `"#"` is passed as the first argument, it returns the total number of arguments passed to it (including `nil`s).
### setfenv[](https://docs.gamesense.gs/docs/api/G/#setfenv "Direct link to heading")
[setfenv(stack, env: table): function](https://docs.gamesense.gs/docs/api/G/setfenv)
> Sets the environment of the given function to the given table.
### setmetatable[](https://docs.gamesense.gs/docs/api/G/#setmetatable "Direct link to heading")
[setmetatable(tbl: table, metatable: table)](https://docs.gamesense.gs/docs/api/G/setmetatable)
> Sets the metatable of the given table `tbl` to `metatable`. If `metatable` is nil, the metatable of t is removed. Finally, this function returns the table `tbl` which was passed to it. If `tbl` already has a metatable whose `__metatable` metamethod is set, calling this on `tbl` raises an error.
### tonumber[](https://docs.gamesense.gs/docs/api/G/#tonumber "Direct link to heading")
[tonumber(value, base: number)](https://docs.gamesense.gs/docs/api/G/tonumber)
> Tries to convert its argument to a number. If the argument is a number, a string or a number cdata object convertible to a number, then `tonumber` returns this number; otherwise, it returns `nil`.
### tostring[](https://docs.gamesense.gs/docs/api/G/#tostring "Direct link to heading")
[tostring(value): string](https://docs.gamesense.gs/docs/api/G/tostring)
> Receives an argument of any type and converts it to a string in a reasonable format. For complete control of how numbers are converted, use `string.format`. If the metatable of `value` has a `__tostring` metamethod, then it will be called with `value` as the only argument and will return the result.
### toticks[](https://docs.gamesense.gs/docs/api/G/#toticks "Direct link to heading")
[toticks(time: number): number](https://docs.gamesense.gs/docs/api/G/toticks)
> Converts time (seconds) to ticks.
### totime[](https://docs.gamesense.gs/docs/api/G/#totime "Direct link to heading")
[totime(ticks: number): number](https://docs.gamesense.gs/docs/api/G/totime)
> Converts ticks to time. Return value is in seconds.
### type[](https://docs.gamesense.gs/docs/api/G/#type "Direct link to heading")
[type(value): string](https://docs.gamesense.gs/docs/api/G/type)
> Returns the type of its only argument, coded as a string. The possible results of this function are `"nil"` (a string, not the value nil), `"number"`, `"string"`, `"boolean"`, `"table"`, `"function"`, `"thread"`, and `"userdata"`.
### unpack[](https://docs.gamesense.gs/docs/api/G/#unpack "Direct link to heading")
[unpack(tbl: table, i: number, j: number):](https://docs.gamesense.gs/docs/api/G/unpack)
> Returns the items with numeric keys from the given table `tbl`, from `i` to `j`.
### vtable\_bind[](https://docs.gamesense.gs/docs/api/G/#vtable_bind "Direct link to heading")
[vtable_bind(module_name: string, interface_name: string, index: number, typestring: string, ...): function](https://docs.gamesense.gs/docs/api/G/vtablebind)
> Utility for calling virtual functions on FFI objects. This variant works with Interfaces and doesn't require passing the this-pointer as the first argument every time.
### vtable\_thunk[](https://docs.gamesense.gs/docs/api/G/#vtable_thunk "Direct link to heading")
[vtable_thunk(index: number, typestring: string, ...): function](https://docs.gamesense.gs/docs/api/G/vtablethunk)
> Utility for calling virtual functions on FFI objects. This variant takes the this-pointer as the first argument and grabs the virtual function from it when called.
### writefile[](https://docs.gamesense.gs/docs/api/G/#writefile "Direct link to heading")
[writefile(filename: string, text: string)](https://docs.gamesense.gs/docs/api/G/writefile)
> Overwrites the file with the passed text. The file is created if it doesn't exist.
### xpcall[](https://docs.gamesense.gs/docs/api/G/#xpcall "Direct link to heading")
[xpcall(func, handler, ...): boolean,](https://docs.gamesense.gs/docs/api/G/xpcall)
> Calls the function `func` in "protected mode". This means that any error inside func is not propagated; instead, `xpcall` catches the error, calls the "error handler" function passed to it, then returns back to the caller. If the first return value is true, the function call succeeded with no errors and the other return values will be the return values from the function. If the first return value is false, the second one will be the error message.
* [Description](https://docs.gamesense.gs/docs/api/G/#description)
* [Functions](https://docs.gamesense.gs/docs/api/G/#functions)
* [assert](https://docs.gamesense.gs/docs/api/G/#assert)
* [collectgarbage](https://docs.gamesense.gs/docs/api/G/#collectgarbage)
* [defer](https://docs.gamesense.gs/docs/api/G/#defer)
* [error](https://docs.gamesense.gs/docs/api/G/#error)
* [getfenv](https://docs.gamesense.gs/docs/api/G/#getfenv)
* [getmetatable](https://docs.gamesense.gs/docs/api/G/#getmetatable)
* [ipairs](https://docs.gamesense.gs/docs/api/G/#ipairs)
* [load](https://docs.gamesense.gs/docs/api/G/#load)
* [next](https://docs.gamesense.gs/docs/api/G/#next)
* [pairs](https://docs.gamesense.gs/docs/api/G/#pairs)
* [pcall](https://docs.gamesense.gs/docs/api/G/#pcall)
* [print](https://docs.gamesense.gs/docs/api/G/#print)
* [printf](https://docs.gamesense.gs/docs/api/G/#printf)
* [rawequal](https://docs.gamesense.gs/docs/api/G/#rawequal)
* [rawget](https://docs.gamesense.gs/docs/api/G/#rawget)
* [rawlen](https://docs.gamesense.gs/docs/api/G/#rawlen)
* [rawset](https://docs.gamesense.gs/docs/api/G/#rawset)
* [readfile](https://docs.gamesense.gs/docs/api/G/#readfile)
* [require](https://docs.gamesense.gs/docs/api/G/#require)
* [select](https://docs.gamesense.gs/docs/api/G/#select)
* [setfenv](https://docs.gamesense.gs/docs/api/G/#setfenv)
* [setmetatable](https://docs.gamesense.gs/docs/api/G/#setmetatable)
* [tonumber](https://docs.gamesense.gs/docs/api/G/#tonumber)
* [tostring](https://docs.gamesense.gs/docs/api/G/#tostring)
* [toticks](https://docs.gamesense.gs/docs/api/G/#toticks)
* [totime](https://docs.gamesense.gs/docs/api/G/#totime)
* [type](https://docs.gamesense.gs/docs/api/G/#type)
* [unpack](https://docs.gamesense.gs/docs/api/G/#unpack)
* [vtable\_bind](https://docs.gamesense.gs/docs/api/G/#vtable_bind)
* [vtable\_thunk](https://docs.gamesense.gs/docs/api/G/#vtable_thunk)
* [writefile](https://docs.gamesense.gs/docs/api/G/#writefile)
* [xpcall](https://docs.gamesense.gs/docs/api/G/#xpcall)
---
# tostring | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/tostring/#docusaurus_skipToContent_fallback)
On this page
tostring
========
Receives an argument of any type and converts it to a string in a reasonable format. For complete control of how numbers are converted, use `string.format`. If the metatable of `value` has a `__tostring` metamethod, then it will be called with `value` as the only argument and will return the result.
tostring(value): string
Arguments[](https://docs.gamesense.gs/docs/api/G/tostring/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| value | The value to convert to a string. | unknown |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/G/tostring/#arguments)
---
# setmetatable | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/setmetatable/#docusaurus_skipToContent_fallback)
On this page
setmetatable
============
Sets the metatable of the given table `tbl` to `metatable`. If `metatable` is nil, the metatable of t is removed. Finally, this function returns the table `tbl` which was passed to it. If `tbl` already has a metatable whose `__metatable` metamethod is set, calling this on `tbl` raises an error.
setmetatable(tbl: table, metatable: table)
Arguments[](https://docs.gamesense.gs/docs/api/G/setmetatable/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The table to set the metatable of. | table |
| metatable | The new metatable | table |
* [Arguments](https://docs.gamesense.gs/docs/api/G/setmetatable/#arguments)
---
# toticks | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/toticks/#docusaurus_skipToContent_fallback)
On this page
toticks
=======
Converts time (seconds) to ticks.
toticks(time: number): number
Arguments[](https://docs.gamesense.gs/docs/api/G/toticks/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| time | The seconds to convert to ticks. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/G/toticks/#arguments)
---
# unpack | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/unpack/#docusaurus_skipToContent_fallback)
On this page
unpack
======
Returns the items with numeric keys from the given table `tbl`, from `i` to `j`.
unpack(tbl: table, i: number, j: number):
Arguments[](https://docs.gamesense.gs/docs/api/G/unpack/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tbl | The table to unpack. | table |
| i | The index of the first element to return. | number |
| j | The index of the last element to return. | number |
Returns `elements: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/G/unpack/#arguments)
---
# totime | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/totime/#docusaurus_skipToContent_fallback)
On this page
totime
======
Converts ticks to time. Return value is in seconds.
totime(ticks: number): number
Arguments[](https://docs.gamesense.gs/docs/api/G/totime/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| ticks | The number of ticks to convert to time. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/G/totime/#arguments)
---
# type | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/type/#docusaurus_skipToContent_fallback)
On this page
type
====
Returns the type of its only argument, coded as a string. The possible results of this function are `"nil"` (a string, not the value nil), `"number"`, `"string"`, `"boolean"`, `"table"`, `"function"`, `"thread"`, and `"userdata"`.
type(value): string
Arguments[](https://docs.gamesense.gs/docs/api/G/type/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| value | The value to get the type of. | unknown |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/G/type/#arguments)
---
# vtable_thunk | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/vtablethunk/#docusaurus_skipToContent_fallback)
On this page
vtable\_thunk
=============
Utility for calling virtual functions on FFI objects. This variant takes the this-pointer as the first argument and grabs the virtual function from it when called.
vtable_thunk(index: number, typestring: string, ...): function
Arguments[](https://docs.gamesense.gs/docs/api/G/vtablethunk/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| index | Index of the virtual function | number |
| typestring | A FFI type string, such as `"int(__thiscall*)(void*, int)"` | string |
| args | Additional arguments for the type (for use with [parameterized types](https://luajit.org/ext_ffi_semantics.html#:~:text=could%20possibly%20provide.-,Parameterized,-Types)
) | unknown |
Returns `function`
* [Arguments](https://docs.gamesense.gs/docs/api/G/vtablethunk/#arguments)
---
# vtable_bind | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/vtablebind/#docusaurus_skipToContent_fallback)
On this page
vtable\_bind
============
Utility for calling virtual functions on FFI objects. This variant works with Interfaces and doesn't require passing the this-pointer as the first argument every time.
vtable_bind(module_name: string, interface_name: string, index: number, typestring: string, ...): function
Arguments[](https://docs.gamesense.gs/docs/api/G/vtablebind/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| module\_name | Filename of the module that contains the interface | string |
| interface\_name | Name of the interface | string |
| index | Index of the virtual function | number |
| typestring | A FFI type string, such as `"int(__thiscall*)(void*, int)"` | string |
| args | Additional arguments for the type (for use with [parameterized types](https://luajit.org/ext_ffi_semantics.html#:~:text=could%20possibly%20provide.-,Parameterized,-Types)
) | unknown |
Returns `function`
* [Arguments](https://docs.gamesense.gs/docs/api/G/vtablebind/#arguments)
---
# writefile | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/writefile/#docusaurus_skipToContent_fallback)
On this page
info
Usually the [database API](https://docs.gamesense.gs/docs/api/database)
is a better choice for persistent storage.
writefile
=========
Overwrites the file with the passed text. The file is created if it doesn't exist.
writefile(filename: string, text: string)
Arguments[](https://docs.gamesense.gs/docs/api/G/writefile/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| filename | The filename relative to the CS:GO directory. | string |
| text | The text to write to the file. | string |
* [Arguments](https://docs.gamesense.gs/docs/api/G/writefile/#arguments)
---
# globals.chokedcommands | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/chokedcommands/#docusaurus_skipToContent_fallback)
globals.chokedcommands
======================
The number of choked commands (commands that haven't yet been sent to the server, for example due to fake lag)
globals.chokedcommands(): number
Returns `number`
---
# globals.absoluteframetime | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/absoluteframetime/#docusaurus_skipToContent_fallback)
globals.absoluteframetime
=========================
The absolute time the last frame took to render.
globals.absoluteframetime(): number
Returns `number`
---
# globals.commandack | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/commandack/#docusaurus_skipToContent_fallback)
globals.commandack
==================
The command number of the most recent server-acknowledged command.
globals.commandack(): number
Returns `number`
---
# xpcall | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/G/xpcall/#docusaurus_skipToContent_fallback)
On this page
xpcall
======
Calls the function `func` in "protected mode". This means that any error inside func is not propagated; instead, `xpcall` catches the error, calls the "error handler" function passed to it, then returns back to the caller. If the first return value is true, the function call succeeded with no errors and the other return values will be the return values from the function. If the first return value is false, the second one will be the error message.
xpcall(func, handler, ...): boolean,
Arguments[](https://docs.gamesense.gs/docs/api/G/xpcall/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| func | The function to call. | function |
| handler | The error handler function, called when the function fails, called with the error message. You can for example use `client.error_log` to simply log the error to the console | function |
| args | The arguments to pass to `func`. | unknown |
Returns `boolean, result: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/G/xpcall/#arguments)
---
# globals.curtime | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/curtime/#docusaurus_skipToContent_fallback)
globals.curtime
===============
The elapsed game time in seconds. This number is synchronized with the server.
globals.curtime(): number
Returns `number`
---
# globals.framecount | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/framecount/#docusaurus_skipToContent_fallback)
globals.framecount
==================
The number of frames rendered since the game started
globals.framecount(): number
Returns `number`
---
# globals.frametime | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/frametime/#docusaurus_skipToContent_fallback)
globals.frametime
=================
The time the last frame took to render.
globals.frametime(): number
Returns `number`
---
# globals.mapname | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/mapname/#docusaurus_skipToContent_fallback)
globals.mapname
===============
The name of the loaded map, or nil if you are not in game.
globals.mapname(): string
Returns `string`
---
# globals.lastoutgoingcommand | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/lastoutgoingcommand/#docusaurus_skipToContent_fallback)
globals.lastoutgoingcommand
===========================
The command number of the most recent sent command.
globals.lastoutgoingcommand(): number
Returns `number`
---
# globals | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/#docusaurus_skipToContent_fallback)
On this page
globals
=======
Description[](https://docs.gamesense.gs/docs/api/globals/#description "Direct link to heading")
-------------------------------------------------------------------------------------------------
Global variables used by the source engine.
Functions[](https://docs.gamesense.gs/docs/api/globals/#functions "Direct link to heading")
---------------------------------------------------------------------------------------------
### absoluteframetime[](https://docs.gamesense.gs/docs/api/globals/#absoluteframetime "Direct link to heading")
[globals.absoluteframetime(): number](https://docs.gamesense.gs/docs/api/globals/absoluteframetime)
> The absolute time the last frame took to render.
### chokedcommands[](https://docs.gamesense.gs/docs/api/globals/#chokedcommands "Direct link to heading")
[globals.chokedcommands(): number](https://docs.gamesense.gs/docs/api/globals/chokedcommands)
> The number of choked commands (commands that haven't yet been sent to the server, for example due to fake lag)
### commandack[](https://docs.gamesense.gs/docs/api/globals/#commandack "Direct link to heading")
[globals.commandack(): number](https://docs.gamesense.gs/docs/api/globals/commandack)
> The command number of the most recent server-acknowledged command.
### curtime[](https://docs.gamesense.gs/docs/api/globals/#curtime "Direct link to heading")
[globals.curtime(): number](https://docs.gamesense.gs/docs/api/globals/curtime)
> The elapsed game time in seconds. This number is synchronized with the server.
### framecount[](https://docs.gamesense.gs/docs/api/globals/#framecount "Direct link to heading")
[globals.framecount(): number](https://docs.gamesense.gs/docs/api/globals/framecount)
> The number of frames rendered since the game started
### frametime[](https://docs.gamesense.gs/docs/api/globals/#frametime "Direct link to heading")
[globals.frametime(): number](https://docs.gamesense.gs/docs/api/globals/frametime)
> The time the last frame took to render.
### lastoutgoingcommand[](https://docs.gamesense.gs/docs/api/globals/#lastoutgoingcommand "Direct link to heading")
[globals.lastoutgoingcommand(): number](https://docs.gamesense.gs/docs/api/globals/lastoutgoingcommand)
> The command number of the most recent sent command.
### mapname[](https://docs.gamesense.gs/docs/api/globals/#mapname "Direct link to heading")
[globals.mapname(): string](https://docs.gamesense.gs/docs/api/globals/mapname)
> The name of the loaded map, or nil if you are not in game.
### maxplayers[](https://docs.gamesense.gs/docs/api/globals/#maxplayers "Direct link to heading")
[globals.maxplayers(): number](https://docs.gamesense.gs/docs/api/globals/maxplayers)
> The maximum number of players in a game (usually 64)
### oldcommandack[](https://docs.gamesense.gs/docs/api/globals/#oldcommandack "Direct link to heading")
[globals.oldcommandack(): number](https://docs.gamesense.gs/docs/api/globals/oldcommandack)
> The command number of the previous server-acknowledged command.
### realtime[](https://docs.gamesense.gs/docs/api/globals/#realtime "Direct link to heading")
[globals.realtime(): number](https://docs.gamesense.gs/docs/api/globals/realtime)
> The time in seconds since the game was started.
### servertickcount[](https://docs.gamesense.gs/docs/api/globals/#servertickcount "Direct link to heading")
[globals.servertickcount(): number](https://docs.gamesense.gs/docs/api/globals/servertickcount)
> Returns the most recently receieved tick from the server.
### tickcount[](https://docs.gamesense.gs/docs/api/globals/#tickcount "Direct link to heading")
[globals.tickcount(): number](https://docs.gamesense.gs/docs/api/globals/tickcount)
> The number of ticks elapsed on the server.
### tickinterval[](https://docs.gamesense.gs/docs/api/globals/#tickinterval "Direct link to heading")
[globals.tickinterval(): number](https://docs.gamesense.gs/docs/api/globals/tickinterval)
> The time between ticks in seconds, 1/64 for 64 tick.
* [Description](https://docs.gamesense.gs/docs/api/globals/#description)
* [Functions](https://docs.gamesense.gs/docs/api/globals/#functions)
* [absoluteframetime](https://docs.gamesense.gs/docs/api/globals/#absoluteframetime)
* [chokedcommands](https://docs.gamesense.gs/docs/api/globals/#chokedcommands)
* [commandack](https://docs.gamesense.gs/docs/api/globals/#commandack)
* [curtime](https://docs.gamesense.gs/docs/api/globals/#curtime)
* [framecount](https://docs.gamesense.gs/docs/api/globals/#framecount)
* [frametime](https://docs.gamesense.gs/docs/api/globals/#frametime)
* [lastoutgoingcommand](https://docs.gamesense.gs/docs/api/globals/#lastoutgoingcommand)
* [mapname](https://docs.gamesense.gs/docs/api/globals/#mapname)
* [maxplayers](https://docs.gamesense.gs/docs/api/globals/#maxplayers)
* [oldcommandack](https://docs.gamesense.gs/docs/api/globals/#oldcommandack)
* [realtime](https://docs.gamesense.gs/docs/api/globals/#realtime)
* [servertickcount](https://docs.gamesense.gs/docs/api/globals/#servertickcount)
* [tickcount](https://docs.gamesense.gs/docs/api/globals/#tickcount)
* [tickinterval](https://docs.gamesense.gs/docs/api/globals/#tickinterval)
---
# globals.maxplayers | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/maxplayers/#docusaurus_skipToContent_fallback)
globals.maxplayers
==================
The maximum number of players in a game (usually 64)
globals.maxplayers(): number
Returns `number`
---
# globals.realtime | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/realtime/#docusaurus_skipToContent_fallback)
globals.realtime
================
The time in seconds since the game was started.
globals.realtime(): number
Returns `number`
---
# globals.oldcommandack | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/oldcommandack/#docusaurus_skipToContent_fallback)
globals.oldcommandack
=====================
The command number of the previous server-acknowledged command.
globals.oldcommandack(): number
Returns `number`
---
# globals.servertickcount | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/servertickcount/#docusaurus_skipToContent_fallback)
globals.servertickcount
=======================
Returns the most recently receieved tick from the server.
globals.servertickcount(): number
Returns `number`
---
# globals.tickinterval | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/tickinterval/#docusaurus_skipToContent_fallback)
globals.tickinterval
====================
The time between ticks in seconds, 1/64 for 64 tick.
globals.tickinterval(): number
Returns `number`
---
# json.decode_invalid_numbers | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/decodeinvalidnumbers/#docusaurus_skipToContent_fallback)
On this page
json.decode\_invalid\_numbers
=============================
[json.parse](https://docs.gamesense.gs/docs/api/json/decodeinvalidnumbers/#parse)
may generate an error when trying to decode numbers not supported by the JSON specification. _Invalid numbers_ are defined as: infinity, not-a-number (NaN) and hexadecimal
Available settings: `true` - Accept and decode invalid numbers. This is the default setting. `false` - Throw an error when invalid numbers are encountered.
The current setting is always returned, and is only updated when an argument is provided.
json.decode_invalid_numbers(setting: boolean): boolean
Arguments[](https://docs.gamesense.gs/docs/api/json/decodeinvalidnumbers/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| setting | The new setting. `true` to accept and decode invalid numbers, `false` to throw an error. | boolean |
Returns `old_setting: boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/json/decodeinvalidnumbers/#arguments)
---
# json.encode_invalid_numbers | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/encodeinvalidnumbers/#docusaurus_skipToContent_fallback)
On this page
json.encode\_invalid\_numbers
=============================
[json.stringify](https://docs.gamesense.gs/docs/api/json/encodeinvalidnumbers/#stringify)
may generate an error when encoding floating point numbers not supported by the JSON specification such as `Infinity` and `NaN`. This behavior can be changed by calling this function.
Available settings: `true` - Allow invalid numbers to be encoded. This will generate non-standard JSON, but this output is supported by some libraries. `false` - Throw an error when attempting to encode invalid numbers. This is the default setting. `"null"` - Encode invalid numbers as a JSON null value. This allows infinity and NaN to be encoded into valid JSON.
The current setting is always returned, and is only updated when an argument is provided.
json.encode_invalid_numbers(setting): boolean
Arguments[](https://docs.gamesense.gs/docs/api/json/encodeinvalidnumbers/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| setting | The new setting. | unknown |
Returns `old_setting: boolean`
* [Arguments](https://docs.gamesense.gs/docs/api/json/encodeinvalidnumbers/#arguments)
---
# json.decode_max_depth | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/decodemaxdepth/#docusaurus_skipToContent_fallback)
On this page
json.decode\_max\_depth
=======================
[json.parse](https://docs.gamesense.gs/docs/api/json/decodemaxdepth/#parse)
will generate an error when parsing deeply nested JSON once the maximum array/object depth has been exceeded. This check prevents unnecessarily complicated JSON from slowing down the application, or crashing the application due to lack of process stack space.
An error may be generated before the depth limit is hit if Lua is unable to allocate more objects on the Lua stack. By default, [json.parse](https://docs.gamesense.gs/docs/api/json/decodemaxdepth/#parse)
will reject JSON with arrays and/or objects nested more than 1000 levels deep.
The current setting is always returned, and is only updated when an argument is provided.
json.decode_max_depth(depth: number): number
Arguments[](https://docs.gamesense.gs/docs/api/json/decodemaxdepth/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| depth | Must be a positive integer. Default: 1000. | number |
Returns `old_depth: number`
* [Arguments](https://docs.gamesense.gs/docs/api/json/decodemaxdepth/#arguments)
---
# json.encode_max_depth | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/encodemaxdepth/#docusaurus_skipToContent_fallback)
On this page
json.encode\_max\_depth
=======================
[json.stringify](https://docs.gamesense.gs/docs/api/json/encodemaxdepth/#stringify)
will generate an error when encoding deeply nested JSON once the maximum table depth has been exceeded. This check prevents unnecessarily complicated JSON from slowing down the application, or crashing the application due to lack of process stack space.
By default, [json.stringify](https://docs.gamesense.gs/docs/api/json/encodemaxdepth/#stringify)
will reject JSON with more than 1000 nested tables.
The current setting is always returned, and is only updated when an argument is provided.
json.encode_max_depth(depth: number): number
Arguments[](https://docs.gamesense.gs/docs/api/json/encodemaxdepth/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| depth | Must be a positive integer. Default: 1000. | number |
Returns `old_depth: number`
* [Arguments](https://docs.gamesense.gs/docs/api/json/encodemaxdepth/#arguments)
---
# json.encode_number_precision | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/encodenumberprecision/#docusaurus_skipToContent_fallback)
On this page
json.encode\_number\_precision
==============================
The amount of significant digits returned by [json.stringify](https://docs.gamesense.gs/docs/api/json/encodenumberprecision/#stringify)
when encoding numbers can be changed to balance accuracy versus performance. For data structures containing many numbers, setting json.encode\_number\_precision to a smaller integer, for example 3, can improve encoding performance by up to 50%. By default, Lua CJSON will output 14 significant digits when converting a number to text.
The current setting is always returned, and is only updated when an argument is provided.
json.encode_number_precision(precision: number): number
Arguments[](https://docs.gamesense.gs/docs/api/json/encodenumberprecision/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| precision | Must be a positive integer. Default: 14. | number |
Returns `old_precision: number`
* [Arguments](https://docs.gamesense.gs/docs/api/json/encodenumberprecision/#arguments)
---
# json | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/#docusaurus_skipToContent_fallback)
On this page
json
====
Description[](https://docs.gamesense.gs/docs/api/json/#description "Direct link to heading")
----------------------------------------------------------------------------------------------
A [JSON](https://www.w3schools.com/js/js_json_intro.asp)
parser and serializer library. Slightly modified version of [Lua CJSON](https://www.kyne.com.au/~mark/software/lua-cjson.php)
.
Useful tools: [JSON Formatter / Validator](https://jsonformatter.curiousconcept.com/)
- [JSON Tree Viewer](http://jsonviewer.stack.hu/)
Functions[](https://docs.gamesense.gs/docs/api/json/#functions "Direct link to heading")
------------------------------------------------------------------------------------------
### decode\_invalid\_numbers[](https://docs.gamesense.gs/docs/api/json/#decode_invalid_numbers "Direct link to heading")
[json.decode_invalid_numbers(setting: boolean): boolean](https://docs.gamesense.gs/docs/api/json/decodeinvalidnumbers)
> [json.parse](https://docs.gamesense.gs/docs/api/json/#parse)
> may generate an error when trying to decode numbers not supported by the JSON specification. _Invalid numbers_ are defined as: infinity, not-a-number (NaN) and hexadecimal
Available settings: `true` - Accept and decode invalid numbers. This is the default setting. `false` - Throw an error when invalid numbers are encountered.
The current setting is always returned, and is only updated when an argument is provided.
### decode\_max\_depth[](https://docs.gamesense.gs/docs/api/json/#decode_max_depth "Direct link to heading")
[json.decode_max_depth(depth: number): number](https://docs.gamesense.gs/docs/api/json/decodemaxdepth)
> [json.parse](https://docs.gamesense.gs/docs/api/json/#parse)
> will generate an error when parsing deeply nested JSON once the maximum array/object depth has been exceeded. This check prevents unnecessarily complicated JSON from slowing down the application, or crashing the application due to lack of process stack space.
An error may be generated before the depth limit is hit if Lua is unable to allocate more objects on the Lua stack. By default, [json.parse](https://docs.gamesense.gs/docs/api/json/#parse)
will reject JSON with arrays and/or objects nested more than 1000 levels deep.
The current setting is always returned, and is only updated when an argument is provided.
### encode\_invalid\_numbers[](https://docs.gamesense.gs/docs/api/json/#encode_invalid_numbers "Direct link to heading")
[json.encode_invalid_numbers(setting): boolean](https://docs.gamesense.gs/docs/api/json/encodeinvalidnumbers)
> [json.stringify](https://docs.gamesense.gs/docs/api/json/#stringify)
> may generate an error when encoding floating point numbers not supported by the JSON specification such as `Infinity` and `NaN`. This behavior can be changed by calling this function.
Available settings: `true` - Allow invalid numbers to be encoded. This will generate non-standard JSON, but this output is supported by some libraries. `false` - Throw an error when attempting to encode invalid numbers. This is the default setting. `"null"` - Encode invalid numbers as a JSON null value. This allows infinity and NaN to be encoded into valid JSON.
The current setting is always returned, and is only updated when an argument is provided.
### encode\_max\_depth[](https://docs.gamesense.gs/docs/api/json/#encode_max_depth "Direct link to heading")
[json.encode_max_depth(depth: number): number](https://docs.gamesense.gs/docs/api/json/encodemaxdepth)
> [json.stringify](https://docs.gamesense.gs/docs/api/json/#stringify)
> will generate an error when encoding deeply nested JSON once the maximum table depth has been exceeded. This check prevents unnecessarily complicated JSON from slowing down the application, or crashing the application due to lack of process stack space.
By default, [json.stringify](https://docs.gamesense.gs/docs/api/json/#stringify)
will reject JSON with more than 1000 nested tables.
The current setting is always returned, and is only updated when an argument is provided.
### encode\_number\_precision[](https://docs.gamesense.gs/docs/api/json/#encode_number_precision "Direct link to heading")
[json.encode_number_precision(precision: number): number](https://docs.gamesense.gs/docs/api/json/encodenumberprecision)
> The amount of significant digits returned by [json.stringify](https://docs.gamesense.gs/docs/api/json/#stringify)
> when encoding numbers can be changed to balance accuracy versus performance. For data structures containing many numbers, setting json.encode\_number\_precision to a smaller integer, for example 3, can improve encoding performance by up to 50%. By default, Lua CJSON will output 14 significant digits when converting a number to text.
The current setting is always returned, and is only updated when an argument is provided.
### encode\_sparse\_array[](https://docs.gamesense.gs/docs/api/json/#encode_sparse_array "Direct link to heading")
[json.encode_sparse_array()](https://docs.gamesense.gs/docs/api/json/encodesparsearray)
> [json.stringify](https://docs.gamesense.gs/docs/api/json/#stringify)
> classifies a Lua table into one of three kinds when encoding a JSON array. This is determined by the number of values missing from the Lua array as follows:
Normal: All values are available. Sparse: At least 1 value is missing. Excessively sparse: The number of values missing exceeds the configured ratio.
It encodes sparse Lua arrays as JSON arrays using JSON `null` for the missing entries. An array is excessively sparse when all the following conditions are met: `ratio > 0`, `maximum_index > safe`, `maximum_index > item_count * ratio`
JSON will never consider an array to be excessively sparse when `ratio` = `0`. The `safe` limit ensures that small Lua arrays are always encoded as sparse arrays. By default, attempting to encode an _excessively sparse_ array will generate an error. If `convert` is set to true, excessively sparse arrays will be converted to a JSON object.
The current settings are always returned. A particular setting is only changed when the argument is provided (non-`nil`).
### parse[](https://docs.gamesense.gs/docs/api/json/#parse "Direct link to heading")
[json.parse(json_text: string):](https://docs.gamesense.gs/docs/api/json/parse)
> Parses a UTF-8 JSON string into a Lua object (table, number, string, etc).
UTF-16 and UTF-32 JSON strings are not supported. All escape codes will be decoded and other bytes will be passed transparently. JSON `null` will be converted to a NULL `lightuserdata` value. This can be compared with `json.null` for convenience.
By default, numbers incompatible with the JSON specification (`infinity`, `NaN`, hexadecimal) can be parsed. This default can be changed with [json.decode\_invalid\_numbers](https://docs.gamesense.gs/docs/api/json/#decode_invalid_numbers)
.
### stringify[](https://docs.gamesense.gs/docs/api/json/#stringify "Direct link to heading")
[json.stringify(object): string](https://docs.gamesense.gs/docs/api/json/stringify)
> Serializes a Lua object into a JSON string.
It supports the following types: `boolean`, `nil`, `number`, `string`, `table`
The remaining Lua types will generate an error: `function`, `lightuserdata`, `thread`, `userdata`
By default, numbers are encoded with 14 significant digits. Refer to [json.encode\_number\_precision](https://docs.gamesense.gs/docs/api/json/#encode_number_precision)
for details.
!!!warning This function will successfully encode/decode binary strings, but this is technically not supported by JSON and may not be compatible with other JSON libraries. To ensure the output is valid JSON, applications should ensure all Lua strings passed to `json.stringify` are UTF-8. Base64 is commonly used to encode binary data as the most efficient encoding under UTF-8 can only reduce the encoded size by a further ~8%. !!!
* [Description](https://docs.gamesense.gs/docs/api/json/#description)
* [Functions](https://docs.gamesense.gs/docs/api/json/#functions)
* [decode\_invalid\_numbers](https://docs.gamesense.gs/docs/api/json/#decode_invalid_numbers)
* [decode\_max\_depth](https://docs.gamesense.gs/docs/api/json/#decode_max_depth)
* [encode\_invalid\_numbers](https://docs.gamesense.gs/docs/api/json/#encode_invalid_numbers)
* [encode\_max\_depth](https://docs.gamesense.gs/docs/api/json/#encode_max_depth)
* [encode\_number\_precision](https://docs.gamesense.gs/docs/api/json/#encode_number_precision)
* [encode\_sparse\_array](https://docs.gamesense.gs/docs/api/json/#encode_sparse_array)
* [parse](https://docs.gamesense.gs/docs/api/json/#parse)
* [stringify](https://docs.gamesense.gs/docs/api/json/#stringify)
---
# json.encode_sparse_array | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/encodesparsearray/#docusaurus_skipToContent_fallback)
json.encode\_sparse\_array
==========================
[json.stringify](https://docs.gamesense.gs/docs/api/json/encodesparsearray/#stringify)
classifies a Lua table into one of three kinds when encoding a JSON array. This is determined by the number of values missing from the Lua array as follows:
Normal: All values are available. Sparse: At least 1 value is missing. Excessively sparse: The number of values missing exceeds the configured ratio.
It encodes sparse Lua arrays as JSON arrays using JSON `null` for the missing entries. An array is excessively sparse when all the following conditions are met: `ratio > 0`, `maximum_index > safe`, `maximum_index > item_count * ratio`
JSON will never consider an array to be excessively sparse when `ratio` = `0`. The `safe` limit ensures that small Lua arrays are always encoded as sparse arrays. By default, attempting to encode an _excessively sparse_ array will generate an error. If `convert` is set to true, excessively sparse arrays will be converted to a JSON object.
The current settings are always returned. A particular setting is only changed when the argument is provided (non-`nil`).
json.encode_sparse_array()
---
# json.parse | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/parse/#docusaurus_skipToContent_fallback)
On this page
json.parse
==========
Parses a UTF-8 JSON string into a Lua object (table, number, string, etc).
UTF-16 and UTF-32 JSON strings are not supported. All escape codes will be decoded and other bytes will be passed transparently. JSON `null` will be converted to a NULL `lightuserdata` value. This can be compared with `json.null` for convenience.
By default, numbers incompatible with the JSON specification (`infinity`, `NaN`, hexadecimal) can be parsed. This default can be changed with [json.decode\_invalid\_numbers](https://docs.gamesense.gs/docs/api/json/parse/#decode_invalid_numbers)
.
json.parse(json_text: string):
Arguments[](https://docs.gamesense.gs/docs/api/json/parse/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| json\_text | The JSON string to parse. | string |
Returns `object: undefined`
* [Arguments](https://docs.gamesense.gs/docs/api/json/parse/#arguments)
---
# materialsystem.arms_material | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/armsmaterial/#docusaurus_skipToContent_fallback)
materialsystem.arms\_material
=============================
Returns a reference to the arms material when 'Hands' is enabled
materialsystem.arms_material(): material
Returns `material`
---
# json.stringify | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/json/stringify/#docusaurus_skipToContent_fallback)
On this page
json.stringify
==============
Serializes a Lua object into a JSON string.
It supports the following types: `boolean`, `nil`, `number`, `string`, `table`
The remaining Lua types will generate an error: `function`, `lightuserdata`, `thread`, `userdata`
By default, numbers are encoded with 14 significant digits. Refer to [json.encode\_number\_precision](https://docs.gamesense.gs/docs/api/json/stringify/#encode_number_precision)
for details.
!!!warning This function will successfully encode/decode binary strings, but this is technically not supported by JSON and may not be compatible with other JSON libraries. To ensure the output is valid JSON, applications should ensure all Lua strings passed to `json.stringify` are UTF-8. Base64 is commonly used to encode binary data as the most efficient encoding under UTF-8 can only reduce the encoded size by a further ~8%. !!!
json.stringify(object): string
Arguments[](https://docs.gamesense.gs/docs/api/json/stringify/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| object | The Lua object to serialize. | unknown |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/json/stringify/#arguments)
---
# materialsystem.chams_material | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/chamsmaterial/#docusaurus_skipToContent_fallback)
materialsystem.chams\_material
==============================
Returns a reference to the player chams material
materialsystem.chams_material(): material
Returns `material`
---
# materialsystem.find_material | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/findmaterial/#docusaurus_skipToContent_fallback)
On this page
materialsystem.find\_material
=============================
Returns a reference to the material
materialsystem.find_material(path: string, force_load: boolean): material
Arguments[](https://docs.gamesense.gs/docs/api/materialsystem/findmaterial/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| path | Path to material including filename | string |
| force\_load | If true, will load the material if it isn't loaded already | boolean |
Returns `material`
* [Arguments](https://docs.gamesense.gs/docs/api/materialsystem/findmaterial/#arguments)
---
# materialsystem | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/#docusaurus_skipToContent_fallback)
On this page
materialsystem
==============
Description[](https://docs.gamesense.gs/docs/api/materialsystem/#description "Direct link to heading")
--------------------------------------------------------------------------------------------------------
Functions for interacting with the source engine [material system](https://developer.valvesoftware.com/wiki/Material)
. Refer to [the material type](https://docs.gamesense.gs/docs/api/types/material)
for information on how to modify a material.
Functions[](https://docs.gamesense.gs/docs/api/materialsystem/#functions "Direct link to heading")
----------------------------------------------------------------------------------------------------
### arms\_material[](https://docs.gamesense.gs/docs/api/materialsystem/#arms_material "Direct link to heading")
[materialsystem.arms_material(): material](https://docs.gamesense.gs/docs/api/materialsystem/armsmaterial)
> Returns a reference to the arms material when 'Hands' is enabled
### chams\_material[](https://docs.gamesense.gs/docs/api/materialsystem/#chams_material "Direct link to heading")
[materialsystem.chams_material(): material](https://docs.gamesense.gs/docs/api/materialsystem/chamsmaterial)
> Returns a reference to the player chams material
### find\_material[](https://docs.gamesense.gs/docs/api/materialsystem/#find_material "Direct link to heading")
[materialsystem.find_material(path: string, force_load: boolean): material](https://docs.gamesense.gs/docs/api/materialsystem/findmaterial)
> Returns a reference to the material
### find\_materials[](https://docs.gamesense.gs/docs/api/materialsystem/#find_materials "Direct link to heading")
[materialsystem.find_materials(path: string): table](https://docs.gamesense.gs/docs/api/materialsystem/findmaterials)
> Returns a table of materials matching the specified path
### find\_texture[](https://docs.gamesense.gs/docs/api/materialsystem/#find_texture "Direct link to heading")
[materialsystem.find_texture(path: string)](https://docs.gamesense.gs/docs/api/materialsystem/findtexture)
> Returns a pointer to a texture, can be used to override textures with [material:set\_shader\_param](https://docs.gamesense.gs/docs/api/types/material#set_shader_param)
> .
### get\_model\_materials[](https://docs.gamesense.gs/docs/api/materialsystem/#get_model_materials "Direct link to heading")
[materialsystem.get_model_materials(entindex: number): table](https://docs.gamesense.gs/docs/api/materialsystem/getmodelmaterials)
> Returns a table of materials used by the specified entity's model
### override\_material[](https://docs.gamesense.gs/docs/api/materialsystem/#override_material "Direct link to heading")
[materialsystem.override_material(material: material, material_new: material)](https://docs.gamesense.gs/docs/api/materialsystem/overridematerial)
> Overrides all of a material properties with another material.
### viewmodel\_material[](https://docs.gamesense.gs/docs/api/materialsystem/#viewmodel_material "Direct link to heading")
[materialsystem.viewmodel_material(): material](https://docs.gamesense.gs/docs/api/materialsystem/viewmodelmaterial)
> Returns a reference to the arms material when 'Weapon viewmodel' is enabled
* [Description](https://docs.gamesense.gs/docs/api/materialsystem/#description)
* [Functions](https://docs.gamesense.gs/docs/api/materialsystem/#functions)
* [arms\_material](https://docs.gamesense.gs/docs/api/materialsystem/#arms_material)
* [chams\_material](https://docs.gamesense.gs/docs/api/materialsystem/#chams_material)
* [find\_material](https://docs.gamesense.gs/docs/api/materialsystem/#find_material)
* [find\_materials](https://docs.gamesense.gs/docs/api/materialsystem/#find_materials)
* [find\_texture](https://docs.gamesense.gs/docs/api/materialsystem/#find_texture)
* [get\_model\_materials](https://docs.gamesense.gs/docs/api/materialsystem/#get_model_materials)
* [override\_material](https://docs.gamesense.gs/docs/api/materialsystem/#override_material)
* [viewmodel\_material](https://docs.gamesense.gs/docs/api/materialsystem/#viewmodel_material)
---
# globals.tickcount | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/globals/tickcount/#docusaurus_skipToContent_fallback)
globals.tickcount
=================
The number of ticks elapsed on the server.
globals.tickcount(): number
Returns `number`
---
# materialsystem.find_materials | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/findmaterials/#docusaurus_skipToContent_fallback)
On this page
materialsystem.find\_materials
==============================
Returns a table of materials matching the specified path
materialsystem.find_materials(path: string): table
Arguments[](https://docs.gamesense.gs/docs/api/materialsystem/findmaterials/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| path | Partial path to material(s) | string |
Returns `materials: table`
* [Arguments](https://docs.gamesense.gs/docs/api/materialsystem/findmaterials/#arguments)
---
# materialsystem.find_texture | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/findtexture/#docusaurus_skipToContent_fallback)
On this page
materialsystem.find\_texture
============================
Returns a pointer to a texture, can be used to override textures with [material:set\_shader\_param](https://docs.gamesense.gs/docs/api/types/material#set_shader_param)
.
materialsystem.find_texture(path: string)
Arguments[](https://docs.gamesense.gs/docs/api/materialsystem/findtexture/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| path | Path to a texture including filename | string |
* [Arguments](https://docs.gamesense.gs/docs/api/materialsystem/findtexture/#arguments)
---
# materialsystem.get_model_materials | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/getmodelmaterials/#docusaurus_skipToContent_fallback)
On this page
materialsystem.get\_model\_materials
====================================
Returns a table of materials used by the specified entity's model
materialsystem.get_model_materials(entindex: number): table
Arguments[](https://docs.gamesense.gs/docs/api/materialsystem/getmodelmaterials/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| entindex | Returns a table of references to materials used by the entity | number |
Returns `materials: table`
* [Arguments](https://docs.gamesense.gs/docs/api/materialsystem/getmodelmaterials/#arguments)
---
# materialsystem.override_material | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/overridematerial/#docusaurus_skipToContent_fallback)
On this page
materialsystem.override\_material
=================================
Overrides all of a material properties with another material.
materialsystem.override_material(material: material, material_new: material)
Arguments[](https://docs.gamesense.gs/docs/api/materialsystem/overridematerial/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| material | The material to override | material |
| material\_new | The material to override it with | material |
* [Arguments](https://docs.gamesense.gs/docs/api/materialsystem/overridematerial/#arguments)
---
# materialsystem.viewmodel_material | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/materialsystem/viewmodelmaterial/#docusaurus_skipToContent_fallback)
materialsystem.viewmodel\_material
==================================
Returns a reference to the arms material when 'Weapon viewmodel' is enabled
materialsystem.viewmodel_material(): material
Returns `material`
---
# math.abs | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/abs/#docusaurus_skipToContent_fallback)
On this page
math.abs
========
Returns the absolute value of x, removing the negative sign if present.
math.abs(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/abs/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/abs/#arguments)
---
# math.acos | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/acos/#docusaurus_skipToContent_fallback)
On this page
math.acos
=========
Returns the arccosine of the given number.
math.acos(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/acos/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/acos/#arguments)
---
# math.asin | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/asin/#docusaurus_skipToContent_fallback)
On this page
math.asin
=========
Returns the arcsine of the given number.
math.asin(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/asin/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/asin/#arguments)
---
# math.atan | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/atan/#docusaurus_skipToContent_fallback)
On this page
math.atan
=========
Returns the arc tangent of x (in radians).
math.atan(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/atan/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/atan/#arguments)
---
# math.atan2 | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/atan2/#docusaurus_skipToContent_fallback)
On this page
math.atan2
==========
Returns the arc tangent of y/x (in radians), but uses the signs of both parameters to find the quadrant of the result. It also handles correctly the case of x being zero.
math.atan2(y: number, x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/atan2/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| y | N/A | number |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/atan2/#arguments)
---
# math.cos | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/cos/#docusaurus_skipToContent_fallback)
On this page
math.cos
========
Returns the cosine of x (assumed to be in radians).
math.cos(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/cos/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Angle in radians. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/cos/#arguments)
---
# math.cosh | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/cosh/#docusaurus_skipToContent_fallback)
On this page
math.cosh
=========
Returns the hyperbolic cosine of x.
math.cosh(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/cosh/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/cosh/#arguments)
---
# math | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/#docusaurus_skipToContent_fallback)
On this page
math
====
Description[](https://docs.gamesense.gs/docs/api/math/#description "Direct link to heading")
----------------------------------------------------------------------------------------------
Standard library for common mathematical functions.
Functions[](https://docs.gamesense.gs/docs/api/math/#functions "Direct link to heading")
------------------------------------------------------------------------------------------
### abs[](https://docs.gamesense.gs/docs/api/math/#abs "Direct link to heading")
[math.abs(x: number): number](https://docs.gamesense.gs/docs/api/math/abs)
> Returns the absolute value of x, removing the negative sign if present.
### acos[](https://docs.gamesense.gs/docs/api/math/#acos "Direct link to heading")
[math.acos(x: number): number](https://docs.gamesense.gs/docs/api/math/acos)
> Returns the arccosine of the given number.
### asin[](https://docs.gamesense.gs/docs/api/math/#asin "Direct link to heading")
[math.asin(x: number): number](https://docs.gamesense.gs/docs/api/math/asin)
> Returns the arcsine of the given number.
### atan[](https://docs.gamesense.gs/docs/api/math/#atan "Direct link to heading")
[math.atan(x: number): number](https://docs.gamesense.gs/docs/api/math/atan)
> Returns the arc tangent of x (in radians).
### atan2[](https://docs.gamesense.gs/docs/api/math/#atan2 "Direct link to heading")
[math.atan2(y: number, x: number): number](https://docs.gamesense.gs/docs/api/math/atan2)
> Returns the arc tangent of y/x (in radians), but uses the signs of both parameters to find the quadrant of the result. It also handles correctly the case of x being zero.
### ceil[](https://docs.gamesense.gs/docs/api/math/#ceil "Direct link to heading")
[math.ceil(x: number): number](https://docs.gamesense.gs/docs/api/math/ceil)
> Rounds the number up to the nearest integer.
### cos[](https://docs.gamesense.gs/docs/api/math/#cos "Direct link to heading")
[math.cos(x: number): number](https://docs.gamesense.gs/docs/api/math/cos)
> Returns the cosine of x (assumed to be in radians).
### cosh[](https://docs.gamesense.gs/docs/api/math/#cosh "Direct link to heading")
[math.cosh(x: number): number](https://docs.gamesense.gs/docs/api/math/cosh)
> Returns the hyperbolic cosine of x.
### deg[](https://docs.gamesense.gs/docs/api/math/#deg "Direct link to heading")
[math.deg(x: number): number](https://docs.gamesense.gs/docs/api/math/deg)
> Converts the angle x from radians to degrees.
### exp[](https://docs.gamesense.gs/docs/api/math/#exp "Direct link to heading")
[math.exp(x: number): number](https://docs.gamesense.gs/docs/api/math/exp)
> Returns the value of `e^x`.
### floor[](https://docs.gamesense.gs/docs/api/math/#floor "Direct link to heading")
[math.floor(x: number): number](https://docs.gamesense.gs/docs/api/math/floor)
> Rounds the number down to the nearest integer.
### fmod[](https://docs.gamesense.gs/docs/api/math/#fmod "Direct link to heading")
[math.fmod(x: number, y: number): number](https://docs.gamesense.gs/docs/api/math/fmod)
> Returns the modulus of the specified values (remainder of `x / y`). While this is similar to the `%` operator, it will return a negative value if the first argument is negative, whereas the `%` operator will return a positive value even if the first operand is negative.
### frexp[](https://docs.gamesense.gs/docs/api/math/#frexp "Direct link to heading")
[math.frexp(x: number): number, number](https://docs.gamesense.gs/docs/api/math/frexp)
> Returns `m` and `e` such that `x = m2e`, `e` is an integer and the absolute value of `m` is in the range ((0.5, 1) (or zero when `x` is zero). Used to split the number value into a normalized fraction and an exponent. Two values are returned: the first is a multiplier in the range 1/2 (inclusive) to 1 (exclusive) and the second is an integer exponent. The result is such that `x = m*2^e`.
### ldexp[](https://docs.gamesense.gs/docs/api/math/#ldexp "Direct link to heading")
[math.ldexp(x: number, e: number): number](https://docs.gamesense.gs/docs/api/math/ldexp)
> Returns `x*2^e` (`e` should be an integer).
### log[](https://docs.gamesense.gs/docs/api/math/#log "Direct link to heading")
[math.log(x: number, base: number): number](https://docs.gamesense.gs/docs/api/math/log)
> Returns the logarithm of x using the given base, or the mathematical constant `e` if no base is provided (natural logarithm).
### log10[](https://docs.gamesense.gs/docs/api/math/#log10 "Direct link to heading")
[math.log10(x: number): number](https://docs.gamesense.gs/docs/api/math/log10)
> Returns the base-10 logarithm of x.
### max[](https://docs.gamesense.gs/docs/api/math/#max "Direct link to heading")
[math.max(...): number](https://docs.gamesense.gs/docs/api/math/max)
> Returns the largest of its arguments.
### min[](https://docs.gamesense.gs/docs/api/math/#min "Direct link to heading")
[math.min(...): number](https://docs.gamesense.gs/docs/api/math/min)
> Returns the smallest of its arguments.
### modf[](https://docs.gamesense.gs/docs/api/math/#modf "Direct link to heading")
[math.modf(base: number): number, number](https://docs.gamesense.gs/docs/api/math/modf)
> Returns the integral and fractional component of the modulo operation.
### pow[](https://docs.gamesense.gs/docs/api/math/#pow "Direct link to heading")
[math.pow(x: number, y: number): number](https://docs.gamesense.gs/docs/api/math/pow)
> Returns `x^y`. In particular, `math.pow(1.0, x)` and `math.pow(x, 0.0)` always return `1.0`, even when x is a zero or NaN. If both x and y are finite, x is negative, and y is not an integer then `math.pow(x, y)` is undefined.
### rad[](https://docs.gamesense.gs/docs/api/math/#rad "Direct link to heading")
[math.rad(x: number): number](https://docs.gamesense.gs/docs/api/math/rad)
> Converts the angle x from degrees to radians.
### random[](https://docs.gamesense.gs/docs/api/math/#random "Direct link to heading")
[math.random(min: number, max: number): number](https://docs.gamesense.gs/docs/api/math/random)
> Returns a random number between the values provided. When called without arguments, returns a uniform pseudo-random real number in the range \[0,1\]. When called with an integer number m, math.random returns a uniform pseudo-random integer in the range \[1, m\]. When called with two integer numbers m and n, math.random returns a uniform pseudo-random integer in the range \[m, n\].
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement [math.random](https://docs.gamesense.gs/docs/api/math/#random)
and \[math.randomseed(#randomseed).\
\
When called without arguments it generates 52 pseudo-random bits for every call. The result is uniformly distributed between `0.0` and `1.0`. It's correctly scaled up and rounded for `math.random(n [,m])` to preserve uniformity.\
\
Important: Neither this nor any other PRNG based on the simplistic math.random API is suitable for cryptographic use.\
\
### randomseed[](https://docs.gamesense.gs/docs/api/math/#randomseed "Direct link to heading")\
\
[math.randomseed(seed: number)](https://docs.gamesense.gs/docs/api/math/randomseed)\
\
> Seeds the random number generator. The same seed will guarantee the same sequence of numbers each time with [math.random](https://docs.gamesense.gs/docs/api/math/#random)\
> . Incorrect usage of this function will affect all loaded scripts.\
\
### sin[](https://docs.gamesense.gs/docs/api/math/#sin "Direct link to heading")\
\
[math.sin(x: number): number](https://docs.gamesense.gs/docs/api/math/sin)\
\
> Returns the sine of x (assumed to be in radians).\
\
### sinh[](https://docs.gamesense.gs/docs/api/math/#sinh "Direct link to heading")\
\
[math.sinh(x: number): number](https://docs.gamesense.gs/docs/api/math/sinh)\
\
> Returns the hyperbolic sine of x.\
\
### sqrt[](https://docs.gamesense.gs/docs/api/math/#sqrt "Direct link to heading")\
\
[math.sqrt(x: number): number](https://docs.gamesense.gs/docs/api/math/sqrt)\
\
> Returns the square root of x. (You can also use the expression x^0.5 to compute this value.)\
\
### tan[](https://docs.gamesense.gs/docs/api/math/#tan "Direct link to heading")\
\
[math.tan(x: number): number](https://docs.gamesense.gs/docs/api/math/tan)\
\
> Returns the tangent of x (assumed to be in radians).\
\
### tanh[](https://docs.gamesense.gs/docs/api/math/#tanh "Direct link to heading")\
\
[math.tanh(x: number): number](https://docs.gamesense.gs/docs/api/math/tanh)\
\
> Returns the hyperbolic tangent of x.\
\
* [Description](https://docs.gamesense.gs/docs/api/math/#description)\
\
* [Functions](https://docs.gamesense.gs/docs/api/math/#functions)\
* [abs](https://docs.gamesense.gs/docs/api/math/#abs)\
\
* [acos](https://docs.gamesense.gs/docs/api/math/#acos)\
\
* [asin](https://docs.gamesense.gs/docs/api/math/#asin)\
\
* [atan](https://docs.gamesense.gs/docs/api/math/#atan)\
\
* [atan2](https://docs.gamesense.gs/docs/api/math/#atan2)\
\
* [ceil](https://docs.gamesense.gs/docs/api/math/#ceil)\
\
* [cos](https://docs.gamesense.gs/docs/api/math/#cos)\
\
* [cosh](https://docs.gamesense.gs/docs/api/math/#cosh)\
\
* [deg](https://docs.gamesense.gs/docs/api/math/#deg)\
\
* [exp](https://docs.gamesense.gs/docs/api/math/#exp)\
\
* [floor](https://docs.gamesense.gs/docs/api/math/#floor)\
\
* [fmod](https://docs.gamesense.gs/docs/api/math/#fmod)\
\
* [frexp](https://docs.gamesense.gs/docs/api/math/#frexp)\
\
* [ldexp](https://docs.gamesense.gs/docs/api/math/#ldexp)\
\
* [log](https://docs.gamesense.gs/docs/api/math/#log)\
\
* [log10](https://docs.gamesense.gs/docs/api/math/#log10)\
\
* [max](https://docs.gamesense.gs/docs/api/math/#max)\
\
* [min](https://docs.gamesense.gs/docs/api/math/#min)\
\
* [modf](https://docs.gamesense.gs/docs/api/math/#modf)\
\
* [pow](https://docs.gamesense.gs/docs/api/math/#pow)\
\
* [rad](https://docs.gamesense.gs/docs/api/math/#rad)\
\
* [random](https://docs.gamesense.gs/docs/api/math/#random)\
\
* [randomseed](https://docs.gamesense.gs/docs/api/math/#randomseed)\
\
* [sin](https://docs.gamesense.gs/docs/api/math/#sin)\
\
* [sinh](https://docs.gamesense.gs/docs/api/math/#sinh)\
\
* [sqrt](https://docs.gamesense.gs/docs/api/math/#sqrt)\
\
* [tan](https://docs.gamesense.gs/docs/api/math/#tan)\
\
* [tanh](https://docs.gamesense.gs/docs/api/math/#tanh)
---
# math.deg | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/deg/#docusaurus_skipToContent_fallback)
On this page
math.deg
========
Converts the angle x from radians to degrees.
math.deg(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/deg/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Angle in radians. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/deg/#arguments)
---
# math.exp | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/exp/#docusaurus_skipToContent_fallback)
On this page
math.exp
========
Returns the value of `e^x`.
math.exp(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/exp/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/exp/#arguments)
---
# math.ceil | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/ceil/#docusaurus_skipToContent_fallback)
On this page
math.ceil
=========
Rounds the number up to the nearest integer.
math.ceil(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/ceil/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/ceil/#arguments)
---
# math.floor | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/floor/#docusaurus_skipToContent_fallback)
On this page
math.floor
==========
Rounds the number down to the nearest integer.
math.floor(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/floor/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/floor/#arguments)
---
# math.fmod | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/fmod/#docusaurus_skipToContent_fallback)
On this page
math.fmod
=========
Returns the modulus of the specified values (remainder of `x / y`). While this is similar to the `%` operator, it will return a negative value if the first argument is negative, whereas the `%` operator will return a positive value even if the first operand is negative.
math.fmod(x: number, y: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/fmod/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
| y | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/fmod/#arguments)
---
# math.frexp | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/frexp/#docusaurus_skipToContent_fallback)
On this page
math.frexp
==========
Returns `m` and `e` such that `x = m2e`, `e` is an integer and the absolute value of `m` is in the range ((0.5, 1) (or zero when `x` is zero). Used to split the number value into a normalized fraction and an exponent. Two values are returned: the first is a multiplier in the range 1/2 (inclusive) to 1 (exclusive) and the second is an integer exponent. The result is such that `x = m*2^e`.
math.frexp(x: number): number, number
Arguments[](https://docs.gamesense.gs/docs/api/math/frexp/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number, number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/frexp/#arguments)
---
# math.log10 | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/log10/#docusaurus_skipToContent_fallback)
On this page
math.log10
==========
Returns the base-10 logarithm of x.
math.log10(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/log10/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/log10/#arguments)
---
# math.log | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/log/#docusaurus_skipToContent_fallback)
On this page
math.log
========
Returns the logarithm of x using the given base, or the mathematical constant `e` if no base is provided (natural logarithm).
math.log(x: number, base: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/log/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
| base | Base (defaults to 2.7182818) | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/log/#arguments)
---
# math.ldexp | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/ldexp/#docusaurus_skipToContent_fallback)
On this page
math.ldexp
==========
Returns `x*2^e` (`e` should be an integer).
math.ldexp(x: number, e: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/ldexp/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
| e | Exponent (Integer) | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/ldexp/#arguments)
---
# math.min | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/min/#docusaurus_skipToContent_fallback)
On this page
math.min
========
Returns the smallest of its arguments.
math.min(...): number
Arguments[](https://docs.gamesense.gs/docs/api/math/min/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/min/#arguments)
---
# math.max | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/max/#docusaurus_skipToContent_fallback)
On this page
math.max
========
Returns the largest of its arguments.
math.max(...): number
Arguments[](https://docs.gamesense.gs/docs/api/math/max/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/max/#arguments)
---
# math.modf | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/modf/#docusaurus_skipToContent_fallback)
On this page
math.modf
=========
Returns the integral and fractional component of the modulo operation.
math.modf(base: number): number, number
Arguments[](https://docs.gamesense.gs/docs/api/math/modf/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| base | N/A | number |
Returns `number, number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/modf/#arguments)
---
# math.rad | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/rad/#docusaurus_skipToContent_fallback)
On this page
math.rad
========
Converts the angle x from degrees to radians.
math.rad(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/rad/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Angle in degrees. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/rad/#arguments)
---
# math.pow | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/pow/#docusaurus_skipToContent_fallback)
On this page
math.pow
========
Returns `x^y`. In particular, `math.pow(1.0, x)` and `math.pow(x, 0.0)` always return `1.0`, even when x is a zero or NaN. If both x and y are finite, x is negative, and y is not an integer then `math.pow(x, y)` is undefined.
math.pow(x: number, y: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/pow/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
| y | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/pow/#arguments)
---
# math.random | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/random/#docusaurus_skipToContent_fallback)
On this page
math.random
===========
Returns a random number between the values provided. When called without arguments, returns a uniform pseudo-random real number in the range \[0,1\]. When called with an integer number m, math.random returns a uniform pseudo-random integer in the range \[1, m\]. When called with two integer numbers m and n, math.random returns a uniform pseudo-random integer in the range \[m, n\].
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement [math.random](https://docs.gamesense.gs/docs/api/math/random/#random)
and \[math.randomseed(#randomseed).\
\
When called without arguments it generates 52 pseudo-random bits for every call. The result is uniformly distributed between `0.0` and `1.0`. It's correctly scaled up and rounded for `math.random(n [,m])` to preserve uniformity.\
\
Important: Neither this nor any other PRNG based on the simplistic math.random API is suitable for cryptographic use.\
\
math.random(min: number, max: number): number\
\
Arguments[](https://docs.gamesense.gs/docs/api/math/random/#arguments "Direct link to heading")\
\
-------------------------------------------------------------------------------------------------\
\
| Name | Description | Type |\
| --- | --- | --- |\
| min | Minimum value (inclusive). Defaults to 0. | number |\
| max | Maximum value (inclusive). Defaults to 1. | number |\
\
Returns `number`\
\
* [Arguments](https://docs.gamesense.gs/docs/api/math/random/#arguments)
---
# math.randomseed | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/randomseed/#docusaurus_skipToContent_fallback)
On this page
math.randomseed
===============
Seeds the random number generator. The same seed will guarantee the same sequence of numbers each time with [math.random](https://docs.gamesense.gs/docs/api/math/randomseed/#random)
. Incorrect usage of this function will affect all loaded scripts.
math.randomseed(seed: number)
Arguments[](https://docs.gamesense.gs/docs/api/math/randomseed/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| seed | N/A | number |
* [Arguments](https://docs.gamesense.gs/docs/api/math/randomseed/#arguments)
---
# math.sinh | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/sinh/#docusaurus_skipToContent_fallback)
On this page
math.sinh
=========
Returns the hyperbolic sine of x.
math.sinh(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/sinh/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Angle in radians. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/sinh/#arguments)
---
# math.sin | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/sin/#docusaurus_skipToContent_fallback)
On this page
math.sin
========
Returns the sine of x (assumed to be in radians).
math.sin(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/sin/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Angle in radians. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/sin/#arguments)
---
# math.tan | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/tan/#docusaurus_skipToContent_fallback)
On this page
math.tan
========
Returns the tangent of x (assumed to be in radians).
math.tan(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/tan/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Angle in radians. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/tan/#arguments)
---
# math.sqrt | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/sqrt/#docusaurus_skipToContent_fallback)
On this page
math.sqrt
=========
Returns the square root of x. (You can also use the expression x^0.5 to compute this value.)
math.sqrt(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/sqrt/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | N/A | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/sqrt/#arguments)
---
# math.tanh | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/math/tanh/#docusaurus_skipToContent_fallback)
On this page
math.tanh
=========
Returns the hyperbolic tangent of x.
math.tanh(x: number): number
Arguments[](https://docs.gamesense.gs/docs/api/math/tanh/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Angle in radians. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/math/tanh/#arguments)
---
# panorama.open | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/panorama/open/#docusaurus_skipToContent_fallback)
On this page
panorama.open
=============
panorama.open(panel: string): table
Arguments[](https://docs.gamesense.gs/docs/api/panorama/open/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| panel | Panel name | string |
Returns `panorama globals: table`
* [Arguments](https://docs.gamesense.gs/docs/api/panorama/open/#arguments)
---
# panorama | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/panorama/#docusaurus_skipToContent_fallback)
On this page
panorama
========
Description[](https://docs.gamesense.gs/docs/api/panorama/#description "Direct link to heading")
--------------------------------------------------------------------------------------------------
API for CS:GO's Panorama UI. Lets you execute JavaScript code in CS:GO's V8 engine, which can then interact with your lua code.
Useful tools: [JS Syntax Validator](https://esprima.org/demo/validate.html)
Functions[](https://docs.gamesense.gs/docs/api/panorama/#functions "Direct link to heading")
----------------------------------------------------------------------------------------------
### loadstring[](https://docs.gamesense.gs/docs/api/panorama/#loadstring "Direct link to heading")
[panorama.loadstring(js_code: string, panel: string)](https://docs.gamesense.gs/docs/api/panorama/loadstring)
### open[](https://docs.gamesense.gs/docs/api/panorama/#open "Direct link to heading")
[panorama.open(panel: string): table](https://docs.gamesense.gs/docs/api/panorama/open)
* [Description](https://docs.gamesense.gs/docs/api/panorama/#description)
* [Functions](https://docs.gamesense.gs/docs/api/panorama/#functions)
* [loadstring](https://docs.gamesense.gs/docs/api/panorama/#loadstring)
* [open](https://docs.gamesense.gs/docs/api/panorama/#open)
---
# panorama.loadstring | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/panorama/loadstring/#docusaurus_skipToContent_fallback)
On this page
panorama.loadstring
===================
panorama.loadstring(js_code: string, panel: string)
Arguments[](https://docs.gamesense.gs/docs/api/panorama/loadstring/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| js\_code | String containing JavaScript code | string |
| panel | Panel name | string |
* [Arguments](https://docs.gamesense.gs/docs/api/panorama/loadstring/#arguments)
---
# plist.set | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/plist/set/#docusaurus_skipToContent_fallback)
On this page
plist.set
=========
Sets the value of a built-in player list option
plist.set(entindex: number, field: string, value)
Arguments[](https://docs.gamesense.gs/docs/api/plist/set/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| entindex | Player index | number |
| field | Name of the field | string |
| value | Value of the field | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/plist/set/#arguments)
---
# plist.get | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/plist/get/#docusaurus_skipToContent_fallback)
On this page
plist.get
=========
Returns the value of a built-in player list option
plist.get(entindex: number, field: string)
Arguments[](https://docs.gamesense.gs/docs/api/plist/get/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| entindex | Player index | number |
| field | Name of the field | string |
* [Arguments](https://docs.gamesense.gs/docs/api/plist/get/#arguments)
---
# plist | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/plist/#docusaurus_skipToContent_fallback)
On this page
plist
=====
Description[](https://docs.gamesense.gs/docs/api/plist/#description "Direct link to heading")
-----------------------------------------------------------------------------------------------
Functions for interacting with the player list
Functions[](https://docs.gamesense.gs/docs/api/plist/#functions "Direct link to heading")
-------------------------------------------------------------------------------------------
### get[](https://docs.gamesense.gs/docs/api/plist/#get "Direct link to heading")
[plist.get(entindex: number, field: string)](https://docs.gamesense.gs/docs/api/plist/get)
> Returns the value of a built-in player list option
### set[](https://docs.gamesense.gs/docs/api/plist/#set "Direct link to heading")
[plist.set(entindex: number, field: string, value)](https://docs.gamesense.gs/docs/api/plist/set)
> Sets the value of a built-in player list option
* [Description](https://docs.gamesense.gs/docs/api/plist/#description)
* [Functions](https://docs.gamesense.gs/docs/api/plist/#functions)
* [get](https://docs.gamesense.gs/docs/api/plist/#get)
* [set](https://docs.gamesense.gs/docs/api/plist/#set)
---
# renderer.load_jpg | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/loadjpg/#docusaurus_skipToContent_fallback)
On this page
renderer.load\_jpg
==================
Loads a texture from raw JPG contents (with file header). The file can for example be loaded using [readfile](https://docs.gamesense.gs/docs/api/G/readfile)
. Returns a texture ID that can be used with renderer.texture, or nil on failure
renderer.load_jpg(contents: string, width: number, height: number): number
Arguments[](https://docs.gamesense.gs/docs/api/renderer/loadjpg/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| contents | JPG file contents | string |
| width | Width | number |
| height | Height | number |
Returns `texture: number`
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/loadjpg/#arguments)
---
# renderer.gradient | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/gradient/#docusaurus_skipToContent_fallback)
On this page
renderer.gradient
=================
Draws a horizontal or vertical gradient on the screen.
renderer.gradient(x: number, y: number, w: number, h: number, r1: number, g1: number, b1: number, a1: number, r2: number, g2: number, b2: number, a2: number, direction: boolean)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/gradient/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Top left X coordinate | number |
| y | Top left Y coordinate | number |
| w | Width in pixels | number |
| h | Height in pixels | number |
| r1 | Top/Left red color component (0 to 255) | number |
| g1 | Top/Left green color component (0 to 255) | number |
| b1 | Top/Left blue color component (0 to 255) | number |
| a1 | Top/Left alpha (opacity) component (0 to 255) | number |
| r2 | Bottom/Right red color component (0 to 255) | number |
| g2 | Bottom/Right green color component (0 to 255) | number |
| b2 | Bottom/Right blue color component (0 to 255) | number |
| a2 | Bottom/Right alpha (opacity) component (0 to 255) | number |
| direction | Pass true for horizontal (left-to-right) gradient, or false for vertical. | boolean |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/gradient/#arguments)
---
# renderer.circle | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/circle/#docusaurus_skipToContent_fallback)
On this page
renderer.circle
===============
Draws a filled circle on the screen
renderer.circle(x: number, y: number, r: number, g: number, b: number, a: number, radius: number, start_degrees: number, percentage: number)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/circle/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | X center position | number |
| y | Y center position | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
| radius | Radius of the circle in pixels. | number |
| start\_degrees | 0 is the right side, 90 is the bottom, 180 is the left, 270 is the top. | number |
| percentage | Must be within \[0.0-1.0\]. 1.0 is a full circle, 0.5 is a half circle, etc. | number |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/circle/#arguments)
---
# renderer.blur | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/blur/#docusaurus_skipToContent_fallback)
On this page
danger
Using this function in a `paint_ui` callback will result in 'too many indices for index buffer' crashes. Calls to this function are not flushed when not in-game, so they eventually pile-up and exceed the limit.
renderer.blur
=============
Creates a region on the screen that blurs everything behind it.
renderer.blur(x: number, y: number, w: number, h: number, alpha: number, amount: number)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/blur/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | The X coordinate of the rectangle | number |
| y | The Y coordinate of the rectangle | number |
| w | The width of the rectangle | number |
| h | The height of the rectangle | number |
| alpha | The alpha of the blur, in the range of 0.0 to 1.0 | number |
| amount | The amount of blur, in the range of 0.0 to 1.0 | number |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/blur/#arguments)
---
# renderer.load_png | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/loadpng/#docusaurus_skipToContent_fallback)
On this page
renderer.load\_png
==================
Loads a texture from raw PNG contents (with file header). The file can for example be loaded using [readfile](https://docs.gamesense.gs/docs/api/G/readfile)
. Returns a texture ID that can be used with renderer.texture, or nil on failure
renderer.load_png(contents: string, width: number, height: number): number
Arguments[](https://docs.gamesense.gs/docs/api/renderer/loadpng/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| contents | PNG file contents | string |
| width | Width | number |
| height | Height | number |
Returns `texture: number`
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/loadpng/#arguments)
---
# renderer.indicator | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/indicator/#docusaurus_skipToContent_fallback)
On this page
renderer.indicator
==================
Draws an indicator on the screen and returns the Y screen coordinate (vertical offset) of the drawn text, or nil on failure.
renderer.indicator(r: number, g: number, b: number, a: number, ...): number
Arguments[](https://docs.gamesense.gs/docs/api/renderer/indicator/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
| text | The text that will be drawn. Additional arguments will be concatenated. | unknown |
Returns `y: number`
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/indicator/#arguments)
---
# renderer.line | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/line/#docusaurus_skipToContent_fallback)
On this page
renderer.line
=============
Draws a anti-aliased line on the screen.
renderer.line(x1: number, y1: number, x2: number, y2: number, r: number, g: number, b: number, a: number)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/line/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x1 | X coordinate of the start point | number |
| y1 | Y coordinate of the start point | number |
| x2 | X coordinate of the end point | number |
| y2 | Y coordinate of the end point | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/line/#arguments)
---
# renderer.circle_outline | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/circleoutline/#docusaurus_skipToContent_fallback)
On this page
renderer.circle\_outline
========================
Draws the outline of a circle on the screen
renderer.circle_outline(x: number, y: number, r: number, g: number, b: number, a: number, radius: number, start_degrees: number, percentage: number, thickness: number)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/circleoutline/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | X center position | number |
| y | Y center position | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
| radius | Radius of the circle in pixels. | number |
| start\_degrees | 0 is the right side, 90 is the bottom, 180 is the left, 270 is the top. | number |
| percentage | Must be within \[0.0-1.0\]. 1.0 is a full circle, 0.5 is a half circle, etc. | number |
| thickness | Thickness of the outline in pixels. | number |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/circleoutline/#arguments)
---
# renderer.load_rgba | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/loadrgba/#docusaurus_skipToContent_fallback)
On this page
renderer.load\_rgba
===================
Loads a texture from a RGBA buffer. Returns a texture ID that can be used with renderer.texture, or nil on failure
renderer.load_rgba(contents: string, width: number, height: number): number
Arguments[](https://docs.gamesense.gs/docs/api/renderer/loadrgba/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| contents | RGBA buffer (byte encoded - red = "\\xFF\\x00\\x00\\xFF") | string |
| width | Width | number |
| height | Height | number |
Returns `texture: number`
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/loadrgba/#arguments)
---
# renderer.measure_text | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/measuretext/#docusaurus_skipToContent_fallback)
On this page
renderer.measure\_text
======================
Returns width, height. This can only be called from the paint callback.
renderer.measure_text(flags: string, ...): number, number
Arguments[](https://docs.gamesense.gs/docs/api/renderer/measuretext/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| flags | Text flags: `"+"` for large text, `"-"` for small text, `"b"` for bold text, `"d"` for high DPI support. "c" and `"d"` can be combined with the other flags. nil can be specified for normal sized text. | string |
| text | Text that will be measured | unknown |
Returns `width: number, height: number`
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/measuretext/#arguments)
---
# renderer.rectangle | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/rectangle/#docusaurus_skipToContent_fallback)
On this page
renderer.rectangle
==================
Draws a filled rectangle on the screen
renderer.rectangle(x: number, y: number, w: number, h: number, r: number, g: number, b: number, a: number)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/rectangle/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Top left X coordinate | number |
| y | Top left Y coordinate | number |
| w | Width in pixels | number |
| h | Height in pixels | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/rectangle/#arguments)
---
# renderer.load_svg | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/loadsvg/#docusaurus_skipToContent_fallback)
On this page
renderer.load\_svg
==================
Loads a [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG)
from a string. The file can for example be loaded using [readfile](https://docs.gamesense.gs/docs/api/G/readfile)
. Returns a texture ID that can be used with [renderer.texture](https://docs.gamesense.gs/docs/api/renderer/loadsvg/#texture)
, or nil on failure
renderer.load_svg(contents: string, width: number, height: number): number
Arguments[](https://docs.gamesense.gs/docs/api/renderer/loadsvg/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| contents | SVG file contents | string |
| width | Width | number |
| height | Height | number |
Returns `texture: number`
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/loadsvg/#arguments)
---
# renderer.text | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/text/#docusaurus_skipToContent_fallback)
On this page
renderer.text
=============
Draws text on the screen.
renderer.text(x: number, y: number, r: number, g: number, b: number, a: number, flags: string, max_width: number, ...)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/text/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | Top left / center X coordinate | number |
| y | Top left / center Y coordinate | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
| flags | Text flags: `"+"` for large text, `"-"` for small text, `"c"` for centered text, `"r"` for right-aligned text, `"b"` for bold text, `"d"` for high DPI support. "c" and `"d"` can be combined with the other flags. nil can be specified for normal sized uncentered text. | string |
| max\_width | Text will be clipped if it exceeds this width in pixels. Use 0 for no limit. | number |
| text | Text that will be drawn | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/text/#arguments)
---
# renderer | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/#docusaurus_skipToContent_fallback)
On this page
renderer
========
Description[](https://docs.gamesense.gs/docs/api/renderer/#description "Direct link to heading")
--------------------------------------------------------------------------------------------------
Functions for drawing on the screen. Usually won't work outside the [`paint`](https://docs.gamesense.gs/events#paint)
/ [`paint_ui`](https://docs.gamesense.gs/events#paint_ui)
events.
Functions[](https://docs.gamesense.gs/docs/api/renderer/#functions "Direct link to heading")
----------------------------------------------------------------------------------------------
### blur[](https://docs.gamesense.gs/docs/api/renderer/#blur "Direct link to heading")
[renderer.blur(x: number, y: number, w: number, h: number, alpha: number, amount: number)](https://docs.gamesense.gs/docs/api/renderer/blur)
> Creates a region on the screen that blurs everything behind it.
### circle[](https://docs.gamesense.gs/docs/api/renderer/#circle "Direct link to heading")
[renderer.circle(x: number, y: number, r: number, g: number, b: number, a: number, radius: number, start_degrees: number, percentage: number)](https://docs.gamesense.gs/docs/api/renderer/circle)
> Draws a filled circle on the screen
### circle\_outline[](https://docs.gamesense.gs/docs/api/renderer/#circle_outline "Direct link to heading")
[renderer.circle_outline(x: number, y: number, r: number, g: number, b: number, a: number, radius: number, start_degrees: number, percentage: number, thickness: number)](https://docs.gamesense.gs/docs/api/renderer/circleoutline)
> Draws the outline of a circle on the screen
### gradient[](https://docs.gamesense.gs/docs/api/renderer/#gradient "Direct link to heading")
[renderer.gradient(x: number, y: number, w: number, h: number, r1: number, g1: number, b1: number, a1: number, r2: number, g2: number, b2: number, a2: number, direction: boolean)](https://docs.gamesense.gs/docs/api/renderer/gradient)
> Draws a horizontal or vertical gradient on the screen.
### indicator[](https://docs.gamesense.gs/docs/api/renderer/#indicator "Direct link to heading")
[renderer.indicator(r: number, g: number, b: number, a: number, ...): number](https://docs.gamesense.gs/docs/api/renderer/indicator)
> Draws an indicator on the screen and returns the Y screen coordinate (vertical offset) of the drawn text, or nil on failure.
### line[](https://docs.gamesense.gs/docs/api/renderer/#line "Direct link to heading")
[renderer.line(x1: number, y1: number, x2: number, y2: number, r: number, g: number, b: number, a: number)](https://docs.gamesense.gs/docs/api/renderer/line)
> Draws a anti-aliased line on the screen.
### load\_jpg[](https://docs.gamesense.gs/docs/api/renderer/#load_jpg "Direct link to heading")
[renderer.load_jpg(contents: string, width: number, height: number): number](https://docs.gamesense.gs/docs/api/renderer/loadjpg)
> Loads a texture from raw JPG contents (with file header). The file can for example be loaded using [readfile](https://docs.gamesense.gs/docs/api/G/readfile)
> . Returns a texture ID that can be used with renderer.texture, or nil on failure
### load\_png[](https://docs.gamesense.gs/docs/api/renderer/#load_png "Direct link to heading")
[renderer.load_png(contents: string, width: number, height: number): number](https://docs.gamesense.gs/docs/api/renderer/loadpng)
> Loads a texture from raw PNG contents (with file header). The file can for example be loaded using [readfile](https://docs.gamesense.gs/docs/api/G/readfile)
> . Returns a texture ID that can be used with renderer.texture, or nil on failure
### load\_rgba[](https://docs.gamesense.gs/docs/api/renderer/#load_rgba "Direct link to heading")
[renderer.load_rgba(contents: string, width: number, height: number): number](https://docs.gamesense.gs/docs/api/renderer/loadrgba)
> Loads a texture from a RGBA buffer. Returns a texture ID that can be used with renderer.texture, or nil on failure
### load\_svg[](https://docs.gamesense.gs/docs/api/renderer/#load_svg "Direct link to heading")
[renderer.load_svg(contents: string, width: number, height: number): number](https://docs.gamesense.gs/docs/api/renderer/loadsvg)
> Loads a [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG)
> from a string. The file can for example be loaded using [readfile](https://docs.gamesense.gs/docs/api/G/readfile)
> . Returns a texture ID that can be used with [renderer.texture](https://docs.gamesense.gs/docs/api/renderer/#texture)
> , or nil on failure
### measure\_text[](https://docs.gamesense.gs/docs/api/renderer/#measure_text "Direct link to heading")
[renderer.measure_text(flags: string, ...): number, number](https://docs.gamesense.gs/docs/api/renderer/measuretext)
> Returns width, height. This can only be called from the paint callback.
### rectangle[](https://docs.gamesense.gs/docs/api/renderer/#rectangle "Direct link to heading")
[renderer.rectangle(x: number, y: number, w: number, h: number, r: number, g: number, b: number, a: number)](https://docs.gamesense.gs/docs/api/renderer/rectangle)
> Draws a filled rectangle on the screen
### text[](https://docs.gamesense.gs/docs/api/renderer/#text "Direct link to heading")
[renderer.text(x: number, y: number, r: number, g: number, b: number, a: number, flags: string, max_width: number, ...)](https://docs.gamesense.gs/docs/api/renderer/text)
> Draws text on the screen.
### texture[](https://docs.gamesense.gs/docs/api/renderer/#texture "Direct link to heading")
[renderer.texture(texture: number, x: number, y: number, w: number, h: number, r: number, g: number, b: number, a: number, mode: string)](https://docs.gamesense.gs/docs/api/renderer/texture)
> Draws a texture from the texture id created from [load\_rgba](https://docs.gamesense.gs/docs/api/renderer/#load_rgba)
> , [load\_png](https://docs.gamesense.gs/docs/api/renderer/#load_png)
> , [load\_jpg](https://docs.gamesense.gs/docs/api/renderer/#load_png)
> or [load\_svg](https://docs.gamesense.gs/docs/api/renderer/#load_svg)
### triangle[](https://docs.gamesense.gs/docs/api/renderer/#triangle "Direct link to heading")
[renderer.triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, r: number, g: number, b: number, a: number)](https://docs.gamesense.gs/docs/api/renderer/triangle)
> Draws a filled triangle on the screen. The points need to be specified in clockwise order.
### world\_to\_screen[](https://docs.gamesense.gs/docs/api/renderer/#world_to_screen "Direct link to heading")
[renderer.world_to_screen(x: number, y: number, z: number): number, number](https://docs.gamesense.gs/docs/api/renderer/worldtoscreen)
> Returns the screen coordinates of a world position or nil if the world position is not visible on your screen.
* [Description](https://docs.gamesense.gs/docs/api/renderer/#description)
* [Functions](https://docs.gamesense.gs/docs/api/renderer/#functions)
* [blur](https://docs.gamesense.gs/docs/api/renderer/#blur)
* [circle](https://docs.gamesense.gs/docs/api/renderer/#circle)
* [circle\_outline](https://docs.gamesense.gs/docs/api/renderer/#circle_outline)
* [gradient](https://docs.gamesense.gs/docs/api/renderer/#gradient)
* [indicator](https://docs.gamesense.gs/docs/api/renderer/#indicator)
* [line](https://docs.gamesense.gs/docs/api/renderer/#line)
* [load\_jpg](https://docs.gamesense.gs/docs/api/renderer/#load_jpg)
* [load\_png](https://docs.gamesense.gs/docs/api/renderer/#load_png)
* [load\_rgba](https://docs.gamesense.gs/docs/api/renderer/#load_rgba)
* [load\_svg](https://docs.gamesense.gs/docs/api/renderer/#load_svg)
* [measure\_text](https://docs.gamesense.gs/docs/api/renderer/#measure_text)
* [rectangle](https://docs.gamesense.gs/docs/api/renderer/#rectangle)
* [text](https://docs.gamesense.gs/docs/api/renderer/#text)
* [texture](https://docs.gamesense.gs/docs/api/renderer/#texture)
* [triangle](https://docs.gamesense.gs/docs/api/renderer/#triangle)
* [world\_to\_screen](https://docs.gamesense.gs/docs/api/renderer/#world_to_screen)
---
# string.byte | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/byte/#docusaurus_skipToContent_fallback)
On this page
string.byte
===========
Returns the given string's characters in their numeric ASCII representation.
string.byte(string: string, start: number, end: number): number
Arguments[](https://docs.gamesense.gs/docs/api/string/byte/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| string | One or more characters to convert. | string |
| start | Start index. Defaults to 1 | number |
| end | End index. Defaults to `start`. | number |
Returns `number`
* [Arguments](https://docs.gamesense.gs/docs/api/string/byte/#arguments)
---
# renderer.triangle | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/triangle/#docusaurus_skipToContent_fallback)
On this page
renderer.triangle
=================
Draws a filled triangle on the screen. The points need to be specified in clockwise order.
renderer.triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, r: number, g: number, b: number, a: number)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/triangle/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x1 | Screen coordinate X for point A | number |
| y1 | Screen coordinate Y for point A | number |
| x2 | Screen coordinate X for point B | number |
| y2 | Screen coordinate Y for point B | number |
| x3 | Screen coordinate X for point C | number |
| y3 | Screen coordinate Y for point C | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/triangle/#arguments)
---
# string.char | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/char/#docusaurus_skipToContent_fallback)
On this page
string.char
===========
Creates a string from one or more numeric ASCII codes.
string.char(...): string
Arguments[](https://docs.gamesense.gs/docs/api/string/char/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| byte | One or more numeric ASCII codes. | number |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/string/char/#arguments)
---
# renderer.texture | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/texture/#docusaurus_skipToContent_fallback)
On this page
renderer.texture
================
Draws a texture from the texture id created from [load\_rgba](https://docs.gamesense.gs/docs/api/renderer/texture/#load_rgba)
, [load\_png](https://docs.gamesense.gs/docs/api/renderer/texture/#load_png)
, [load\_jpg](https://docs.gamesense.gs/docs/api/renderer/texture/#load_png)
or [load\_svg](https://docs.gamesense.gs/docs/api/renderer/texture/#load_svg)
renderer.texture(texture: number, x: number, y: number, w: number, h: number, r: number, g: number, b: number, a: number, mode: string)
Arguments[](https://docs.gamesense.gs/docs/api/renderer/texture/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| texture | Texture ID | number |
| x | X screen coordinate | number |
| y | Y screen coordinate | number |
| w | Width | number |
| h | Height | number |
| r | Red color component (0 to 255) | number |
| g | Green color component (0 to 255) | number |
| b | Blue color component (0 to 255) | number |
| a | Alpha (opacity) component (0 to 255) | number |
| mode | `"f"` for filled, `"r"` for repeat, otherwise automatic | string |
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/texture/#arguments)
---
# string.gmatch | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/gmatch/#docusaurus_skipToContent_fallback)
On this page
string.gmatch
=============
Using [lua patterns](https://www.lua.org/pil/20.2.html)
, returns an iterator which will return either one value if no capture groups are defined, or any capture group matches.
string.gmatch(str: string, pattern: string): function
Arguments[](https://docs.gamesense.gs/docs/api/string/gmatch/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to search. | string |
| pattern | Pattern to search for. | string |
Returns `iterator: function`
* [Arguments](https://docs.gamesense.gs/docs/api/string/gmatch/#arguments)
---
# string.gsub | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/gsub/#docusaurus_skipToContent_fallback)
On this page
string.gsub
===========
Using [lua patterns](https://www.lua.org/pil/20.2.html)
, returns a copy of `str` with all matches of the pattern replaced by the given replacement string.
The pattern may be a string, a table or a function.
* If it is a string, then it can contain captures.
* If it is a table, the match is looked up in the table as a key, and the value (string) is used to replace it, if it exists.
* If it is a function, then the function is called for each match, with the value of the match as the first argument, the value of the n argument as the second argument, and the position of the match as the third argument. The function must then return the replacement string to be used for the match.
string.gsub(str: string, pattern: string, replacement: string, max: number): string, number
Arguments[](https://docs.gamesense.gs/docs/api/string/gsub/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to search. | string |
| pattern | Pattern to search for. | string |
| replacement | Replacement string or function. | string |
| max | Maximum number of replacements. | number |
Returns `string, number`
* [Arguments](https://docs.gamesense.gs/docs/api/string/gsub/#arguments)
---
# string.format | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/format/#docusaurus_skipToContent_fallback)
On this page
string.format
=============
Returns a formatted version of its variable number of arguments following the description given in its first argument (which must be a string). === Format string options
Available numeric format specifiers:
* **`%d`** - Decimal integer, rounded down.
* **`%o`** - Octal integer, rounded down.
* **`%x`** - Hexadecimal integer, rounded down. Use `%X` for uppercase.
* **`%f`** - Floating-point number, rounded based on the specified precision.
* **`%e`** - Scientific notation (mantissa/exponent). Use `%E` for uppercase.
* **`%g`** - Shortest float representation, either `%f` or `%e`. Use `%G` for uppercase.
* **`%a`** - Hexadecimal float. Use `%A` for uppercase.
Numeric specifiers can be combined with one or more of the following sub-specifiers:
* Padding: Use `%5d` to pad a number to at least 5 characters. By default, it will be padded with spaces, use `%05d` to use zeroes instead. Use `%-5d` to left-justify instead of right-justify the output.
* Sign: Use `%+d` to preceed positive numbers with a plus sign or `% d` to preceed them with a space.
* `#`: When used with `%o`, `%x` or `%X` it prefixes the output with 0, 0x or 0X respectively for values different than zero. Used with e, E, f, F, g or G it forces the written output to contain a decimal point even if no more digits follow.
* Precision: Number of digits to be printed after the decimal point, for example `%011.5f` to print 5 digits after the decimal point and pad the output to at least 11 characters (including the decimal point)
Other format specifiers:
* **`%c`** - Single character as ascii code.
* **`%s`** - String
* **`%q`** - String between double quotes, with all special characters escaped
* **`%%`** - A single `%` character.
String specifiers can also be combined with the width and right-justify sub-specifiers. Use `%16s` to make sure the output string is at least 16 characters long.
\===
string.format(format: string, ...)
Arguments[](https://docs.gamesense.gs/docs/api/string/format/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| format | Format string. | string |
| undefined | Arguments to insert into the format string. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/string/format/#arguments)
---
# string.find | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/find/#docusaurus_skipToContent_fallback)
On this page
info
More information on [lua patterns](https://www.lua.org/pil/20.2.html)
string.find
===========
Looks for the first match of the pattern in the string `str`. If it finds a match, then it returns the indices of `str` where the occurrence starts and ends; otherwise, it returns `nil`.
Passing true as the fourth argument turns off pattern matching facilities, so the function does a plain “find substring” operation, with no characters in the pattern being considered “magic”. Note that if `no_patterns` is given, then `start` must be given as well.
string.find(str: string, pattern: string, start: number, no_patterns: boolean): number, number
Arguments[](https://docs.gamesense.gs/docs/api/string/find/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to search. | string |
| pattern | Pattern to search for. | string |
| start | Start index. Defaults to 1 | number |
| no\_patterns | If true, then pattern matching is disabled. | boolean |
Returns `start: number, end: number`
* [Arguments](https://docs.gamesense.gs/docs/api/string/find/#arguments)
---
# renderer.world_to_screen | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/renderer/worldtoscreen/#docusaurus_skipToContent_fallback)
On this page
renderer.world\_to\_screen
==========================
Returns the screen coordinates of a world position or nil if the world position is not visible on your screen.
renderer.world_to_screen(x: number, y: number, z: number): number, number
Arguments[](https://docs.gamesense.gs/docs/api/renderer/worldtoscreen/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| x | X position in the world | number |
| y | Y position in the world | number |
| z | Z position in the world | number |
Returns `x: number, y: number`
* [Arguments](https://docs.gamesense.gs/docs/api/renderer/worldtoscreen/#arguments)
---
# string.lower | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/lower/#docusaurus_skipToContent_fallback)
On this page
string.lower
============
Returns a copy of `str` with all uppercase letters replaced by their lowercase counterparts.
string.lower(str: string): string
Arguments[](https://docs.gamesense.gs/docs/api/string/lower/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to lower-case. | string |
Returns `lower: string`
* [Arguments](https://docs.gamesense.gs/docs/api/string/lower/#arguments)
---
# string.len | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/len/#docusaurus_skipToContent_fallback)
On this page
string.len
==========
Returns the length of the string `str` in bytes.
string.len(str: string): number
Arguments[](https://docs.gamesense.gs/docs/api/string/len/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to get the length of. | string |
Returns `length: number`
* [Arguments](https://docs.gamesense.gs/docs/api/string/len/#arguments)
---
# string.match | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/match/#docusaurus_skipToContent_fallback)
On this page
string.match
============
Using [lua patterns](https://www.lua.org/pil/20.2.html)
, returns the first match of the pattern in the string `str`. If no match is found, it returns `nil`.
string.match(str: string, pattern: string, start): table
Arguments[](https://docs.gamesense.gs/docs/api/string/match/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to search. | string |
| pattern | Pattern to search for. | string |
| start | Where to start the search. Defaults to 1, can be negative. | unknown |
Returns `captures: table`
* [Arguments](https://docs.gamesense.gs/docs/api/string/match/#arguments)
---
# string.reverse | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/reverse/#docusaurus_skipToContent_fallback)
On this page
string.reverse
==============
Reverses the string `str`.
string.reverse(str: string): string
Arguments[](https://docs.gamesense.gs/docs/api/string/reverse/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to reverse. | string |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/string/reverse/#arguments)
---
# string.rep | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/rep/#docusaurus_skipToContent_fallback)
On this page
string.rep
==========
Repeats the string `n` times and concatenates them using the separator `sep`.
string.rep(str: string, n: number, sep: string): string
Arguments[](https://docs.gamesense.gs/docs/api/string/rep/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to repeat. | string |
| n | Number of times to repeat the string. | number |
| sep | Separator to use between the strings. None by default | string |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/string/rep/#arguments)
---
# string.sub | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/sub/#docusaurus_skipToContent_fallback)
On this page
string.sub
==========
Returns a substring of `str` starting at `s` and ending at `e`. Use negative numbers to start from the end of the string.
string.sub(str: string, s: number, e: number): string
Arguments[](https://docs.gamesense.gs/docs/api/string/sub/#arguments "Direct link to heading")
------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to get the substring of. | string |
| s | Where to start the substring, inclusive. Defaults to 1. | number |
| e | Where to end the substring. Defaults to -1 (end of the string). | number |
Returns `string`
* [Arguments](https://docs.gamesense.gs/docs/api/string/sub/#arguments)
---
# ui.is_menu_open | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/ismenuopen/#docusaurus_skipToContent_fallback)
ui.is\_menu\_open
=================
Returns true if the menu is currently open.
ui.is_menu_open(): boolean
Returns `menu open: boolean`
---
# string.upper | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/upper/#docusaurus_skipToContent_fallback)
On this page
string.upper
============
Returns a copy of `str` with all lowercase letters replaced by their uppercase counterparts.
string.upper(str: string): string
Arguments[](https://docs.gamesense.gs/docs/api/string/upper/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| str | String to upper-case. | string |
Returns `upper: string`
* [Arguments](https://docs.gamesense.gs/docs/api/string/upper/#arguments)
---
# ui.menu_position | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/menuposition/#docusaurus_skipToContent_fallback)
ui.menu\_position
=================
Returns the x, y of the menu, even when closed.
ui.menu_position(): number, number
Returns `x: number, y: number`
---
# ui.menu_size | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/menusize/#docusaurus_skipToContent_fallback)
ui.menu\_size
=============
Returns the width, height of the menu, even when closed.
ui.menu_size(): number, number
Returns `width: number, height: number`
---
# ui.mouse_position | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/mouseposition/#docusaurus_skipToContent_fallback)
ui.mouse\_position
==================
Returns current mouse coordinates x, y
ui.mouse_position(): number, number
Returns `x: number, y: number`
---
# string | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/string/#docusaurus_skipToContent_fallback)
On this page
string
======
Description[](https://docs.gamesense.gs/docs/api/string/#description "Direct link to heading")
------------------------------------------------------------------------------------------------
Standard library for generic string manipulation, such as finding and extracting substrings or pattern matching.
Functions[](https://docs.gamesense.gs/docs/api/string/#functions "Direct link to heading")
--------------------------------------------------------------------------------------------
### byte[](https://docs.gamesense.gs/docs/api/string/#byte "Direct link to heading")
[string.byte(string: string, start: number, end: number): number](https://docs.gamesense.gs/docs/api/string/byte)
> Returns the given string's characters in their numeric ASCII representation.
### char[](https://docs.gamesense.gs/docs/api/string/#char "Direct link to heading")
[string.char(...): string](https://docs.gamesense.gs/docs/api/string/char)
> Creates a string from one or more numeric ASCII codes.
### find[](https://docs.gamesense.gs/docs/api/string/#find "Direct link to heading")
[string.find(str: string, pattern: string, start: number, no_patterns: boolean): number, number](https://docs.gamesense.gs/docs/api/string/find)
> Looks for the first match of the pattern in the string `str`. If it finds a match, then it returns the indices of `str` where the occurrence starts and ends; otherwise, it returns `nil`.
Passing true as the fourth argument turns off pattern matching facilities, so the function does a plain “find substring” operation, with no characters in the pattern being considered “magic”. Note that if `no_patterns` is given, then `start` must be given as well.
### format[](https://docs.gamesense.gs/docs/api/string/#format "Direct link to heading")
[string.format(format: string, ...)](https://docs.gamesense.gs/docs/api/string/format)
> Returns a formatted version of its variable number of arguments following the description given in its first argument (which must be a string). === Format string options
Available numeric format specifiers:
* **`%d`** - Decimal integer, rounded down.
* **`%o`** - Octal integer, rounded down.
* **`%x`** - Hexadecimal integer, rounded down. Use `%X` for uppercase.
* **`%f`** - Floating-point number, rounded based on the specified precision.
* **`%e`** - Scientific notation (mantissa/exponent). Use `%E` for uppercase.
* **`%g`** - Shortest float representation, either `%f` or `%e`. Use `%G` for uppercase.
* **`%a`** - Hexadecimal float. Use `%A` for uppercase.
Numeric specifiers can be combined with one or more of the following sub-specifiers:
* Padding: Use `%5d` to pad a number to at least 5 characters. By default, it will be padded with spaces, use `%05d` to use zeroes instead. Use `%-5d` to left-justify instead of right-justify the output.
* Sign: Use `%+d` to preceed positive numbers with a plus sign or `% d` to preceed them with a space.
* `#`: When used with `%o`, `%x` or `%X` it prefixes the output with 0, 0x or 0X respectively for values different than zero. Used with e, E, f, F, g or G it forces the written output to contain a decimal point even if no more digits follow.
* Precision: Number of digits to be printed after the decimal point, for example `%011.5f` to print 5 digits after the decimal point and pad the output to at least 11 characters (including the decimal point)
Other format specifiers:
* **`%c`** - Single character as ascii code.
* **`%s`** - String
* **`%q`** - String between double quotes, with all special characters escaped
* **`%%`** - A single `%` character.
String specifiers can also be combined with the width and right-justify sub-specifiers. Use `%16s` to make sure the output string is at least 16 characters long.
\===
### gmatch[](https://docs.gamesense.gs/docs/api/string/#gmatch "Direct link to heading")
[string.gmatch(str: string, pattern: string): function](https://docs.gamesense.gs/docs/api/string/gmatch)
> Using [lua patterns](https://www.lua.org/pil/20.2.html)
> , returns an iterator which will return either one value if no capture groups are defined, or any capture group matches.
### gsub[](https://docs.gamesense.gs/docs/api/string/#gsub "Direct link to heading")
[string.gsub(str: string, pattern: string, replacement: string, max: number): string, number](https://docs.gamesense.gs/docs/api/string/gsub)
> Using [lua patterns](https://www.lua.org/pil/20.2.html)
> , returns a copy of `str` with all matches of the pattern replaced by the given replacement string.
The pattern may be a string, a table or a function.
* If it is a string, then it can contain captures.
* If it is a table, the match is looked up in the table as a key, and the value (string) is used to replace it, if it exists.
* If it is a function, then the function is called for each match, with the value of the match as the first argument, the value of the n argument as the second argument, and the position of the match as the third argument. The function must then return the replacement string to be used for the match.
### len[](https://docs.gamesense.gs/docs/api/string/#len "Direct link to heading")
[string.len(str: string): number](https://docs.gamesense.gs/docs/api/string/len)
> Returns the length of the string `str` in bytes.
### lower[](https://docs.gamesense.gs/docs/api/string/#lower "Direct link to heading")
[string.lower(str: string): string](https://docs.gamesense.gs/docs/api/string/lower)
> Returns a copy of `str` with all uppercase letters replaced by their lowercase counterparts.
### match[](https://docs.gamesense.gs/docs/api/string/#match "Direct link to heading")
[string.match(str: string, pattern: string, start): table](https://docs.gamesense.gs/docs/api/string/match)
> Using [lua patterns](https://www.lua.org/pil/20.2.html)
> , returns the first match of the pattern in the string `str`. If no match is found, it returns `nil`.
### rep[](https://docs.gamesense.gs/docs/api/string/#rep "Direct link to heading")
[string.rep(str: string, n: number, sep: string): string](https://docs.gamesense.gs/docs/api/string/rep)
> Repeats the string `n` times and concatenates them using the separator `sep`.
### reverse[](https://docs.gamesense.gs/docs/api/string/#reverse "Direct link to heading")
[string.reverse(str: string): string](https://docs.gamesense.gs/docs/api/string/reverse)
> Reverses the string `str`.
### sub[](https://docs.gamesense.gs/docs/api/string/#sub "Direct link to heading")
[string.sub(str: string, s: number, e: number): string](https://docs.gamesense.gs/docs/api/string/sub)
> Returns a substring of `str` starting at `s` and ending at `e`. Use negative numbers to start from the end of the string.
### upper[](https://docs.gamesense.gs/docs/api/string/#upper "Direct link to heading")
[string.upper(str: string): string](https://docs.gamesense.gs/docs/api/string/upper)
> Returns a copy of `str` with all lowercase letters replaced by their uppercase counterparts.
* [Description](https://docs.gamesense.gs/docs/api/string/#description)
* [Functions](https://docs.gamesense.gs/docs/api/string/#functions)
* [byte](https://docs.gamesense.gs/docs/api/string/#byte)
* [char](https://docs.gamesense.gs/docs/api/string/#char)
* [find](https://docs.gamesense.gs/docs/api/string/#find)
* [format](https://docs.gamesense.gs/docs/api/string/#format)
* [gmatch](https://docs.gamesense.gs/docs/api/string/#gmatch)
* [gsub](https://docs.gamesense.gs/docs/api/string/#gsub)
* [len](https://docs.gamesense.gs/docs/api/string/#len)
* [lower](https://docs.gamesense.gs/docs/api/string/#lower)
* [match](https://docs.gamesense.gs/docs/api/string/#match)
* [rep](https://docs.gamesense.gs/docs/api/string/#rep)
* [reverse](https://docs.gamesense.gs/docs/api/string/#reverse)
* [sub](https://docs.gamesense.gs/docs/api/string/#sub)
* [upper](https://docs.gamesense.gs/docs/api/string/#upper)
---
# ui.new_button | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newbutton/#docusaurus_skipToContent_fallback)
On this page
ui.new\_button
==============
Throws an error on failure. The return value should not be used with ui.set or ui.get.
ui.new_button(tab: string, container: string, name: string, callback): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newbutton/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this checkbox will be added. | string |
| name | The name of the button. | string |
| callback | The lua function that will be called when the button is pressed. | function |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newbutton/#arguments)
---
# ui.new_checkbox | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newcheckbox/#docusaurus_skipToContent_fallback)
On this page
ui.new\_checkbox
================
Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
ui.new_checkbox(tab: string, container: string, name: string): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newcheckbox/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this control will be added. | string |
| name | The name of the checkbox. | string |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newcheckbox/#arguments)
---
# ui.new_color_picker | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newcolorpicker/#docusaurus_skipToContent_fallback)
On this page
ui.new\_color\_picker
=====================
Throws an error on failure. The color picker is placed to the right of the previous menu item.
ui.new_color_picker(tab: string, container: string, name: string, r: number, g: number, b: number, a: number): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newcolorpicker/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this checkbox will be added. | string |
| name | The name of the color picker. This will not be shown, it is only used to identify this item in saved configs. | string |
| r | Initial red value (0-255) | number |
| g | Initial green value (0-255) | number |
| b | Initial blue value (0-255) | number |
| a | Initial alpha value (0-255) | number |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newcolorpicker/#arguments)
---
# ui.new_combobox | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newcombobox/#docusaurus_skipToContent_fallback)
On this page
ui.new\_combobox
================
Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
ui.new_combobox(tab: string, container: string, name: string, ...): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newcombobox/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this control will be added. | string |
| name | The name of the combobox. | string |
| ... | One or more comma separated string values that will be added to the combobox. Alternatively, a table of strings that will be added. | unknown |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newcombobox/#arguments)
---
# ui.new_multiselect | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newmultiselect/#docusaurus_skipToContent_fallback)
On this page
ui.new\_multiselect
===================
Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
ui.new_multiselect(tab: string, container: string, name: string, ...): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newmultiselect/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this control will be added. | string |
| name | The name of the multiselect. | string |
| ... | One or more comma separated string values that will be added to the combobox. Alternatively, a table of strings that will be added. | unknown |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newmultiselect/#arguments)
---
# ui.new_listbox | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newlistbox/#docusaurus_skipToContent_fallback)
On this page
ui.new\_listbox
===============
Throws an error on failure. Returns a special value that can be used with ui.get. Calling ui.get on a listbox will return the zero-based index of the currently selected string.
ui.new_listbox(tab: string, container: string, name: string, items: table): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newlistbox/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA | string |
| container | The name of the existing container to which this listbox will be added | string |
| name | Name | string |
| items | Table of items (strings) | table |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newlistbox/#arguments)
---
# ui.new_hotkey | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newhotkey/#docusaurus_skipToContent_fallback)
On this page
ui.new\_hotkey
==============
Returns a special value that can be passed to ui.get to see if the hotkey is pressed, or throws an error on failure.
ui.new_hotkey(tab: string, container: string, name: string, inline: boolean, default_hotkey: number): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newhotkey/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this control will be added. | string |
| name | The name of the hotkey. | string |
| inline | Boolean. If set to true, the hotkey will be placed to the right of the preceding menu item. | boolean |
| default\_hotkey | Virtual key | number |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newhotkey/#arguments)
---
# ui.new_label | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newlabel/#docusaurus_skipToContent_fallback)
On this page
ui.new\_label
=============
Creates a new label, this can be used to make otherwise attached menu items standalone or have interactive menus. Returns a special value that can be passed to ui.set, or throws an error on failure.
ui.new_label(tab: string, container: string, name: string): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newlabel/#arguments "Direct link to heading")
-------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, CONFIG or LUA. | string |
| container | The name of the existing container to which this control will be added. | string |
| name | The name of the label. This can later be changed using ui.set. | string |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newlabel/#arguments)
---
# ui.new_string | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newstring/#docusaurus_skipToContent_fallback)
On this page
ui.new\_string
==============
Creates a string UI element, can be used to store arbitrary strings in configs. No menu item is created but it has the same semantics as other ui.new\_\* functions. Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
ui.new_string(name: string, default_value: string): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newstring/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| name | The name of the string element, make sure this is unique. | string |
| default\_value | String that specifies the default value. | string |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newstring/#arguments)
---
# ui.get | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/get/#docusaurus_skipToContent_fallback)
On this page
ui.get
======
For a checkbox, returns true or false. For a slider, returns an integer. For a combobox, returns a string. For a multiselect combobox, returns an array of strings. For a hotkey, returns true if the hotkey is active. For a color picker, returns r, g, b, a. Throws an error on failure.
ui.get(item: number): any
Arguments[](https://docs.gamesense.gs/docs/api/ui/get/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | The special value returned by ui.new\_checkbox, ui.new\_slider, ui.new\_combobox, ui.new\_hotkey, or ui.reference. | number |
Returns `the current value of the menu item: any`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/get/#arguments)
---
# ui.new_textbox | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newtextbox/#docusaurus_skipToContent_fallback)
On this page
ui.new\_textbox
===============
Throws an error on failure. Returns a special value that can be used with ui.get
ui.new_textbox(tab: string, container: string, name: string): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newtextbox/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this textbox will be added. | string |
| name | The name of the textbox | string |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newtextbox/#arguments)
---
# ui.reference | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/reference/#docusaurus_skipToContent_fallback)
On this page
ui.reference
============
Avoid calling this from inside a function. Returns a reference that can be passed to ui.get and ui.set, or throws an error on failure. This allows you to access a built-in pre-existing menu items. This function returns multiple values when the specified menu item is followed by unnamed menu items, for example a color picker or a hotkey.
ui.reference(tab: string, container: string, name: string): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/reference/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this checkbox will be added. | string |
| name | The name of the menu item. | string |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/reference/#arguments)
---
# ui.new_slider | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/newslider/#docusaurus_skipToContent_fallback)
On this page
ui.new\_slider
==============
Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
ui.new_slider(tab: string, container: string, name: string, min: number, max: number, init_value: number, show_tooltip: boolean, unit: string, scale: number, tooltips: table): number
Arguments[](https://docs.gamesense.gs/docs/api/ui/newslider/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| tab | The name of the tab: RAGE, AA, LEGIT, VISUALS, MISC, SKINS, PLAYERS, LUA. | string |
| container | The name of the existing container to which this control will be added. | string |
| name | The name of the slider. | string |
| min | The minimum value that can be set using the slider. | number |
| max | The maximum value that can be set using the slider. | number |
| init\_value | Integer. The initial value. If not provided, the initial value will be min. | number |
| show\_tooltip | Boolean. true if the slider should display its current value. | boolean |
| unit | String that is two characters or less. This will be appended to the display value. For example, "px" for pixels or "%" for a percentage. | string |
| scale | The display value will be multiplied by this scale. For example, 0.1 will make a slider with the range \[0-1800\] show as 0.0-180.0 with one decimal place. | number |
| tooltips | Table used to override the tooltip for the specified values. The key must be within min-max. The value is a string that will be shown instead of the numeric value whenever that value is selected. | table |
Returns `menu item: number`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/newslider/#arguments)
---
# ui | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/#docusaurus_skipToContent_fallback)
On this page
ui
==
Description[](https://docs.gamesense.gs/docs/api/ui/#description "Direct link to heading")
--------------------------------------------------------------------------------------------
Functions for interfacing with the GameSense user interface.
Functions[](https://docs.gamesense.gs/docs/api/ui/#functions "Direct link to heading")
----------------------------------------------------------------------------------------
### get[](https://docs.gamesense.gs/docs/api/ui/#get "Direct link to heading")
[ui.get(item: number): any](https://docs.gamesense.gs/docs/api/ui/get)
> For a checkbox, returns true or false. For a slider, returns an integer. For a combobox, returns a string. For a multiselect combobox, returns an array of strings. For a hotkey, returns true if the hotkey is active. For a color picker, returns r, g, b, a. Throws an error on failure.
### is\_menu\_open[](https://docs.gamesense.gs/docs/api/ui/#is_menu_open "Direct link to heading")
[ui.is_menu_open(): boolean](https://docs.gamesense.gs/docs/api/ui/ismenuopen)
> Returns true if the menu is currently open.
### menu\_position[](https://docs.gamesense.gs/docs/api/ui/#menu_position "Direct link to heading")
[ui.menu_position(): number, number](https://docs.gamesense.gs/docs/api/ui/menuposition)
> Returns the x, y of the menu, even when closed.
### menu\_size[](https://docs.gamesense.gs/docs/api/ui/#menu_size "Direct link to heading")
[ui.menu_size(): number, number](https://docs.gamesense.gs/docs/api/ui/menusize)
> Returns the width, height of the menu, even when closed.
### mouse\_position[](https://docs.gamesense.gs/docs/api/ui/#mouse_position "Direct link to heading")
[ui.mouse_position(): number, number](https://docs.gamesense.gs/docs/api/ui/mouseposition)
> Returns current mouse coordinates x, y
### name[](https://docs.gamesense.gs/docs/api/ui/#name "Direct link to heading")
[ui.name(item: number): string](https://docs.gamesense.gs/docs/api/ui/name)
> Returns the display name
### new\_button[](https://docs.gamesense.gs/docs/api/ui/#new_button "Direct link to heading")
[ui.new_button(tab: string, container: string, name: string, callback): number](https://docs.gamesense.gs/docs/api/ui/newbutton)
> Throws an error on failure. The return value should not be used with ui.set or ui.get.
### new\_checkbox[](https://docs.gamesense.gs/docs/api/ui/#new_checkbox "Direct link to heading")
[ui.new_checkbox(tab: string, container: string, name: string): number](https://docs.gamesense.gs/docs/api/ui/newcheckbox)
> Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
### new\_color\_picker[](https://docs.gamesense.gs/docs/api/ui/#new_color_picker "Direct link to heading")
[ui.new_color_picker(tab: string, container: string, name: string, r: number, g: number, b: number, a: number): number](https://docs.gamesense.gs/docs/api/ui/newcolorpicker)
> Throws an error on failure. The color picker is placed to the right of the previous menu item.
### new\_combobox[](https://docs.gamesense.gs/docs/api/ui/#new_combobox "Direct link to heading")
[ui.new_combobox(tab: string, container: string, name: string, ...): number](https://docs.gamesense.gs/docs/api/ui/newcombobox)
> Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
### new\_hotkey[](https://docs.gamesense.gs/docs/api/ui/#new_hotkey "Direct link to heading")
[ui.new_hotkey(tab: string, container: string, name: string, inline: boolean, default_hotkey: number): number](https://docs.gamesense.gs/docs/api/ui/newhotkey)
> Returns a special value that can be passed to ui.get to see if the hotkey is pressed, or throws an error on failure.
### new\_label[](https://docs.gamesense.gs/docs/api/ui/#new_label "Direct link to heading")
[ui.new_label(tab: string, container: string, name: string): number](https://docs.gamesense.gs/docs/api/ui/newlabel)
> Creates a new label, this can be used to make otherwise attached menu items standalone or have interactive menus. Returns a special value that can be passed to ui.set, or throws an error on failure.
### new\_listbox[](https://docs.gamesense.gs/docs/api/ui/#new_listbox "Direct link to heading")
[ui.new_listbox(tab: string, container: string, name: string, items: table): number](https://docs.gamesense.gs/docs/api/ui/newlistbox)
> Throws an error on failure. Returns a special value that can be used with ui.get. Calling ui.get on a listbox will return the zero-based index of the currently selected string.
### new\_multiselect[](https://docs.gamesense.gs/docs/api/ui/#new_multiselect "Direct link to heading")
[ui.new_multiselect(tab: string, container: string, name: string, ...): number](https://docs.gamesense.gs/docs/api/ui/newmultiselect)
> Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
### new\_slider[](https://docs.gamesense.gs/docs/api/ui/#new_slider "Direct link to heading")
[ui.new_slider(tab: string, container: string, name: string, min: number, max: number, init_value: number, show_tooltip: boolean, unit: string, scale: number, tooltips: table): number](https://docs.gamesense.gs/docs/api/ui/newslider)
> Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
### new\_string[](https://docs.gamesense.gs/docs/api/ui/#new_string "Direct link to heading")
[ui.new_string(name: string, default_value: string): number](https://docs.gamesense.gs/docs/api/ui/newstring)
> Creates a string UI element, can be used to store arbitrary strings in configs. No menu item is created but it has the same semantics as other ui.new\_\* functions. Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
### new\_textbox[](https://docs.gamesense.gs/docs/api/ui/#new_textbox "Direct link to heading")
[ui.new_textbox(tab: string, container: string, name: string): number](https://docs.gamesense.gs/docs/api/ui/newtextbox)
> Throws an error on failure. Returns a special value that can be used with ui.get
### reference[](https://docs.gamesense.gs/docs/api/ui/#reference "Direct link to heading")
[ui.reference(tab: string, container: string, name: string): number](https://docs.gamesense.gs/docs/api/ui/reference)
> Avoid calling this from inside a function. Returns a reference that can be passed to ui.get and ui.set, or throws an error on failure. This allows you to access a built-in pre-existing menu items. This function returns multiple values when the specified menu item is followed by unnamed menu items, for example a color picker or a hotkey.
### set[](https://docs.gamesense.gs/docs/api/ui/#set "Direct link to heading")
[ui.set(item: number, value: any, ...)](https://docs.gamesense.gs/docs/api/ui/set)
> For checkboxes, pass true or false. For a slider, pass a number that is within the slider's minimum/maximum values. For a combobox, pass a string value. For a multiselect combobox, pass zero or more strings. For referenced buttons, value is ignored and the button's callback is invoked. For color pickers, pass the arguments r, g, b, a.
### set\_callback[](https://docs.gamesense.gs/docs/api/ui/#set_callback "Direct link to heading")
[ui.set_callback(item: number, callback)](https://docs.gamesense.gs/docs/api/ui/setcallback)
> Sets the change callback of a custom menu item. It will be executed on change and passed the reference
### set\_enabled[](https://docs.gamesense.gs/docs/api/ui/#set_enabled "Direct link to heading")
[ui.set_enabled(item: number, enabled: boolean)](https://docs.gamesense.gs/docs/api/ui/setenabled)
> Sets the enabled state of the menu item
### set\_visible[](https://docs.gamesense.gs/docs/api/ui/#set_visible "Direct link to heading")
[ui.set_visible(item: number, visible: boolean)](https://docs.gamesense.gs/docs/api/ui/setvisible)
> Sets the visibility of the menu item
### type[](https://docs.gamesense.gs/docs/api/ui/#type "Direct link to heading")
[ui.type(item: number)](https://docs.gamesense.gs/docs/api/ui/type)
> Returns the type of an element
### update[](https://docs.gamesense.gs/docs/api/ui/#update "Direct link to heading")
[ui.update(item: number, value: any, ...)](https://docs.gamesense.gs/docs/api/ui/update)
> Creates a string UI element, can be used to store arbitrary strings in configs. No menu item is created but it has the same semantics as other ui.new\_\* functions. Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
* [Description](https://docs.gamesense.gs/docs/api/ui/#description)
* [Functions](https://docs.gamesense.gs/docs/api/ui/#functions)
* [get](https://docs.gamesense.gs/docs/api/ui/#get)
* [is\_menu\_open](https://docs.gamesense.gs/docs/api/ui/#is_menu_open)
* [menu\_position](https://docs.gamesense.gs/docs/api/ui/#menu_position)
* [menu\_size](https://docs.gamesense.gs/docs/api/ui/#menu_size)
* [mouse\_position](https://docs.gamesense.gs/docs/api/ui/#mouse_position)
* [name](https://docs.gamesense.gs/docs/api/ui/#name)
* [new\_button](https://docs.gamesense.gs/docs/api/ui/#new_button)
* [new\_checkbox](https://docs.gamesense.gs/docs/api/ui/#new_checkbox)
* [new\_color\_picker](https://docs.gamesense.gs/docs/api/ui/#new_color_picker)
* [new\_combobox](https://docs.gamesense.gs/docs/api/ui/#new_combobox)
* [new\_hotkey](https://docs.gamesense.gs/docs/api/ui/#new_hotkey)
* [new\_label](https://docs.gamesense.gs/docs/api/ui/#new_label)
* [new\_listbox](https://docs.gamesense.gs/docs/api/ui/#new_listbox)
* [new\_multiselect](https://docs.gamesense.gs/docs/api/ui/#new_multiselect)
* [new\_slider](https://docs.gamesense.gs/docs/api/ui/#new_slider)
* [new\_string](https://docs.gamesense.gs/docs/api/ui/#new_string)
* [new\_textbox](https://docs.gamesense.gs/docs/api/ui/#new_textbox)
* [reference](https://docs.gamesense.gs/docs/api/ui/#reference)
* [set](https://docs.gamesense.gs/docs/api/ui/#set)
* [set\_callback](https://docs.gamesense.gs/docs/api/ui/#set_callback)
* [set\_enabled](https://docs.gamesense.gs/docs/api/ui/#set_enabled)
* [set\_visible](https://docs.gamesense.gs/docs/api/ui/#set_visible)
* [type](https://docs.gamesense.gs/docs/api/ui/#type)
* [update](https://docs.gamesense.gs/docs/api/ui/#update)
---
# ui.set | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/set/#docusaurus_skipToContent_fallback)
On this page
ui.set
======
For checkboxes, pass true or false. For a slider, pass a number that is within the slider's minimum/maximum values. For a combobox, pass a string value. For a multiselect combobox, pass zero or more strings. For referenced buttons, value is ignored and the button's callback is invoked. For color pickers, pass the arguments r, g, b, a.
ui.set(item: number, value: any, ...)
Arguments[](https://docs.gamesense.gs/docs/api/ui/set/#arguments "Direct link to heading")
--------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | The result of either ui.new\_\* or ui.reference | number |
| value | The value to which the menu item will be set | any |
| ... | For multiselect comboboxes, you may want to set more than one option. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/ui/set/#arguments)
---
# ui.set_callback | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/setcallback/#docusaurus_skipToContent_fallback)
On this page
ui.set\_callback
================
Sets the change callback of a custom menu item. It will be executed on change and passed the reference
ui.set_callback(item: number, callback)
Arguments[](https://docs.gamesense.gs/docs/api/ui/setcallback/#arguments "Direct link to heading")
----------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | The special value returned by ui.new\_\*. Do not try passing a reference to an existing menu item. | number |
| callback | Lua function that will be called when the menu item changes values. For example, this will be called when the user checks or unchecks a checkbox. | function |
* [Arguments](https://docs.gamesense.gs/docs/api/ui/setcallback/#arguments)
---
# ui.set_enabled | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/setenabled/#docusaurus_skipToContent_fallback)
On this page
ui.set\_enabled
===============
Sets the enabled state of the menu item
ui.set_enabled(item: number, enabled: boolean)
Arguments[](https://docs.gamesense.gs/docs/api/ui/setenabled/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | A menu item reference. | number |
| enabled | Boolean. Pass false to lock the control from value alteration. | boolean |
* [Arguments](https://docs.gamesense.gs/docs/api/ui/setenabled/#arguments)
---
# vector | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/vector/#docusaurus_skipToContent_fallback)
On this page
vector
======
Description[](https://docs.gamesense.gs/docs/api/vector/#description "Direct link to heading")
------------------------------------------------------------------------------------------------
Built-in euclidean vector math library. To use it, load it at the top of your script using require:
local vector = require("vector")local myVec = vector(0, 0, 0)
info
The documentation for the `vector` type is unfinished as it relies on types that aren't in the docs yet.
Functions[](https://docs.gamesense.gs/docs/api/vector/#functions "Direct link to heading")
--------------------------------------------------------------------------------------------
### \_\_call[](https://docs.gamesense.gs/docs/api/vector/#__call "Direct link to heading")
[vector.__call(x: number, y: number, z: number): vector](https://docs.gamesense.gs/docs/api/vector/call)
> Creates a new vector object
* [Description](https://docs.gamesense.gs/docs/api/vector/#description)
* [Functions](https://docs.gamesense.gs/docs/api/vector/#functions)
* [\_\_call](https://docs.gamesense.gs/docs/api/vector/#__call)
---
# ui.update | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/update/#docusaurus_skipToContent_fallback)
On this page
ui.update
=========
Creates a string UI element, can be used to store arbitrary strings in configs. No menu item is created but it has the same semantics as other ui.new\_\* functions. Returns a special value that can be passed to ui.get and ui.set, or throws an error on failure.
ui.update(item: number, value: any, ...)
Arguments[](https://docs.gamesense.gs/docs/api/ui/update/#arguments "Direct link to heading")
-----------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | The special value returned by ui.new\_checkbox, ui.new\_slider, ui.new\_combobox, ui.new\_hotkey, or ui.reference. | number |
| value | The value to which the menu item will be set | any |
| ... | For multiselect comboboxes, you may want to set more than one option. | unknown |
* [Arguments](https://docs.gamesense.gs/docs/api/ui/update/#arguments)
---
# ui.set_visible | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/setvisible/#docusaurus_skipToContent_fallback)
On this page
ui.set\_visible
===============
Sets the visibility of the menu item
ui.set_visible(item: number, visible: boolean)
Arguments[](https://docs.gamesense.gs/docs/api/ui/setvisible/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | A menu item reference. | number |
| visible | Boolean. Pass false to hide the control from the menu, or nil to return the previous visibility state. | boolean |
* [Arguments](https://docs.gamesense.gs/docs/api/ui/setvisible/#arguments)
---
# ui.name | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/name/#docusaurus_skipToContent_fallback)
On this page
ui.name
=======
Returns the display name
ui.name(item: number): string
Arguments[](https://docs.gamesense.gs/docs/api/ui/name/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | The special value returned by ui.new\_checkbox, ui.new\_slider, ui.new\_combobox, ui.new\_hotkey, or ui.reference. | number |
Returns `display name: string`
* [Arguments](https://docs.gamesense.gs/docs/api/ui/name/#arguments)
---
# ui.type | GameSense Documentation
[Skip to main content](https://docs.gamesense.gs/docs/api/ui/type/#docusaurus_skipToContent_fallback)
On this page
ui.type
=======
Returns the type of an element
ui.type(item: number)
Arguments[](https://docs.gamesense.gs/docs/api/ui/type/#arguments "Direct link to heading")
---------------------------------------------------------------------------------------------
| Name | Description | Type |
| --- | --- | --- |
| item | The special value returned by ui.new\_checkbox, ui.new\_slider, ui.new\_combobox, ui.new\_hotkey, or ui.reference. | number |
* [Arguments](https://docs.gamesense.gs/docs/api/ui/type/#arguments)
---