Cheat Engine (CE) – один из самых популярных инструментов для поиска и изменения значений в играх. Помимо привычного сканирования памяти‚ CE предоставляет обширный Lua API‚ который позволяет писать собственные трейнеры‚ автоматизировать рутинные задачи и даже создавать полностью автономные скрипты.
В этой статье мы подробно разберём‚ как начать писать Lua‑скрипты в Cheat Engine‚ какие основные функции использовать‚ как внедрять ассемблерный код через Auto Assembler‚ а также покажем типичные ошибки и способы их исправления.
Почему именно Lua?
- Лёгкость изучения. Синтаксис прост и похож на другие скриптовые языки.
- Гибкая интеграция. CE «встраивает» интерпретатор Lua прямо в процесс‚ предоставляя доступ к внутренним объектам (процессы‚ таблицы‚ окна).
- Мощный API. Функций более 300‚ покрывающих всё: от работы с памятью до создания пользовательских меню.
Для более подробного знакомства с самим языком Lua можно посетить официальный сайт lua.org.
Как открыть Lua‑консоль в Cheat Engine
- Запустите Cheat Engine.
- Откройте нужный процесс (игру) через кнопку «Select a process to open».
- В главном окне нажмите «Table» → «Show Cheat Table Lua Script» или просто Ctrl+Alt+L.
- Появится окно
Cheat Table Lua Script– здесь вы можете писать и выполнять код;
Для постоянного использования скриптов рекомендуется сохранять их в виде .CT (Cheat Table) файлов или экспортировать в отдельные .lua‑скрипты.
Минимальный «Hello World»
print("Hello‚ Cheat Engine!")
Выполняем скрипт – в нижней части окна появится строка Hello‚ Cheat Engine!. Если это работает – вы успешно подключились к Lua‑интерпретатору CE.
Основные категории функций Lua API в Cheat Engine
| Категория | Примеры функций |
|---|---|
| Работа с процессом | openProcess‚ closeProcess‚ isProcessOpen |
| Чтение/запись памяти | readInteger(address)‚ writeFloat(address‚ value)‚ readString(address‚ length) |
| Auto Assembler | autoAssemble(asmCode)‚ assemble(asmCode) |
| Таймеры и события | createTimer‚ registerHotkey‚ onClose |
| UI и меню | createForm‚ addMenuItem‚ showMessage |
Полный список функций доступен в Cheat Engine Lua API.
Пример: изменение количества патронов в шутере
Допустим‚ в игре «Super Shooter» количество патронов хранится по адресу 0x0049A1B0 (тип DWORD). Мы хотим создать скрипт‚ который будет автоматически ставить 999 патронов каждый раз‚ когда игрок нажимает F1.
Шаги
- Создаём таймер‚ который будет проверять состояние клавиши.
- Если клавиша нажата – записываем новое значение в память.
Код скрипта
-- Адрес‚ где хранится количество патронов
local ammoAddress = 0x0049A1B0
-- Функция‚ которая будет вызываться каждый тик таймера
local function setAmmo
if isKeyPressed(VK_F1) then -- VK_F1 – виртуальный код клавиши F1
writeInteger(ammoAddress‚ 999) -- записываем 999 патронов
print("[Lua] Ammo set to 999")
end
end
-- Создаём таймер‚ который будет вызываться каждые 100 мс
local t = createTimer
t.Interval = 100 -- миллисекунды
t.OnTimer = setAmmo
print("[Lua] Script loaded – press F1 to set ammo.")
Сохраните скрипт в .lua файл и загрузите через «Table → Lua Script → Load Lua Script». После этого‚ нажимая F1‚ вы будете видеть в консоли сообщение и в игре – 999 патронов.
Как исправить типичную ошибку «Auto Assembler code works‚ but Lua integration fails»
В интернете часто встречается проблема‚ когда ассемблерный код работает при ручном включении‚ но не запускается из Lua‑скрипта. Причина обычно кроется в двух вещах:
- Неправильный контекст. Функция
autoAssembleдолжна получать строку‚ а не таблицу. - Отсутствие
registerSymbolилиunregisterSymbol. Если в ассемблерном коде используются метки‚ их нужно объявлять в Lua.
Пример неправильного кода
local asm = [[
mov eax‚ [myVar]
ret
]]autoAssemble(asm) -- Ошибка: myVar не объявлен
Исправленный вариант
-- Объявляем переменную‚ которую будем использовать в ASM
registerSymbol("myVar"‚ 0x0049A1B0)
local asm = [[
mov eax‚ [myVar]
ret
]]
autoAssemble(asm)
-- По окончании работы (например‚ при закрытии скрипта) удаляем символ
unregisterSymbol("myVar")
Таким образом‚ каждый символ‚ используемый в Auto Assembler‚ должен быть зарегистрирован в Lua перед вызовом autoAssemble.
Полезные приёмы и советы
Получение пути к папке процесса
Иногда нужно знать‚ где находится исполняемый файл игры. Это удобно делать через io.popen:
local handle = io.popen('wmic process where processid='..getProcessID..' get ExecutablePath /value')
local result = handle:read("*a")
handle:close
local exePath = result:match("ExecutablePath=(.+)")
print("Executable path:"‚ exePath)
Обновление трейнера из удалённого сервера
Если ваш скрипт должен получать новые параметры (например‚ новые адреса)‚ можно загрузить их через HTTP:
local url = "http://example.com/trainer/config.txt"
local response = http.get(url) -- Требует включения модуля http в CE
if response then
for line in response:gmatch("[^
]+") do
-- Парсим строки вида: address=0x0049A1B0;value=999
local addr‚ val = line:match("address=(0x%x+);value=(%d+)")
if addr and val then
writeInteger(tonumber(addr)‚ tonumber(val))
end
end
print("[Lua] Config applied from remote server.")
else
print("[Lua] Failed to download config.")
end
Добавление собственного пункта в главное меню CE
local function menuCallback
showMessage("Привет! Это ваш кастомный пункт меню.")
end
addMenuItem("My Scripts\Show greeting"‚ menuCallback)
После выполнения скрипта в главном меню появится пункт My Scripts → Show greeting.
Работа с таймерами без утечек памяти
Важно удалять таймеры‚ когда они больше не нужны‚ иначе они продолжают работать в фоне.
local t = createTimer
t.Interval = 500
t.OnTimer = function print("Tick") end
-- Остановить и удалить таймер через 10 секунд
local stopTimer = createTimer
stopTimer.Interval = 10000
stopTimer.OnTimer = function
t.destroy -- удаляем основной таймер
stopTimer.destroy -- удаляем вспомогательный таймер
print("[Lua] Timers stopped")
end
Полный пример: простой тренер «Бесконечные жизни»
В этом примере мы объединим всё: чтение/запись памяти‚ Auto Assembler‚ таймер и пользовательский UI.
Шаги
- Найти адрес количества жизней (в примере –
0x0050F4D8). - Создать форму с кнопкой «Включить/Выключить».
- При включении – постоянно писать в память значение 9999;
- При выключении – остановить таймер.
Код
-- Адрес жизней (пример)
local lifeAddress = 0x0050F4D8
-- Флаг активности
local enabled = false
-- Таймер‚ который будет писать значение
local lifeTimer = createTimer
lifeTimer.Interval = 200 -- 5 раз в секунду
lifeTimer.OnTimer = function
if enabled then
writeInteger(lifeAddress‚ 9999)
end
end
-- Создаём простую форму
local frm = createForm
frm.Caption = "Бесконечные жизни"
frm.Width = 250
frm.Height = 120
local btn = createButton(frm)
btn.Caption = "Включить"
btn.Left = 50
btn.Top = 30
btn.Width = 150
btn.OnClick = function
enabled = not enabled
if enabled then
btn.Caption = "Выключить"
print("[Lua] Infinite lives ENABLED")
else
btn.Caption = "Включить"
print("[Lua] Infinite lives DISABLED")
end
end
frm.show
Сохраните скрипт‚ запустите‚ и у вас появится небольшое окно с кнопкой. При включении жизни будут постоянно обновляться до 9999.
Часто задаваемые вопросы (FAQ)
Почему скрипт не видит переменные‚ объявленные в Auto Assembler?
Необходимо использовать registerSymbol и unregisterSymbol (см. раздел 4.3).
Можно ли использовать внешние библиотеки Lua?
Встроенный интерпретатор CE поддерживает только стандартные библиотеки Lua. Для подключения сторонних модулей придётся собрать собственный lua.dll и загрузить его через package.loadlib‚ но это уже продвинутый уровень.
Как отладить скрипт?
Используйте функции print и debugger. В окне консоли CE выводятся все сообщения. Для более сложного отладчика можно подключить LuaDebug из внешних пакетов.
Lua‑скрипты в Cheat Engine открывают безграничные возможности: от простого изменения значений до создания полноценных трейнеров с графическим интерфейсом. Главное – помнить о правильной регистрации символов‚ управлении таймерами и тестировании кода в безопасной среде.
Теперь вы знаете‚ как:
- Открыть и использовать Lua‑консоль в CE.
- Читать и писать память через функции
readиwrite. - Встраивать ассемблерный код с помощью
autoAssemble. - Создавать таймеры‚ горячие клавиши и пользовательские окна.
- Отлавливать и исправлять типичные ошибки.
Экспериментируйте‚ комбинируйте функции и создавайте свои уникальные трейнеры! Удачной разработки.
Дата публикации: 08:15:00