Lua API
  • 🔎Overview
  • Introduction
    • 🚀Creating scripts
      • 🧠First Steps
      • 🖥️Adding UI
      • 📚Creating Libraries
  • API
    • 🌐Global Functions
    • ⚙️Instances
      • 🔢Math
      • ☎️Events
        • event_t
      • 🎮Game
        • global_vars_t
        • cengine_client
          • cnet_chan
        • ccsgo_input
        • cinput_system
        • cgame_ui_funcs
        • ccvar
          • convar
      • 🕹️Mods
        • events_t
      • ✏️Draw
        • ⚙️Types
          • ⚙️rect
          • ⚙️vec2
          • ⚙️color
          • ⚙️accessor
        • 🖥️Adapter
        • ✏️Layer
          • outline_mode
          • rounding
          • glow_parts
          • text_params
            • text_alignment
          • shadow_dir
          • command
            • render_mode
        • 🖼️Managed
          • 🖼️texture
            • svg_texture
            • animated_texture
          • 🖼️shader
          • ™️font_base
            • font
            • font_gdi
            • glyph_t
            • font_flags
      • 🙋Entities
        • entity_list_t
          • entity_entry_t
        • base_entity
          • schema_accessor_t
          • cs2_weapon_base_gun
          • cs2_player_pawn
          • cs2_player_controller
          • cs2_weapon_base
          • cs2_grenade_projectile
        • ccsweapon_base_vdata
          • cfiring_mode
        • chandle
        • csweapon_mode
        • csweapon_type
        • weapon_id
        • csweapon_category
        • observer_mode_t
      • 🖥️Gui
        • ⚙️Types
          • ⚙️bits
          • ⚙️control_id
        • context
          • user_t
        • context_input
          • mouse_button
        • notification_system
          • notification
        • control
          • control_type
          • value_param
          • checkbox
          • slider
          • label
          • selectable
          • button
          • color_picker
          • spacer
          • text_input
          • combo_box
          • image
        • container
          • control_container
            • layout
            • group
      • ⚙️Utils
    • ⚙️Types
      • ⚙️ptr
      • ⚙️ref_holder_t
      • ⚙️vector
      • ⚙️vector4d
      • 🎮veccolor
      • 🎮color
      • 🎮cview_setup
      • 🎮cuser_cmd
      • 🎮game_event_t
    • 🟰Enums
      • 🟰client_frame_stage
      • 🟰input_bit_mask
Powered by GitBook

© 2025 - FATALITY

On this page
  • Fire up a text editor
  • Writing your first script
  • Defining a callback function
  • Accessing drawing layer
  • Result
Export as PDF
  1. Introduction
  2. Creating scripts

First Steps

PreviousCreating scriptsNextAdding UI

Last updated 3 months ago

Now that you’ve covered the essentials, it’s time to start scripting.

Fire up a text editor

Feel free to use any text editor you prefer: , , or even a simple Notepad.

Local scripts are located here: <CS2_Directory>/game/csgo/fatality/scripts. You may notice there's also a lib directory, but we’ll get to that later.

Create a new file ending with .lua, and begin your work on the script.

.ljbc format cannot be loaded from local sources.

Writing your first script

A typical “Hello world!” example can be a bit trivial, so let’s try something slightly more advanced instead.

local function on_present_queue()
    local d = draw.surface;
    d.font = draw.fonts['gui_main'];
    d:add_text(draw.vec2(50, 50),
        'Hello drawing! My first script speaking.',
         draw.color.white()
    );
end

events.present_queue:add(on_present_queue);

Now, let's break down this example script:

Defining a callback function

local function on_present_queue()
end

Defining something local is optional, although recommended for clearer scope management.

Accessing drawing layer

With the callback function defined, let’s actually render something on the screen!

This setup allows you not only to draw but also to query information on player health or other entities.

To access the layer, simply reference the surface field in the draw table:

local d = draw.surface;

You don't have to store it in a variable, but it would be nicer if you don't have to type out draw.surface every time, right?

Setting a font

After retrieving the layer, you must set a font object before drawing any text on the screen. This is purely for performance reasons, so you don’t have to pass a heavy font object every time you draw text.

d.font = draw.fonts['gui_main'];

Drawing text

With the font set, it’s time to draw some text.

You can also invoke methods with a dot syntax, as long as you provide the object in the first argument. Both calls: obj:fn() and obj.fn(obj) are identical.

d:add_text(draw.vec2(50, 50),
        'Hello drawing! My first script speaking brev.',
         draw.color.white()
    );

Registering a callback

events.present_queue:add(on_present_queue);

Result

That's it! If you've done everything correctly, you should see something like this:

Most of your scripting will run within we provide. Each event has its own signature, so pay attention to the parameters your callback function should accept. present_queue doesn’t provide any parameters, so our function doesn’t need any either.

To do this, you first need to access the . We provide a single drawing layer that’s safe to use within the game thread. Due to how the game functions internally, it’s strongly discouraged to call game functions in other threads. Luckily all of our events run in the game thread.

All fonts are stored in . To access a font, either use dot syntax, or treat it like a dictionary:

Invoke the method on the layer. Notice that it’s called using the colon syntax: obj:fn(), because it’s a method.

Now that you’ve created your first callback, you need to register it so Fatality knows to invoke it. This is done by calling the method on .

🚀
🧠
Visual Studio Code
Notepad++
several callbacks
drawing layer
add
events.present_queue
draw.fonts
My first lua
add_text