Игровой сервер как учебная дисциплина

Увлекательные приключения программиста команды сервера Skyforge Виталия Чибрикова в «Технопарке» МГТУ им. Баумана.

Бойцы невидимого фронта

Меня зовут Виталий Чибриков, и я работаю в команде сервера проекта Skyforge. Другими словами, я и мои коллеги по цеху — бойцы невидимого фронта. Результат наших трудов не заметен игрокам. Они обсуждают графику, геймплей, интерфейс — все, что угодно, только не сервер. Никто и не думает, благодаря чему в верном порядке подгружаются новые локации, а персонаж моментально реагирует на команды. Абсолютно все в MMORPG проходит через сервер, и серверная часть — важная и неотъемлемая часть игры. В проектах уровня Skyforge требования особенно высоки, ведь мы должны поддержать комфортное существование более миллиона игроков на одном супер-большом сервере. Задача нашей команды — продумать и обеспечить стабильную работу этого сложнейшего механизма.
Выполнить такую разностороннюю задачу может только программист крайне-широкого профиля. Задачи нужно решать самый разнообразные: от разработки архитектуры игрового сервера (как на «софтверном», так и «хардверном» уровнях) до создания инструментария для обновления игры и введения нового функционала. Поэтому специалисты для такой работы нужны с самым широким кругозором, а таких сильных программистов, к сожалению, на рынке труда совсем немного. Мы прилагаем максимум усилий для развития специалистов внутри команды Allods Team, а также постоянно ищем перспективных ребят. Отличной почвой для роста специалистов стал «Технопарк» МГТУ им. Баумана. В середине прошлого лета в рамках совместного проекта Mail.ru Group с МГТУ им. Н.Э Баумана я выступил в новой для себя роли — в качестве преподавателя курса углубленного изучения Java. Зачем мне это? Хотел поделиться опытом, а может и найти таланты среди молодых ребят, чтобы вырастить из них хороших серверных программистов. В общем, читайте как все было…

История создания курса

Придумать и прочитать курс по теме своей основной работы — это возможность одновременно получить опыт преподавания, лучше узнать язык программирования, по-новому взглянуть на себя и свою работу.
Подробно о самом Технопарке я писать не буду — об этом уже есть отличная статья его основателя Дмитрия Волошина.
Полное название дисциплины курса, который мне предстояло прочесть, было: «Углубленное программирование на Java». Это полугодовой курс для студентов, которые успешно прошли первый семестр обучения в Технопарке. На момент начала курса у студентов уже должны были быть основные знания программирования и небольшой опыт разработки на каком-либо языке высокого уровня.
Интересное:
Первый семестр Технопарка включает курс «Алгоритмы и структуры данных». Наши разработчики обязаны хорошо знать математические основы профессии.
Мне предстояло подготовить материал для 9 лекций и 6 семинаров (по четыре академических часа на каждое занятие). Курс должен был стать частью общей программы по подготовке web-разработчиков и системных архитекторов. Я был свободен в выборе тем и материалов, мог подготовить любой курс, соответствующий названию. Единственное обязательное условие — практическая направленность курса. То есть, студенты должны были не просто прослушать теоретический материал, но и сделать ряд практических работ. Например, решить задачи, похожие на те, которые мы решаем сами.
Ну что ж, я сотрудник отдела разработки клиентских компьютерных игр. Я участвовал в работе над проектом «Аллоды Онлайн» и сейчас работаю в серверной команде проекта SkyForge. Я пишу игры. Точнее, я пишу на Java серверную часть онлайновой игры. Мне надо подготовить курс для студентов, который был бы практически ориентирован на решение проблем, похожих на мои рабочие.
Сформулировав свою задачу таким образом, я понял какой курс нам нужен. Это должен быть курс, в процессе изучения которого студенты напишут на Java свой игровой сервер.
Это курс по Java? Да. Это практический курс? Да. По моей работе? Да! Начальные условия соблюдены. Можно начинать разработку программы.
Основную работу по подготовке курса я провел сам, но конечно, над многими вопросами я думал не один. Описывая результаты коллективной работы (обсуждений с руководством, коллегами, студентами), я буду писать — «Мы».

Разработка курса

