Представлюсь — меня зовут Сергей и все, что я делал до этого это бесконечные телеграм-боты на фрилансе. В один момент времени я решил, что надо попробовать себя в чем‑то новом. Темой создания игры я задавался давно (возможно когда первый раз сыграл в игру про трансформеров). В этой статье я хотел бы рассказать о своих ошибках при разработке игры.

Скачать свежайшее обновление игры можно в моем телеграмме
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. Команда
«Одиночество — яд заключен в этом слове» — В. Гюго
При создании игры, как показала моя практика, нужна команда. Любая.
Я создавал игру один, и это было не легко. «Тестировщик» в лице моего друга мне сильно помог своим знанием питона.
Однако создать шедевр одному можно, но крайне сложно. Нужно хотя-бы пару человек. Можно даже и не самых опытных. Лучше всего, по моему, когда вы с командой на одном уровне знаний, даже если он низкий.
Команда вам пригодится в придумывании механик, создании кода, текстур, сюжета и т.д.
Заключение
Я искренне надеюсь, что опыт, извлеченный из этой статьи вам поможет. Повторюсь, что у меня есть телеграм, в котором я выкладываю обновления игры. Если вам интересно - подписывайтесь.
Удачи вам!
