Devlog
July 3, 2023

Как я сделал бота для фарма в GTA RP

Всем привет. В этом посте я хотел бы рассказать вам о своем опыте создания ИИ-бота для фарма $$ в гта РП.

Мысль о создании какого-нибудь бота/ИИ для фарма денег у меня появилась больше полугода назад, но тогда я думал что это слишком сложно и даже не пытался взяться за это. Как оказалось, все это не так уж и страшно как я себе это представлял.

Основные трудности, с которыми я столкнулся:

Первый шаг под названием Что делать то или (Постановка цели)

Так как на тот момент у меня не было НИКАКИХ знаний о ботоводстве, Я решил прикинуть, какая работа была бы САМОЙ ПРОСТОЙ в исполнении? Мой выбор пал на рыбалку, и вот почему:

Рыбалка (скриншот с ютуба)

Всю суть рыбалки можно изложить в нескольких шагах

  1. Закидываешь удочку
  2. Ждешь пока рыба клюнет
  3. Тянешь рыбу в противоположную сторону
  4. Вытягиваешь

Выглядит довольно просто, поэтому я решился делать первого бота именно для рыбалки (В будущем планирую написать ботов и для более сложных работ).


И так, первым делом я решил начать с создания модели с использованием Computer Vision для того, чтобы определить, где на экране находится рыба.

Просмотрев серию гайдов от sentdex и пару видео на ютубе по поводу Object Detection, я приступил к действию.

После небольшого ресерча, я решил делать бота используя модель YOLO. Наслушавшись, что ФПС увеличивается при конвертации цветов изображения в СЕРЫЙ цвет.

(ну типо RGB это трехмерный массив и занимает ГОРАЗДО больше места и вычислительной мощности, чем просто Gray).

Написал небольшой скрипт для снятия снимков экрана каждую секунду и сохранения их в специальной папке на компьютере. Сделав около 150 скринов Я перешел к созданию training dataset.

Для разметки использовал классический labelImg, хотя позднее выяснилось что roboflow может быть даже удобнее.

Разметил порядка 150 серых картинок, начал тренировать модель YOLOv7, смотрю на графики, а там confidence просто нулевая. Загружаю свое видео для проверки, убираю ограничение по уверенности и вижу, что модель ОПРЕДЕЛЯЕТ рыбу, но уверена в этом всего лишь на несколько процентов.

йоло)

Начал искать решение проблемы, как оказалось модели YOLO созданы для тренировки на цветных изображениях, я же тренировал модель на серых картинках, посему и получил такой скудный результат.

Окей, пришлось заново собирать кучу картинок, заново тренировать модель и так далее. Спустя несколько часов Я имею на руках модель с довольно высокой точностью определения (60%+). Ну, думаю, пора внедрять ее в бота и писать основной функционал (как бы не так))) )

ОКАЗЫВАЕТСЯ YOLOv7 почти что НЕРЕАЛЬНО внедрить в обычный питоновский код (по крайне мере я так и не понял как), в следствии чего не пришлось делать НОВУЮ модель (опять), но уже на восьмой версии ЙОЛО, там даже тренинг можно делать из кода, что довольно удобно.

Ладно, я сделал еще 100500 картинок рыбы, разобрался во всем опять с нуля и имел на руках уже реально рабочую модель которую я мог использовать в коде (Ура)


Считывание экрана

В качестве image-taker'a я использовал библиотеку mss, которая отличается довольно высокой производительность, в отличии от pyautogui. С использованием MSS я смог добиться производительности в размере 20-25 кадров в секунду, что является довольно большим показателем. (Это считай столько скриншотов делается в секунду и обрабатывается моделью)

А как находить рыбу на экране то? Не знаю, я спросил это у чат-гпт и спустя несколько часов я смог успешно транслировать игру и определять есть ли на экране рыба.

как я это вижу:

Переходим к третьему шагу, "изнурение" рыбы

Для того, чтобы тянуть рыбу в нужную сторону, нам нужно определить вектор ее направления (т.е в какую сторону плывет рыба). Для этого я использовал встроенную функцию .xyxy для получения координаты Х (вертикальной оси). Так как наша модель видит игру в формате огромного количества переменных кадров (в принципе как и мы, лол) Я просто решил сравнивать координату Х текущего кадра с предыдущем кадром. Таким образом, если Х меньше => рыба движется влево => тянем вправо. Х стал больше => рыба движется вправо => тянем влево. Спустя еще несколько часов я смог внедрить этот функционал.

Дело осталось за малым

Завершающий этап

Осталось понять, "когда же вытягивать рыбу?" Изначально в моих планах было сделать template-matching, но вскоре я понял, что этот вариант мне не подходит, поэтому решил сделать так:

"ЕСЛИ Я ВИДЕЛ РЫБУ И ОНА ПРОПАЛА ИЗ МОЕГО ПОЛЯ ЗРЕНИЯ БОЛЕЕ ЧЕМ НА 1 СЕКУНДУ, ЗНАЧИТ Я ЕЕ ВЫЛОВИЛ"

Данный принцип оказался гораздо проще в исполнении.

На данном этапе мне оставалось только прикрутить возможность закидывать удочку и вытягивать рыбу зажимая ЛКМ, в прочем, это дело нескольких строк кода.

Таким образом Я написал своего первого бота частично используя искуственный интеллект. Кстати, оказалось что кто-то на ютубе уже сделал бота для рыбалки, но там используется другой прицнип, но, в прочем, это не важно.

Следующим делом хочу сделать ботов и для других работ, потому что таких ВРОДЕ нет, но самое главное что это было весело :)