Я начал работать над программой. Первая сложность, которая сразу бросалась в глаза — сервер бесполезен без клиента. Можно написать «божественный» сервер, но если к нему никто не сможет обратиться, ценность его будет невелика и писать его будет не интересно. Писать свой клиент, тем более на Java, не было ни желания, ни времени. Решение, в общем-то, тоже бросалось в глаза. В качестве клиента можно использовать браузер. И написать сервер для браузерной игры. По той архитектуре, которую я опишу ниже, с точки зрения сервера, разницы в том, какой клиент использовать, нет вообще никакой.

Интересное:
Студент Технопарка, который работает или проходит стажировку (в любой компании, не обязательно у нас) может сдавать только те учебные дисциплины, которые ему интересны.

Вторая сложность подбора материалов была в том, что их должно быть достаточно для создания законченного проекта, но при этом не слишком много, чтобы эту работу можно было выполнить за отведенное время. За 4 месяца, которые длится курс, студенты должны выполнить работу, равнозначную работе по разработке небольших браузерных и/или социальных игр. Насколько я знаком с такого рода разработками, весь цикл создания подобных игр занимает 1-2 месяца командой из 3-4 человек. Но в разработке участвуют профессионалы (в большей или меньшей степени), и работают они full-time. А большинство студентов, с которыми нужно было работать мне, опыта разработки не имеют (не важно, на каком языке, важно, что нет опыта создания проектов) и кроме моего курса у них еще 2 курса Технопарка и еще неизвестно сколько курсов МГТУ.

Мы решили, что для достижения наших задач нужно придерживаться ряда правил. Таких как:

  • Все практические задания по разработке кода должны складываться в один проект. Ни одна строка кода не должна быть написана просто для тренировки;
  • Для задач, не связанных непосредственно с курсом, мы используем сторонние библиотеки;
  • Студентов объединяем в группы по 3-4 человека, одна группа разрабатывает один проект. Оценку за практическую работу получает вся группа.

В результате мы решили что надо обязательно рассказать о истории и особенностях языка Java, о многопоточности и обмене данными между потоками, о том какие бывают игровые механики, о тестировании и нагрузке, о работе с файловой системой и чтении ресурсов и, в заключение, о работе с базами данных.

Подробнее программу Технопарка вы можете посмотреть здесь.

Напомню, что полное название курса «Углубленное программирование на Java». Поэтому права на резкий переход от первого занятия с Hello World к многопоточности на втором занятии у меня было. В аннотации к курсу мы написали, что для успешного восприятия студентам необходимо знакомство с базовыми понятиями в Java. Что из этого получится, можно было узнать только на практике.

Требования к слушателям курса

Из трех слов, составляющих название курса: Java, «программирование» и «углубленное» последнее самое не однозначное. Если бы курс назывался «Введение в Java», было бы понятно, о чем рассказывать. «Углубленное» означает, что у слушателей уже есть знания. Причем не только по программированию на языке высокого уровня, а программированию именно на Java. Мы решили что для успешного восприятия курса студенты уже должны знать о примитивных типах, основах ООП, ветвлениях, порядке операторов и модификаторах видимости.

Интересное:
Больше 40% студентов Технопарка видят себя через 5 лет руководителями подразделений. 30% рассчитывают зарабатывать больше 150 000 р.

В Технопарке учатся студенты МГТУ со второго по пятый курс со всех факультетов. К моему курсу они подошли после первого семестра обучения. Проверку на мотивацию они прошли, все, кто не обладал базовыми знаниями, их получили. Среди студентов были и те, кто уже пишет на Java и зарабатывает этим деньги, и те, кто до курса на Java вообще ничего не писал.

В результате часть слушателей на первой практической работе в первый раз написали «Hello world», другая часть решила, что без шаблонизаторов и http-сессий разрабатывать не интересно. По результатам первых двух занятий я решил, что правильно будет не ограничивать студентов и разрешил использовать любые библиотеки, которые им известны. А к середине курса и вовсе разрешил писать свою Frontend-часть, то есть, всю работу сервера с браузером организовать так, как им удобнее. При этом те, кто опыта работы на java до этого не имел, могли продолжать учиться по моей программе. Использование дополнительных знаний на оценку не влияло.

Особенности чтения курса в Технопарке

Технопарк — дело добровольное. В том смысле, что мы не берем со студентов платы за обучение, не подписываем никаких контрактов и не можем заставить посещать наши занятия. Это накладывает некоторые условия на формат занятий. У студентов должна быть заинтересованность в посещении лекций и семинаров. Это должно быть их собственное желание. А это значит, что сами занятия должны быть в первую очередь интересными. Если студент заинтересован происходящим, материал лекции он тоже запомнит и, скорее всего, придет на следующее занятие. Мы решили, что сделать не просто курс по java, а курс о разработке игр — мало. Лекция в нашем понимании должна быть в некотором роде шоу, то есть учебное занятие, в котором есть место для развлечения. В первую очередь это коснулось иллюстраций к учебным материалам. Ниже я хочу привести три примера из лекций:


