gamesensical — read-only API
CS2 Dev · обновлено 14.10.2026. Слой совместимости следует контрактам gamesensical, адаптируя их к внешнему чтению CS2. Это поддержанное подмножество API; оригинальная документация не означает, что любая её функция доступна здесь. Существующие events, render, schema, config, thread и ui продолжают работать.
События и жизненный цикл
| Вызов | Поведение |
|---|---|
client.set_event_callback(name, fn) | Зарегистрировать функцию; повторная регистрация той же функции не дублирует вызовы |
client.unset_event_callback(name, fn) | Снять именно эту функцию |
client.delay_call(seconds, fn, ...) | Отложенный вызов с аргументами; 0–86400 секунд, без блокировки кадра |
Доступны paint, paint_ui, shutdown и собственное событие read_only_tick. paint и paint_ui вызываются каждый кадр оверлея, в том числе вне матча. read_only_tick — обновление оверлея, а не серверный тик или usercmd. shutdown вызывается при выгрузке/reload.
Неизвестное событие вызывает Lua-ошибку. setup_command, run_command, net_update_end, player_death и другие игровые события не имитируются. Ошибки callbacks попадают в менеджер; остальные функции события могут продолжить работу. Лимит — 64 callbacks на событие и действующий бюджет примерно 250 000 инструкций на вызов.
entity — чтение игроков
| Вызов | Результат |
|---|---|
entity.get_local_player() | Индекс локального игрока или nil |
entity.get_players(enemies_only?) | Таблица индексов живых игроков; true оставляет противников |
entity.is_alive(index) | Boolean |
entity.is_enemy(index) | Boolean относительно локального игрока |
entity.get_player_name(index) | Имя или nil |
entity.get_origin(index) | x, y, z или nil |
entity.get_player_weapon(index) | Индекс активного оружия или nil |
entity.get_steam64(index) | SteamID строкой без потери 64-битной точности или nil |
entity.get_classname(index) | Совместимый идентификатор CCSPlayer для игрока; ключ каталога CS2 для оружия |
entity.get_prop(index, property, array_index?) | Прочитанное значение; неизвестное свойство или отсутствующая сущность → nil |
entity.hitbox_position(index, hitbox) | x, y, z соответствующего сустава скелета или nil |
entity.get_bounding_box(index) | left, top, right, bottom, alpha; при отсутствии проекции alpha = 0 |
Снимки собираются на следующем overlay-кадре после запроса. Первый запрос может вернуть пустой список или nil. Индексы берутся из списка сущностей; оружие имеет собственный индекс, а не индекс владельца. Проверяйте данные после смены карты, смерти и отключения.
get_prop поддерживает m_iHealth, m_ArmorValue, m_fFlags, m_iTeamNum, m_bIsScoped, m_bHasHelmet, m_vecOrigin, m_vecAbsOrigin, m_vecVelocity, m_vecAbsVelocity, m_hActiveWeapon. Векторы возвращают три числа; индекс компонента начинается с 0. Для индекса оружия доступны m_iClip1 и m_iItemDefinitionIndex.
hitbox_position сопоставляет hitbox ID CS:GO с суставами CS2. Это приближение позиции, а не центр точной collision-капсулы. Bounding box тоже рассчитывается по скелету и origin.
client — камера, время и трассировки
| Вызов | Результат |
|---|---|
client.screen_size() | width, height в пикселях |
client.eye_position() | Текущий origin камеры x, y, z, иначе nil |
client.camera_angles() | pitch, yaw, иначе nil; аргументы запрещены, запись углов недоступна |
client.key_state(vk) | Удерживается ли Windows virtual key 1–255 |
client.latency() | Ping локального игрока в секундах, иначе nil |
client.timestamp() | Время оверлея в миллисекундах |
client.unix_time() | Unix-время в секундах |
client.system_time() | hours, minutes, seconds, milliseconds Windows |
client.random_int(min, max) | Случайное целое |
client.random_float(min, max) | Случайное число |
client.log(...), client.error_log(...) | Сообщение в лог скрипта; аргументы объединяются |
client.color_log(r, g, b, ...) | То же сообщение; RGB-форматирование консоли не воспроизводится |
client.visible(x, y, z) | Видимость по статическому BVH карты или nil |
client.trace_line(skip_index, x, y, z, x2, y2, z2) | fraction, index; fraction 0–1, index всегда -1 для статического мира |
Трассировки учитывают загруженную статическую геометрию карты. Игроки, подвижные двери, разрушаемые объекты и дым не трассируются; skip_index не меняет статический результат. Если BVH или камера недоступны, вернётся nil.
globals — игровые значения
globals.realtime() возвращает время оверлея в секундах. globals.curtime(), tickcount(), framecount(), frametime(), absoluteframetime() и maxplayers() читают игровые globals и могут вернуть nil вне матча или при неудачном чтении. globals.mapname() возвращает карту или nil.
globals.tickinterval и счётчики команд не предоставляются: значения не подменяются догадками. Для длительности overlay-кадра существует client.frame_time() из базового API.
renderer — рисование
Рисуйте из paint / paint_ui. Вне этих событий примитивы совместимого renderer пропускаются. Координаты — экранные пиксели, цвета RGBA 0–255.
| Вызов | Назначение |
|---|---|
renderer.world_to_screen(x, y, z) | screen_x, screen_y или nil |
renderer.line(x1, y1, x2, y2, r, g, b, a) | Линия |
renderer.rectangle(x, y, w, h, r, g, b, a) | Заполненный прямоугольник |
renderer.gradient(x, y, w, h, r1, g1, b1, a1, r2, g2, b2, a2, horizontal) | Градиент |
renderer.triangle(x1, y1, x2, y2, x3, y3, r, g, b, a) | Заполненный треугольник |
renderer.circle(x, y, r, g, b, a, radius, start_degrees, percentage) | Заполненный круг/сектор |
renderer.circle_outline(x, y, r, g, b, a, radius, start_degrees, percentage, thickness) | Контур круга/дуги |
renderer.text(x, y, r, g, b, a, flags, max_width, ...) | Текст с обводкой и ограничением ширины; 0 отключает ограничение |
renderer.measure_text(flags, ...) | width, height текста |
renderer.indicator(r, g, b, a, ...) | Индикатор слева; возвращает экранный y |
percentage — 0–1. Флаги текста: c — центр, r — справа, - — маленький, + — большой. Другие шрифтовые флаги, загрузка изображений/текстур, SVG и собственных шрифтов не реализованы.
ui — собственные элементы меню
Элементы появляются под скриптом во вкладке Lua. tab и container принимаются для совместимости исходника; они не встраивают элементы в меню CS2. Значения находятся в памяти скрипта и сбрасываются после reload.
| Вызов | Значение ui.get(ref) |
|---|---|
ui.new_checkbox(tab, container, name) | Boolean, по умолчанию false |
ui.new_slider(tab, container, name, min, max, initial?, tooltip?, unit?, scale?, tooltips?) | Целое в диапазоне min–max |
ui.new_color_picker(tab, container, name, r?, g?, b?, a?) | Четыре целых r, g, b, a |
ui.new_combobox(tab, container, name, ...) | Строка выбранного варианта; варианты также можно передать таблицей |
ui.new_multiselect(tab, container, name, ...) | Таблица выбранных строк |
ui.new_listbox(tab, container, name, items) | Индекс, начиная с 0; визуально отображается списком выбора |
ui.new_textbox(tab, container, name) | Строка |
ui.new_string(name, initial?) | Строка без видимого элемента |
ui.new_hotkey(tab, container, name, inline?, default_key?) | Удерживается ли выбранная клавиша |
ui.new_label(tab, container, name) | Текст метки |
ui.new_button(tab, container, name, callback) | Кнопка вызывает callback; ui.get для кнопки не используйте |
ui.set(ref, value, ...) меняет только эти контролы: checkbox — boolean, slider — число, combobox — строка, multiselect — строки или таблица, color picker — четыре числа RGBA. Неверная ссылка/тип/вариант вызывает Lua-ошибку. ui.set для кнопки вызывает её callback; для hotkey принимает virtual key 0–255.
ui.name(ref) возвращает имя, ui.set_visible(ref, bool) меняет видимость, ui.set_callback(ref, fn) задаёт callback изменения. ui.update(ref, ...) заменяет варианты combobox/listbox/multiselect и сбрасывает выбор. ui.is_menu_open() и ui.mouse_position() читают состояние оверлея.
Лимит — 128 контролов на скрипт. Hotkey пока работает только при удержании; строковые режимы hotkey, встроенные ui.reference, координаты меню, tooltip/scale-форматирование слайдеров и inline-раскладка не реализованы. Не меняйте контрол рекурсивно из его callback.
Пример: подписи игроков
local enabled = ui.new_checkbox("VISUALS", "Other ESP", "Read-only player labels")
local tint = ui.new_color_picker("VISUALS", "Other ESP", "Label RGBA", 120, 200, 255, 210)
ui.set(enabled, true)
client.set_event_callback("paint", function()
if not ui.get(enabled) then return end
local r, g, b, a = ui.get(tint)
for _, id in ipairs(entity.get_players(true)) do
local x, y, z = entity.get_origin(id)
if x then
local sx, sy = renderer.world_to_screen(x, y, z + 80)
if sx then
renderer.text(sx, sy, r, g, b, a, "c", 0, entity.get_player_name(id))
end
end
end
end)
Что отсутствует
entity.set_prop, FFI, запись памяти, client.exec, создание интерфейсов, vtable-вызовы, client.find_signature, изменение usercmd и запись camera angles не экспортируются. Неподдержанные функции не выдают фиктивный успешный результат. Lua io, os, debug, loadfile, dofile и загрузка нативных библиотек отключены. Сохраняйте явные проверки nil и переносите скрипты с учётом описанных отличий.