Я уверен, что многие из вас, кто сейчас занимается олимпиадным программированием, попутно занимаются или пытаются заниматься разработкой игр. Я могу с ходу вспомнить упоминания как минимум двух человек об этом хобби, один из которых красный и медалист (если не дважды) ICPC.
Я давно хотел тут написать об одной игре - мы занимались ей с другом, запустили, и она существовала на протяжении двух лет. До этого я так и не написал о ней, потому что не хотел чтобы это сочли как её рекламу, но теперь, когда мы полностью прекратили её поддержку, я думаю я абсолютно чист в желании рассказать о ней.
Я сначала расскажу немного предыстории, затем как мы его разрабатывали, со всеми препятствиями, как мы его запустили, как он развивался, и почему мы его закрыли.
Игра - обычная браузерная ММОРПГ. Посмотреть на нее можно здесь: alideria.ru.
Сначала предыстория. Я раньше играл в игру, назовем ее ИКНН (игра-которую-нельзя-называть), которая собственно послужила прототипом Алидерии. Игра тогда была очень сырая, и я, за компенсацию игровыми ценностями, помогал администраторам переписывать какие-то фрагменты с чистого PHP на PHP+JavaScript, чтобы перенести часть каких-то вещей на клиент, и добавить асинхронности. Я сам тогда был не очень крут как в PHP, так и в JavaScript, и эта работа на самом деле принесла невероятное количество опыта.
В какой-то момент времени оказалось, что я приложил руку почти к каждому аспекту игры на тот момент, и это дало мне понять, что, вероятно, я смогу написать такую игру и сам. Я начал ее писать, и благополучно забил, написав какие-то основы типа регистрации, брождения, боя, инвентаря и магазинов. Это даже было немного играбельно.
Спустя некоторое время мне постучал другой человек, Дима, который тоже помогал разработчикам ИКНН. Только он занимался ей со стороны рисования картинок. Он предложил мне написать вместе игру, а также познакомил с еще одним человеком, тоже Димой, который тоже помогал разработчикам ИКНН, но он, в свою очередь, писал квесты. Я до сих пор его считаю самым талантливым человеком в этой области из всех кого я знаю :о)
Я сразу отрыл исходники игры, которой я занимался, и это послужило как отправная точка. Дима, который рисовал, успел только сделать дизайн (который до сих пор стоит в игре), и ушел из проекта, оставив нас в двоем с Димой, который делает квесты. Он, в свою очередь, согласился проинвестировать часть своих денег в игру (я тогда жил на стипендию и такой возможости не имел), оплатив виртуальный хостинг, и начав заказывать картинки вещей на сайте free-lance.ru. Работа у нас шла очень медленно, в основном потому что я готовился к соревнованиям. Через полтора года у нас был уже рабочий прототип, но все еще не готовый к запуску. В это время у меня начался год, который был посвящен ICPC целиком, а за ним стажировка в Microsoft. Таким образом игра оттянулась еще примерно на год. После стажировки за пять месяцев мы дописали все, что недоставало для запуска, вставили заглушки вместо картинок, которых не хватало, и 16-ого февраля 2009 года мы ее открыли. В качестве первой попытки привлечь аудиторию мы просто кинули ссылку в ИКНН, в игру вошло 20 человек, и виртуальный хостинг накрылся попой. Заказ выделенного сервера пришелся аккурат на праздники в честь 23-его февраля, и поэтому на протяжении первых 10 дней жизни игры она существовала между полностью убитым состоянием, и едва живым :о)
Затем выделенный сервер у нас появился.
Первые проблемы, которые встали после этого:
1. Многие участки кода были очень сырыми. В первые дни работа шла в режиме 10 часов в день, с непрерывным исправлением ошибок, о которых писали в чат. Там же произошла первая отправка запроса вида delete from player_items с забытым where... На протяжении жизни проекта запросов в забытым where, и многочасовых разгребаний их последствий, будет штук 40 :о)
2. Чат, написанный на PHP, нагружает сервер очень сильно. Я не верю вообще в возможность написать на PHP чат, который будет делать адекватную нагрузку. Поэтому сразу пришлось писать новый чат на C++. Это было достаточно сложно, учитывая, что в работе с сетью и потоками под линукс на С++ я был полнейшим нубом. Потом-таки пришлось переписать на Java.
Затем время текло, игроки требовали вещей, которые мы не успели сделать до старта игры. Например - кланов. ММОРПГ без кланов - это не ММОРПГ :о) Систему кланов мы сделали очень крутую, с огромной системой прав доступа, удобным управлением клановыми вещами, и необходимостью всем кланом строить постройки, чтобы получать бонусы. Запускали все это добро в апреле, прямо в мой день рождения. Нет ничего приятнее, чем подарить себе на день рождения релиз клевой штуки. И полный день у компьютера с наблюдением, что все работает. Конечно, в первую секунду упало все, что могло упасть...
Как мы ее раскручивали. Я к моменту запуска уже работал в ИКНН почти официально, и получал кучу бабла - 1000 долларов в месяц за достаточно не большое количество часов. Поэтому деньги на рекламу были. Мы покупали рекламу в Яндексе, Гугле и на ВКонтакте. В тот момент при равных вложениях третья обходила первые две на голову. Потому что тогда контекстная реклама на ВКонтакте вроде как только появилась, и тысяч крутых игр, которые бы ей пользовались, там не было. Сегодня на наш тогдашний бюджет с ВКонтакте наверное даже одного посетителя не получить :о)
Такая реклама позволила медленными темпами развить игру до 200 человек онлайн. И эта цифра никогда не была побита по большому счету. Потому что реклама становилась дороже, а наш бюджет больше не становился. В какой-то момент мы рекламу попросту отключили.
Следующая проблема, которую мы наблюдали - кликов много, но после этого средний игрок уходил через пять минут. Зарегистрировав персонажа в игре и поставив себя на место новичка мы поняли, что в Алидерии вообще невозможно разобраться. В качестве заглушки мы сделали несколько обучающих сообщений, падающих в чат при первом заходе, но это почти не помогло. Тогда мы начали работать над сложными первыми шагами, которые можно наблюдать в игре сегодня.
Если бы эти первые шаги были запланированы сразу, то, скорее всего, их реализация имела бы нулевую стоимость. Но, так как весь код игры уже был написан, и он не был рассчитан на первые шаги, приходилось вставлять ужасные костыли везде, и это заняло тонну времени и усилий.
После запуска первых шагов 30% игроков, регистрирующихся в игре, доходили до второго уровня.
В какой-то момент времени мы стали думать о введении платных сервисов. Проект с самого начала разрабатывался как что-то, что со временем должно приносить прибыль. Легче всего было подключить мерчант веб-мани. У Димы был персональный аттестат, и имея его подключить мерчант - это пять кликов на сайте. Но вы можете догадываться, что WebMoney есть у очень малого процента посетителей игры. По этому, помимо мерчанта сразу же начали сотрудничество с компанией, управляющей коротким номером для СМС-сообщений. Запуск СМС-ок и WebMoney для покупки внутренней валюты, и нескольких премиум-сервисов за эту внутреннюю валюту (вида "в течение месяца вы будете получать x1.5 боевого опыта" за 300 рублей) начал приносить какую-то небольшую прибыль. К этому мы добавили позже 2pay, основная крутость которого - это терминалы (ну и яндекс.деньги), и этих трех способов нам хватало по сей день. За все время жалобы от игроков о невозможности пополнить баланс мы слышали лишь несколько раз, всегда от игроков из ближнего зарубежья, и чаще всего выяснялось, что у нашего СМС-оператора есть короткий номер в этой стране, который мы просто добавляли.
В будущем из платных сервисов мы добавили только возможность поменять аватар на форуме, и возможность докупить дополнительные смайлики в игре. Будучи "хорошими админами" мы так и не ввели платные вещи и платные заклинания, сохранив в игре баланс донаторов и не донаторов. Теперь вот я лично жалею о недополученной прибыли :о)
Чтобы вы понимали, чего ждать от такого подхода: при 200 игроках онлайн в середине дня, платных сервисах, ограничивающихся премиум-аккаунтами по 150-300 рублей (в среднем игрок, вкладывающий деньги, активировал три разных премиум-аккаунта на месяц), игра приносит порядка 30 тысяч рублей в месяц (до вычета расходов на сервер, новые картинки, рекламу итд).
Для сравнения, в ИКНН, где онлайн 800 человек, и где можно покупать уникальные вещи за реальные деньги, есть по меньшей мере пять человек, чей комплект вещей стоит более 15ти тысяч долларов. Это мне подсказывает, что их прибыль значительно больее чем в четыре раза превышает нашу.
Другие проблемы, с которыми мы сталкивались:
1. Всегда есть бараны, которые взламывают игру. Иногда приходится тратить очень много времени, чтобы разгрести последствия действий этих баранов.
2. Если администрация ведет себя открыто с игроками (не прячется за абстрактным ником Администратор), общается с ними, то игроки ведут себя значительно требовательней, и относятся к администрации как к обязанной немедленно выполнять их требования. Это заметно раздражает :о
3. Игроки ждут апдейтов очень часто. Выпускать их часто очень сложно. В итоге, опять же, недовольства игроков.
4. Вообще, игроки недовольны всегда. Бывали случаи, когда игрок просил какое-то изменение, а когда оно вводилось, в первых рядах кричал, что это изменение погубит игру.
5. Очень сложно сбалансировать игру. В нашем случае никого баланса между стихиями так и не было достигнуто.
6. Фрилансеры имеют свойство пропадать. Очень неприятно, когда очередной комплект вещей ждешь два месяца...
7. Сделать качественную модерацию в игре очень сложно. Все люди в какой-то мере неадекватны, и если их сделать модераторами, это быстро проявляется.
Еще очень важно потратить время на создание админки. Для сравнения - в ИКНН все квесты целиком пишутся кодом. У нас все разговоры, фразы, переходы, требования, пункты в дневнике, и базовые действия вроде "добавить игроку вещей" или "установить игроку триггер 121" делались через интерфейс админки. По большому счету к коду прибегали только когда в квесте надо было либо сделать нестандартную логику (НПЦ появляется только с 2 до 6 дня допустим), либо когда надо было вставить в квест миниигру.
При этом я делал в ИКНН квест, на который я потратил почти неделю чистого времени, и который в Алидерии я бы почти целиком просто вбил в админке.
Аналогично, по ходу управления игрой постойнно приходится добавлять или забирать у игроков вещи, деньги, заклинания, выкидывать их из клана (глава пропал допустим), расформировывать кланы, выкидывать игроков из зависших боев, перекидывать игроков из локации в локацию. Хорошее правило, которому я следовал - если какое-то действие пришлось сделать трижды, надо его добавить в админку.
Игра наша просуществовала на протяжении двух лет. Кода за это время было написано тонна, картинок куплено еще больше. Мы выбрали вариант развития в ширину, а не в глубину, вводя новые квесты, локации, возможности. Тем самым постоянно портя еще сильнее и без того отсутствующий баланс.
Закончилось все тем, что у меня просто перестало хватать времени, и, так как онлайн давно не рос, и перспектив не было, я ушел из проекта. Дима пригласил в проект своего знакомого программиста из еще одного проекта, над которым он работал. Новый программист начал переделывать почти все с нуля, пока в какой-то момент времени не пропал. Алидерия осталась без программиста, и Дима заявил о прекращении поддержки проекта.
Я упоминал выше про взломы игры. Конечно, любой взлом игры происходит из-за ошибки программиста. Из самых тупых взломов я помню следующий:
Когда игрок авторизуется в игре, мы ему присваиваем номер сессии, который в сущности просто является случайным числом, возвращенным функцией mt_rand(). Очевидно, код авторизации был написан одним из первых, то есть за три года до открытия игры, даже раньше, и в нем как-то получилась в то время очень странная конструкция
mt_srand(time());
session_id = mt_rand();
Теперь, мы видим, что перед генерацией сессии инициализируется seed, и инициализируется он на основе текущего времени с точностью до секунды. Добавим к этому, что в Алидерии в информации любого игрока можно увидеть как он давно онлайн с точностью до минуты, а в углу главного экрана игры есть часы с текущим временем на сервере. Хакеру было достаточно перебрать всего 120 значений зерна, чтобы подобрать id сессии нужного ему игрока. В роли нужного ему игрока выступил я, с доступом к админке :о)
Важный урок, который я после этого вынес - не надо размещать ссылку на админку прямо в игре :о Так бы может, взломав меня, он бы хотя бы не нашел как до неё добраться. В админке после этого он сделал только одно действие - поставил админские права своему персонажу. И всплыло это только через две недели.
На последок скажу несколько советов из полученного опыта тем, кто сейчас думает в эту сторону.
1. Когда вы начинаете проект, есть большой шанс, что через месяц он вам будет не интересен, и вы будете хотеть написать уже совсем другой проект, а код текущего будете считать грязным и ужасным (хотя навреное у крутанов нет такой проблемы). Разумно, однако, продолжать работать над текущим проектом.
2. Имеет смысл перед началом работы над сложным проектом написать сначала что-то простое на той технологии, которую вы планируете использовать (например, напишите Марблс). Это откроет вам глаза на многие проблемы, о которых вы не догадываетесь.
3. Игроки не любят сложную игру. Если вы сделаете Magic The Gathering Online, и игру, в которой есть только кнопка "Получить +10 опыта", вторая будет популярнее, и принесет больше прибыли. Ботва - хорошее тому доказательство :о)
4. И, конечно, запуск игры стоит денег. Как минимум на содержание сервера и покупку рекламы. Это с предположением, что у вас есть команда, покрывающая все необходимое в игре. Иначе надо еще рассчитывать бюджет на покупку недостающего контента. Прежде чем тратить значительные усилия на разработку, убедитесь, что ваше финансовое положение позволит потом проект запустить.
Первый год где-то - однозначно.
Потом уже энтузиазм спал.
Здорово, спасибо!
Как раз сейчас гуляют мысли чем-то игровым заняться =)
При том сугубо добровольно, вычислить такое в админке было нельзя, поелику она не обладала оповещением про изменение прав игроков, верно? :3
Потому что когда админку пишешь, ты же думаешь, что ей тока ты пользуешься :о)
Там и проверок на инъекции нет, допустим.
undefined - это и есть тот баран, который это сделал :о) После этого мы с ним пообщались, и он еще помогал мне исправлять какие-то другие дыры, и писал какие-то участки кода..
Защита очевидно включить Magic Quotes в апаче, и всегда проверять входные данные. Особенно не забывать приводить тип целочисленных данных. Грубо говоря, почти любая PHP-шка, принимающая параметры, должна начинаться с чего-то вроде
p = (int)_GET['p'];
Нет, это где надо шарики перегонять по полю, чтобы они выстраивались в ряды.
Это просто пример, можно написать и то, что ты сказал. Главное сделать что-то простое. Грубо говоря, приходя в тренажорку, ты не хватаешься сразу за огромные веса, ты сначала поднимаешь какой-то простой вес для разминки. Тут надо также.