«Матрешки-бэтмены» — иллюстрация к теме «Шаблон Decorator в java I/O»

«Обход дерева» — иллюстрация к теме «Работа с XML документами»

Вуки на слайде с большим количеством кода, чтобы глазу было на чем отдохнуть.

Кроме слайдов, для привлечения внимания оказалось очень полезным задавать аудитории странные вопросы. Например, кто помнит расстояние от Земли до Луны? Если у нас сервер с базами на Луне, какая будет минимальная задержка при записи в базу? Или, кто играл в корейские онлайновые игры? Вы можете объяснить термин ВКР?

Позитивно на восприятии сказывается и упоминание названий и игровых терминов, которые студенты не ожидают услышать в университете. Кстати, 90% опрошенных студентов играли в Tetris, Mario и GTA. Среди них нашелся эльф 80-го уровня и энтузиаст, прошедший все части Angry Birds.

Архитектура учебного сервера и практическая работа

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

Начну с описания задачи. Предлагаемый для разработки учебный сервер состоит из 8 модулей:

1.jpg

Подробно о каждом модуле:

  1. Main — зависит от всех остальных модулей. Содержит функцию main(). Создает все остальные модули в момент старта сервера. Запускает frontend, dbService и gameMechanics в отдельных потоках. Инициализирует библиотеку Jetty, передает в Jetty ссылку на frontend.
  2. Frontend это одновременно handler для событий Jetty (через браузер пользователь передает запрос в Jetty, Jetty вызывает handle у Frontend) и служба, живущая в собственном потоке. Frontend хранит только те данные о пользователях, которые нужны для создания страницы, и пересылки ее обратно в браузер. Все расчеты происходят в потоке gameMechanics. Задача фронтенда — принять запрос от пользователя, передать его в нужную службу и отдать пользователю страницу (в асинхронном режиме).
  3. dbService сервис связи сервера с базой данных. Живет в отдельном потоке, держит коннект к базе. Обрабатывает запросы остальных модулей и возвращает им ответы. dbSerivice может быть несколько, каждый в своем потоке.
  4. gameMechanics — служба сервера, в которой происходят все игровые события. Игровой мир живет в этом потоке. Для всех остальных сервисов это просто черный ящик. Разные игры, написанные студентами должны отличаться только игровой механикой. Игровая механика обсчитывает все события и отправляет реплику на Frontend.
  5. messageSystem — общий для всех потоков объект, через который происходит обмен данными между потоками. Содержит по одной очереди сообщений для каждого потока. Желающий обратиться к другому потоку должен положить в соответствующую очередь специальный объект — сообщение. Получатель достанет это сообщение из очереди и обработает его в удобное для себя время. Результатом обработки может стать отправка ответного сообщения.
  6. resourceSustem — singleton, который позволяет всем службам обратиться к файлам с параметрам работы сервера (ресурсам). Подробнее о ресурсах вы можете посмотреть здесь
  7. Утилиты — набор служб и хелперов для работы со временем, случайными числами и логами.
  8. base — набор интерфейсов и базовых классов всех служб.

Вы можете сравнить архитектуру учебного сервера с архитектурой сервера Аллодов Онлайн. Заимствование не полное, но очевидно, что мы всячески старались им подражать.

Теперь о том, в какой последовательности мы все это писали. Работа была разбита на 6 семинаров в следующей последовательности:

  1. «Hello World», знакомство с Eclipse, знакомство с Jetty. Запуск web-сервера на localhost:8080, который возвращает страницу с «Hello Server!». Запоминание пользователя либо через сессии Jetty, либо через hidden-поля на форме. Создание страницы, которая запрашивает саму себя раз в T миллисекунд.
  2. Запуск Frontend в отдельном потоке. Подсчёт из этого потока количество обращений, которые пришли к серверу со стороны пользователя. Запуск в отдельном потоке прототипа dbService (который пока к базе не обращается, а только имитирует обращение через кэш в памяти). Написание messageSystem для взаимодействия этих потоков через сообщения.
  3. Начало работы над игровой механикой. Студенты решают, какую игру они будут писать, и начинают разработку логики. Создание модуля gameMechanics в отдельном потоке, пересылка сообщений от Frontend к механике и обратно. Тестирование уже написанных модулей. Разработка unit тестов и функциональных тестов.
  4. Создание утилит для работы со временем и случайными числами (если они нужны для механики). Создание модуля для работы с файловой системой. Перенос всех параметров из кода сервера в файлы (ресурсы).
  5. Работа с базами данных. Превращение "поддельного" dbService в настоящий.
  6. Завершение работы и защита сервера.

