Представлюсь — меня зовут Сергей и все, что я делал до этого это бесконечные телеграм-боты на фрилансе. В один момент времени я решил, что надо попробовать себя в чем‑то новом. Темой создания игры я задавался давно (возможно когда первый раз сыграл в игру про трансформеров). В этой статье я хотел бы рассказать о своих ошибках при разработке игры.
Скачать свежайшее обновление игры можно в моем телеграмме
1. План
«Цель без плана — это просто мечта.» — Антуан де Сент‑Экзюпери
План — это то, что должно стоять в начале любого большого дела, именно им я и пренебрег. Связанно это было, наверное, с тем, что у меня было некое вдохновение, которое я не хотел терять на составление плана.
Все же не стоит думать, что я ни с того, ни с сего зашел в PyCharm и начал писать код. У меня было некое представление о том, что я буду делать:
Жанр — Текстовый Квест RPG
Язык — Python
Главная библиотека — PyQt (Об этом я хотел бы сказать позже)
Но как можно составить план и из чего он должен состоять?
Для планирования любых задач есть сервисы по типу Trello или в репозитории в Гитхабе создать проект.
Казалось бы, почему я не могу сделать что захочу и когда захочу? Ответ прост — рано или поздно вам надоест заниматься игрой (да и вообще любым делом). Подобное решение позволит сохранить всю мотивацию для создания игры.
2. Код
Перейдем к технической части.
Во-первых, как уже говорилось ранее, я использовал PyQt для создания «графики» в игре.
Знающие люди могут сказать, что PyQt не предназначен для создания игр и я с ними соглашусь. Когда я выбирал между PyGame и PyQt я выбрал для себя наиболее легкий вариант, о котором впоследствии пожалел.
Во-вторых, для себя я заметил, что все будущие механики игры нужно писать сразу или оставлять некоторые «намеки» на их наличие - сейчас объясню.
Допустим вы хотите добавить читы к уже работающей игре. Чит, допустим, должен сразу убивать врагов.
def battle_func(self, name, lvl):
self.IS_BATTLE = True
self.enemy = Mob(name, lvl)
self.add_text(f'На вас напал {self.enemy.name} {self.enemy.lvl} уровня.\n
Битва началась!\n')
Вы видите простейшую реализацию начала боя. Создается враг и включается режим боя.
new_dmg = random.randint(self.player.min_dmg, self.player.max_dmg)
crit_dmg = self.player.crit_damage()
self.enemy.hp -= new_dmg + crit_dmg
self.add_text(f'Вы ударили {self.enemy.name} на {new_dmg} + {crit_dmg}.')
Это фрагмент кода, отвечающий за нанесение урона, и в нем не предусмотрено то, что вы включили читы. Чтобы этот код работал, его нужно переделать в этот:
if self.IS_CHEAT:
self.enemy.hp = 0
self.add_text(f'Вы победили!')
else:
new_dmg = random.randint(self.player.min_dmg, self.player.max_dmg)
crit_dmg = self.player.crit_damage()
self.enemy.hp -= new_dmg + crit_dmg
self.add_text(f'Вы ударили {self.enemy.name} на {new_dmg} + {crit_dmg}.')
Мы только что добавили возможность убивать врагов с одного касания, но, как только игра запускается и мы бежим дубасить всех чертей, оказывается, что после первой убитой нечисти наша супер-сила пропадает:
if self.enemy.hp <= 0:
self.player.exp += self.enemy.exp
while self.player.exp >= lvls[self.player.lvl + 1]:
self.player.exp -= lvls[self.player.lvl + 1]
self.player.upgrade()
self.add_text(f'Теперь ты Герой {self.player.lvl} уровня!\n')
Это произошло из-за того, что при убийстве врага, как ни странно,мы получаем опыт, который конвертируется в новый уровень:
def upgrade(self):
self.lvl += 1
self.base_dmg += 3
self.min_dmg = self.base_dmg
self.max_dmg = self.base_dmg + 5
Для того чтобы исправить это, мы делаем нечто подобное:
if self.enemy.hp <= 0:
self.player.exp += self.enemy.exp
while self.player.exp >= lvls[self.player.lvl + 1]:
self.player.exp -= lvls[self.player.lvl + 1]
self.player.upgrade()
self.add_text(f'Теперь ты Герой {self.player.lvl} уровня!\n')
if self.IS_CHEAT:
self.player.hp_max = 1000
self.player.max_dmg, self.player.min_dmg, self.player.dmg = \
2000, 1000, f'1000-2000'
Таких примеров было немало,но рассказывать о них нету смысла, ведь это были подобные ошибки. В сумме, из-за того что я поленился написать механику читерства сразу, я, помимо 7 добавленных строчек, потратил время. Пример был достаточно упрощенный, но вполне наглядный.
3. Баланс
С этим у меня проблемы до сих пор. Возможно, это проблема данного жанра, что все завязано на рандоме. Тут советов я дать не могу. Хочу сказать лишь то, что если хочешь примерно уравнять шансы делай все по алгоритму:
Запускай игру
Атакуй врага
Победил? сделай урон игрока ниже и/или увеличь HP врагу.
Проиграл? сделай урон игрока выше и/или уменьши HP врагу.
Повторять до 50% побед
Теперь мне даже жалко разработчиков онлайн игр, которые постоянно слышат об отсутствие баланса в игре(
4. Время
Как я уже говорил ранее, надо составлять план, иначе бросишь делать игру. Я пытаюсь перестроить себя с графика 1/7. Просто совесть мучает, что твое творение лежит неоконченным. Советую выделять пару часов на написание чего‑либо. Буквально 2–3 часа перед сном, но зато ежедневно. Так работа будет делаться эффективнее. Больше мне нечего сказать — цените время.
5. Команда
«Одиночество — яд заключен в этом слове» — В. Гюго
При создании игры, как показала моя практика, нужна команда. Любая.
Я создавал игру один, и это было не легко. «Тестировщик» в лице моего друга мне сильно помог своим знанием питона.
Однако создать шедевр одному можно, но крайне сложно. Нужно хотя-бы пару человек. Можно даже и не самых опытных. Лучше всего, по моему, когда вы с командой на одном уровне знаний, даже если он низкий.
Команда вам пригодится в придумывании механик, создании кода, текстур, сюжета и т.д.
Заключение
Я искренне надеюсь, что опыт, извлеченный из этой статьи вам поможет. Повторюсь, что у меня есть телеграм, в котором я выкладываю обновления игры. Если вам интересно - подписывайтесь.
Удачи вам!
Комментарии (15)
Areek
30.07.2023 08:40Пункт 2 на самом деле тоже "План", но в более глобальном понятии. Для игр это называется "дизайн-документ". В нём, в частности, описываются все механики игры, в том числе и читы. ЗАРАНЕЕ. Если такового нет, происходит всякое, например:
Игра про магов, бьющих монстру и растущих в опыте. Уже есть маги, монстры, заклинания, всё уже работает.
Приходит "гениальная идея" и одним из левелапов магу будет даваться призыв монстра на свою сторону из небытия.
Ой, нет, не даётся. Потому что есть команда "маги" и команда "монстры". В коде это разные типы, у них разный набор характеристик, разная обработка событий и действий. Монстр не умеет целиться в монстра, он атакует только магов. Магу можно выдать картинку и хиты монстра, но атаками монстра объект "маг" пользоваться просто не умеет, у него есть заклинания, а если они кончились - оружие. А после боя обработка гибели мага и монстра тоже различается, нельзя дать магу оружие с названием атаки монстра и сказать, "бей, всё ок".
Почему так? Потому что так было задумано изначально. Не просто стороны боя А и Б, а "маги" и "монстры".
Ружьё висело на сцене в самом начале, и вот оно стреляет в ногу владельца.PrinceKorwin
30.07.2023 08:40+1Вспомнилась история как одна компания получила заказ от правительства Австралии сделать симулятор вертолета для тренировки пилотов.
Особенностью проекта было то, что нужно добавить кенгуру. Исходно симулятор в кунгеру не умел поэтому для упрощения взяли элемент "пехотинец" и поменяли модельку на кенгуру.
При сдаче проекта заказчику один из пилотов сделал маневр над стаей кенгуру и какое же было удивление заказчика когда кенгуру сначала бросились в рассыпную, потом перегруппировались и дали отпор с огневой поддержкой :)
Areek
30.07.2023 08:40Уверен, бета-тестеры могли бы рассказать десятки таких историй.
Конкретно я наткнулся на гениальность ИИ, который, как матёрый катала, воровал и разыгрывал карты из руки оппонента, и только потом свои - розыгрыш карты шёл без проверки валидности владения (игрок-то мышью карту утащить не может), а скрипт выдавал приоритеты "лишить оппонента карт" и "сохранить свои карты". Ну и вот, играть чужую карту - выгодно.
Странно, что из колоды не таскал)))
exTvr
30.07.2023 08:40для упрощения взяли элемент "пехотинец" и поменяли модельку на кенгуру.
Леша, прицепи к самолетам по две белые полоски.
Осторожно, вызывает гомерический хохот, несмотря на то что десять лет уже этой байке.
VandCi
30.07.2023 08:40На самом деле не только у тебя такие проблемы, я тоже таким страдаю
Надеюсь таких постов будет больше)
Мы обязательно допишим свои игры!
neki-dev
30.07.2023 08:40Начиная делать свою игру даже и не подозревал что самым сложным для меня окажется именно баланс
Malizia
30.07.2023 08:40По балансу чуть ли не единственная книга Game Balance by Brenda Romero and Ian Schreiber. Из софта есть https://machinations.io - позволяет создавать блок схемы и запускать - это быстрее чем создавать прототипы.
Quinekanc Автор
30.07.2023 08:40Скажи, а где эту книгу можно найти (желательно бесплатно) с русским переводом. Я просто боюсь что на английском ничо не пойму.
Vandomas
30.07.2023 08:40Я тоже занимаюсь разработкой игры как и ты, и знаешь что, я страдаю такой же проблемой как и ты... Точно такой же...
Очень надеюсь что у тебя получится продолжить делать игру!
Хотелось бы больше видеть таких статей, в каком-то смысле они придают мотивации
temabed
30.07.2023 08:40Я, как говорится, нулёвый чел. Но мне кажется, если ты создаешь проект с намеком на его рост, то лучше сразу делать в стиле ООП, проектируя классы. Для игры в жанре РПГ это даже логично. Хотя весь код я не видел, да и на экспертность не претендую. За статью спасибо, было интересно.
AcckiyGerman
Попробуй прокачать скилы (и программирование и общение на английском) на codingame.com
Там будешь создавать не игры конечно, но ботов для соревнований с другими участниками в рамках игр с разными правилами - а это пригодится потом для создания интересных противников уже в своей собственной игре.
Ну и gamedev.ru для поиска русскоязычных партнёров по разработке.
Quinekanc Автор
Спасибо за совет. Очень приятно!
temabed
О, я тоже благодарю за подсказку сервиса.