listener
Global signal system for multi-purpose callbacks.
Aimbot & triggerbot
should_aimbot_target(entIndex: number): boolean
- Determines if the player should be targeted by the aimbot or not.
- Also applies to legit bot.
secret.listener.add("should_aimbot_target", "notarget", function(index)
return true -- blocks
end)
should_triggerbot_target(entIndex: number): boolean
- Determines if the player should be targeted by the triggerbot.
secret.listener.add("should_triggerbot_target", "notrigger", function(index)
return true -- blocks
end)
override_vischeck(aimbot_target_index: number, tstart: vector, tend: vector, record: boolean): boolean
- Called every time the cheat performs a visibility check between you and a potential aimbot target.
- Currently only ragebot uses this listener.
- tstart – starting position of the trace (usually your eye position).
- tend – ending position of the trace (usually the target hitbox).
- record - is the trace running at a backtrack record?
- Return value:
true→ force the vischeck to succeed (target is always considered visible).false→ force the vischeck to fail (target is never considered visible).nil→ do nothing and let the default engine visibility check decide.
-- simple override, treat everyone as visible.
secret.listener.add("override_vischeck", "always_visible", function(target_index, tstart, tend, record)
return true
end)
-- custom logic, allow vis if distance < 500 units
secret.listener.add("override_vischeck", "short_range_vis", function(target_index, tstart, tend, record)
local dist = (tend - tstart):Length()
if dist < 500 then
return true
end
end)
should_aimbot_autofire(): boolean
- Called every time the ragebot decides whether it should autofire.
- Useful for custom logic to control when the ragebot fires (e.g., based on target state, weapon, or other conditions).
secret.listener.add("should_aimbot_autofire", "custom_logic", function()
-- only allow autofire if some condition is met
return LocalPlayer():Health() > 50
end)
override_aimbot_angle(target_ent_index: number, original_angle: Angle, target_angle: Angle): boolean,(Angle)
- Lets you override the final aim angle before the aimbot uses it.
- return true, new_angle to apply your override.
- return false to use the default angle.
secret.listener.add("override_aimbot_angle", "67", function(target_ent_index, original_angle, target_angle)
local target = Entity(target_ent_index)
-- override when target is low hp
if target and target:Health() < 30 then
local new_ang = Angle(67, 67, 0)
return true, new_ang
end
return false
end)
ESP
should_draw_player(entIndex: number): boolean
- Determines if the player should be drawn in the esp or not.
secret.listener.add("should_draw_player", "nodraw", function(index)
return true -- blocks
end)
should_draw_entity(entIndex: number): boolean
- Determines if an entity should be drawn in the esp or not.
secret.listener.add("should_draw_entity", "nodraw", function(index)
return true -- blocks
end)
Player overrides
Global overrides run before the ESP-specific listeners below (esp_player_name, esp_player_usergroup, esp_player_team_name, esp_player_team_color). They affect the playerlist and the baseline values ESP builds from.
Use override listeners when you want one RP name, usergroup, or team everywhere (playerlist, staff detection, team filter labels, etc.). Use esp_player_* listeners when you only want a different display on ESP (for example a nickname on ESP while the playerlist keeps the real RP name).
The first registered callback that returns a non-nil value wins for each override event.
override_player_rpname(entIndex: number): string
- Overrides the RP name of a player globally (playerlist, ESP baseline, staff checks, etc.).
- If a non-empty string is returned, that value is used as the player's RP name.
- Does not change the steam name shown when display steam name is enabled in the playerlist.
can still override the name shown on ESP only.esp_player_name
secret.listener.add("override_player_rpname", "real_name", function(index)
return "Maverick Trevillian"
end)
secret.listener.add("esp_player_name", "nickname", function(index)
return "67 kid" -- playerlist shows Maverick Trevillian; ESP shows 67 kid
end)
override_player_usergroup(entIndex: number): string
- Overrides the usergroup of a player globally (playerlist, ESP baseline, staff highlight, etc.).
- If a non-empty string is returned, that value is used as the player's usergroup.
can still override the usergroup shown on ESP only.esp_player_usergroup
secret.listener.add("override_player_usergroup", "real_usergroup", function(index)
return "admin"
end)
override_player_team(entIndex: number, teamIndex: number): table
- Overrides team information for a specific player globally (playerlist, ESP baseline, team filter labels, etc.).
- Return a table to apply the override. All fields are optional; omitted fields keep the current value.
andesp_player_team_name can still override team display on ESP only.esp_player_team_color
secret.listener.add("override_player_team", "real_team", function(ent_index, team_index)
return {
index = 1,
name = "Sigma Squad",
color = { r = 255, g = 175, b = 50 }
}
end)
esp_player_name(entIndex: number): string
- Overrides the name shown for a player on ESP only.
- Runs after
(if registered).override_player_rpname - If a non-empty string is returned, the ESP will display that value instead of the global RP name.
- Returning
nilor a non-string will cause the default name to be used.
secret.listener.add("esp_player_name", "custom_name", function(index)
return "67 kid" -- esp only; playerlist still uses override_player_rpname / game RP name
end)
esp_player_usergroup(entIndex: number): string
- Overrides the usergroup shown for a player on ESP only.
- Runs after
(if registered).override_player_usergroup - If a non-empty string is returned, the ESP will display that value instead of the global usergroup.
- Returning
nilor a non-string will cause the default usergroup to be used.
secret.listener.add("esp_player_usergroup", "custom_usergroup", function(index)
return "admin"
end)
esp_player_team_name(entIndex: number): string
- Overrides the team name shown for a player on ESP only.
- Runs after
(if registered).override_player_team - If a non-empty string is returned, the ESP will display that value instead of the global team name.
- Returning
nilor a non-string will cause the default team name to be used.
secret.listener.add("esp_player_team_name", "custom_team", function(index)
return "sigma squad"
end)
esp_player_team_color(entIndex: number): table
- Overrides the team color used for a player on ESP only (team text, team-based box color, etc.).
- Runs after
(if registered).override_player_team - Return a table with
r,g,b, and optionallya(0–255).
secret.listener.add("esp_player_team_color", "pink_team", function(index)
return { r = 255, g = 50, b = 200 }
end)
esp_player_name_color(entIndex: number): table
- Override the color used for a player’s name in ESP. Return a table
{ r, g, b, a }(0–255). Return nothing or a non-table to keep the default (priority/friend/dormant/config) color.
secret.listener.add("esp_player_name_color", "my_script", function(ent_index)
return { r = 255, g = 100, b = 100, a = 255 }
end)
esp_player_usergroup_color(entIndex: number): table
- Override the color used for a player’s usergroup text in ESP. Return a table
{ r, g, b, a }(0–255). Return nothing or a non-table to keep the default color.
secret.listener.add("esp_player_usergroup_color", "my_script", function(ent_index)
return { r = 200, g = 200, b = 255, a = 255 }
end)
draw_player_esp(ctx: table): draw_item | draw_item[]
- Used for drawing custom elements on player ESP.
- Context fields such as
name,usergroup, andteamreflect ESP display values (after global overrides and ESP-specific listeners).
Context (ctx) fields:
Draw item fields:
- Position values:
0/"top",1/"bottom",2/"right",3/"left". - Friend, priority, and dormant targets may override your
colorthe same way built-in ESP does.
secret.listener.add("draw_player_esp", "my_player_esp", function(ctx)
return {
text = "custom tag",
color = { 255, 80, 80, 255 },
position = "top"
}
end)
secret.listener.add("draw_player_esp", "multi_line", function(ctx)
if ctx.dormant then return end
return {
{ text = ctx.name, position = "top", color = { r = 255, g = 255, b = 255 } },
{ text = ctx.weapon, position = "bottom", side_font = true },
}
end)
draw_entity_esp(ctx: table): draw_item | draw_item[]
- Used for drawing custom elements on entity ESP
- Scripted entities only.
Context (ctx) fields:
secret.listener.add("draw_entity_esp", "ent_tags", function(ctx)
if not ctx.scripted then return end
return {
text = ctx.name,
color = { r = 200, g = 255, b = 200, a = 255 },
position = "right"
}
end)
Game loop
think()
- Called every frame.
secret.listener.add("think", "spam_console", function()
print("spammmm!")
end)
Rendering
paint_traverse()
- Mostly used for custom drawing.
- This is a 2D render context.
secret.listener.add("paint_traverse", "draw_box", function()
surface.SetDrawColor(255,255,255,255)
surface.DrawRect(25, 25, 100, 100)
end)
view_render_post()
- Occurs after ViewRender has been ran, usually used for screengrab proof esp.
- This is a 3D render context.
secret.listener.add("view_render_post", "draw_2d_box", function()
cam.Start2D()
surface.SetDrawColor(255,255,255,255)
surface.DrawRect(25, 25, 100, 100)
cam.End2D()
end)
Network
server_connect(ip: string, port: number, hostname: string)
- Called when connecting to a server.
server_disconnect(reason: string)
- Called when disconnected/kicked/banned from a server.
Input & usercmd
presend(CUserCmd: table)
- Called right before movement packets are sent.
- Provides full access to the native Garry's Mod
CUserCmdclass. - Provides additional functions not found in the default GMod class, allowing extended control over the usercmd.
secret.listener.add("presend", "viewangles", function(cmd)
cmd.angles = Angle(50, 50, 0) -- sets our viewangles
cmd.SetWorldClicker(cmd, Vector(20, 20, 20)) -- sets our context menu angle, not present in the garry's mod class.
end)
CUserCmd — properties available on the cmd table:
wndproc(vk_key: number): boolean
- Called whenever a Windows virtual key event is received.
- If
trueis returned, the input will be blocked from reaching the game.
secret.listener.add("wndproc", "block_space", function(vk)
if vk == 0x20 then -- space key
return true -- block input
end
end)