Семинары проходили очень живо. Я и мой ассистент бегали между студентами, отвечали на массу вопросов разной степени сложности. Студенты показывали друг другу свои решения. Мы разбирали общие для всех проблемы и трудности. Некоторые из вопросов были действительно интересными и свое желание «узнать в процессе преподавания о себе и о Java что-то новое» было удовлетворено полностью.

Подход, при котором студент от состояния «ничего не писал на Java» за месяц переходит в состояние «написал web-сервер, который работает в 3 потока», может показаться жестоким. Однако, как показывает практика, именно он работает лучше всего.

Результаты первого семестра

Большинство студентов предложенную выше программу освоили. Проблемы с восприятием материала были на третьей лекции, к концу которой мы разбирали взаимодействие потоков через систему обмена сообщениями. Сейчас я прочел эту же лекцию второму потоку студентов. И теперь мне кажется, что проблемы были не столько с восприятием, сколько с моими способностями объяснить материал. Повторное чтение курса, насколько я могу судить по степени остекленения глаз студентов, проходит гораздо продуктивнее.

Интересное:
Дмитрий Гришин – основатель компании Mail.Ru – выпускник МГТУ им Баумана

Почти на всех лекциях я показывал свой код и рассказывал, как он работает. В результате, даже если студент что-то не понимал на лекции, он мог просмотреть ее в записи и скопировать сложные участки кода. Исходники своего кода я не раздавал, и, как следствие, даже при заимствовании кода из лекции этот код надо было как минимум переписать.

Главным результатом первого семестра я считаю доказанную студентами возможность написать за отведенное время проект web-севера по предложенной мной архитектуре. До защиты сервера дошли шесть групп из десяти. Три группы из шести подошли к задаче творчески и кроме реализации всех модулей сервера разработали интересную игровую механику.

Ну и, конечно, опрос студентов после завершения курса:

Заключение

Экзамен сдавали только те студенты, которые не смогли вовремя выполнить практическую работу. Мы решили, что это теоретики, и что они, возможно, смогут добиться признания в роли архитекторов. Чтобы получить отличную оценку, надо было ответить на 3 вопроса, случайным образом взятых из двух одинаковых наборов по 49 вопросов в каждом. Вариант, при котором студент вытащит два одинаковых вопроса, мы не стали отбрасывать. В этом случае он должен был отвечать на один и тот же вопрос дважды. Правда, таких счастливчиков на экзамене не было.

В заключение хочу заметить, что мы продолжаем работать над курсом. С каждым прочтением структура курса становится более логичной, а сам материал понятнее. В планах на будущее — сделать курс еще более ориентированным на практику, включить в обязательную программу использование шаблонизаторов для создания страниц и практику по разворачиванию продукта на сервере. Но об этом я напишу позже, когда будет достаточно нового материала.

Хочу пожелать удачи молодым специалистам и особенно тем, которые заинтересовались серверным программированием. И помните, именно благодаря вашему коду игра обретает настоящую жизнь в сети.

Все, кто хочет примкнуть к нашей команде, отправляйте, пожалуйста, свои резюме в нашу HR-службу на адрес job.gamedev@corp.mail.ru

Благодарности

В работе над статьей и курсом мне помогали:

  • Александр Акбашев — QA сервера проекта SkyForge, аспирант МГТУ и мой ассистент в Технопарке.
  • Дмитрий Волошин — директор отдела исследований и образования Mail.Ru Group
  • Сергей Загурский — руководитель команды сервера проекта SkyForge
  • Тимур Бухараев — руководитель Web-команды проекта SkyForge

[17.06.2013]

Copyright © 2017 ООО "ДТФ.РУ". Все права защищены.

Воспроизведение материалов или их частей в любом виде и форме без письменного согласия запрещено.

Замечания и предложения отправляйте через форму обратной связи.

Пользовательское соглашение