Bomberman Online и хабраэффект — 450 игроков на одной карте. Отчёт и детали игрового движка



    Как и обещали в топике-анонсе нашей игры, выкладываем отчёт о хабраэффекте и детали игрового движка.


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

     

    Статистика за 3 недели


    Зарегистрировано игроков: 4 663
    Сыграно раундов: 2 252
    Кол-во игроков (включая гостей): 13 402
    Кол-во фрагов: 469 534
    Кол-во смертей: 545 957
    Кол-во забитых мячей: 1 707 (WTF?)

    [во время хабраэффекта]
    Игроков онлайн (максимум): 453
    Загрузка ЦП (по графику мунина): 168% (16 ядер — 1600%)
    Использование памяти: 1.65 ГБ
    Трафик (максимум): исходящий 24 Мбит/с | входящий 9 Мбит/с

    (Графики кликабельны)
    [Engine] Connections [1]

    [Engine] Main cycle time [2]

    [Engine] Bytes per send [3]

    [Server] CPU usage

    [Server] Memory usage


    ТТХ


    Хостинг: выделенный сервер в ЦОД Владимир (который любезно предоставлен Parking.ru на время хабратестирования)

    1. Игровой движок на Java & Jetty
    2. HAProxy — проксирование вебсокетов
    3. Nginx — статика и проксирование к ноде
    4. Веб-функционал — Node.js (packages: express, mysql, request, nodemailer, validator, moment, forever)
    5. Клиентсайд — GWT, транслируемый в javascript

     

    Детали игрового движка


    Далее — от лица Jedi_Knight (автора движка).
    Разработка игровых приложений на канвасе — перспективное направление, в котором сейчас двигаются многие группы разработчиков, например эстонский проект mightyfingers.com

    Некоторые идеи взяты из статьи www.html5rocks.com/en/tutorials/canvas/performance

    Основы Тайлизма на HTML5 canvas


    Терминология: тайл — один квадратик, например 32×32; чанк — 8×8 тайлов.

    Рассмотрим особенности тайлового движка. Вот модель, к которой я пришёл:

    1) Субпиксельная прорисовка для тайлов просто не нужна.

    2) Используется несколько прозрачных canvas-ов, расположенных друг на друге. Если terrain не модифицировался, не было скроллинга, то его можно не перерисовывать — это даёт небольшой прирост производительности (по сравнению с оптимизацией кешом).

    3) Так же как и в модели игры, всё поле делится на чанки 8×8. Поскольку 64 вызова drawImage для изображений 32×32 стоят гораздо дороже одного вызова для 256×256, видимые чанки отрисовываются в кеш, состоящих из двух слоёв: под игроком и над ним.

    4) Кеш ассоциативный, то есть пара canvas'ов используется нескольким чанкам на карте: чанк с координатами (X, Y) использует кеш с координатами (X mod A, Y mod B) где (A, B) — размеры кеша. При этом размеры кеша должны быть такими, чтобы на экране не появлялись одновременно два чанка с общим кешом, будет гонка.

    5) Кроме canvas-ов в кеше запоминаются номера тайлов из текстуры, которые генерируются по логической карте. По номеру можно однозначно отрисовать тайл.

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

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

    8) Для тайлов удобнее использовать не drawImage, а createPattern и fillRect. fillRect также удобнее тем, что им можно нарисовать несколько одинаковых подряд идущих тайлов, и это будет быстрее.
    Данный тест раскрывает странный эффект: что для текстур 32×32 есть существенный прирост производительности на айпаде в 2.5 раза:
    jsperf.com/canvas-texture-draw-vs-fill
    Коммент с дополнением от TheShock

    9) И наконец зачем всё это надо: при скроллинге вместо рисования кучи мелких изображений 32×32 происходит рисование из кеша. Вызовов drawImage существенно меньше, это серьёзно влияет на производительность.

    Зелёный, жёлтый, тени — рисуются на первом слое, каждый квадрат 32×32 может рисоваться независимо от других, так как номер тайла содержит информацию о подложке, стене и тени.
    Красным рисуется второй слой, он сдвинут на 8 пикселей вверх.

     
     
     

    Найденные баги


    Итак, в ходе коллективного тестирования были обнаружены следующие проблемы:

    1) На большой карте определённого размера внезапно заглючил тайловый кеш, что привело к диким тормозам, с которыми справлялся только хром. Всё дело было в периодической карте: размеры карты (W,H) должны делиться на размеры кеша (A, B).



    Пусть W,H=7 A,B=3, угловые чанки попадают на одну позицию кеша, а на периодической карте они попадают на один экран, что приводит к гонке. Та же ситуация наблюдается по всему “шву” карты.

    2) Профилировка клиента выявила узкие места в коде, использующим java-коллекции. В этих местах коллекции заменены на самописные структуры.

    3) Изменение сетевого протокола и переход с utf8 на бинарные вебсокеты в тех браузерах, где они поддерживаются (Chrome, Firefox) позволили сократить средний трафик клиента до 12 Кбит/с. Используется нативный ArrayBuffer, отмечу что в Firefox не реализован класс DataView, поэтому обходимся обычным Uint8Array.

     

    На графиках в начале статьи показаны:


    [1] Connections — количество активных соединений с сервером.

    [2] Main cycle time — сколько занимают различные стадии главного цикла. Тик длится 100мс, preprocess — проверка команд от клиентов, tick — апдейт игрового состояния, Observers — формирование сообщений для клиентов. Total — всё вместе, и плюс время за которое сообщения уйдут в сетевой буфер. Измеряется в затраченных миллисекундах внутри одной секунды, так что когда Total приближается к 1000 — серверу плохо, начинает появляться overhead.

    [3] Bytes per send — чистый трафик, отправляемый клиентам, без заголовков websocket-фреймов, в байтах/сек.

     

    Изменения геймплея


    Почти всё время ушло на ускорение движка, клиента и сетевого протокола. Была проведена серьезная работа по оптимизации и рефакторингу, устранена масса багов.

    Но немножко удалось сделать и по геймплею: запереть врага стало легче. Но самое главное — добавлен мячик и ворота! Забившие получают спасательный щит. Особо проворные собирают по 3 щита и бегают как супергерои :)


     

    Новое нагрузочное хабратестирование. Цель — 1000 игроков онлайн на одной карте


    В первый раз сервер без проблем и лагов держал 350 игроков онлайн. Сегодня он готов к 1000.

    Мы приглашаем всех 8, 9 и 10 июня, с 17 до 22 постараться достигнуть новой планки игроков онлайн. Присоединяйтесь, зовите друзей/коллег — мы ждём вас!
    (если у кого-то недоступен домен, заходите напрямую: 141.101.245.117 — ещё не у всех обновились днс после переезда)

    Специально для хабраюзеров мы подготовили Хабрамонитор, который показывает графики текущей нагрузки на движок и сервер (с интервалом в 5 минут).

    И да пребудет с вами Сила и Фан.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 95

      +3
      Спасибо за игрулю и отчет!
        +8
        Прошу прощения, но как физически выглядит загрузка центрального процессора в 168 процентов?
          +11
          Проц вспухает
            +4
            Двухъядерный процессор?
              +2
              одно ядро на 100%, второе на 68% :) или два ядра на 84% или…
                0
                Если ядер больше одного то вполне могут быть и 168% и 200.
                  +20
                  Так вот откуда 146% взялось! 100% за одного и 46% за другого. Спасибо, теперь все понятно.
                    0
                    Ну вот: кому-как удобнее считать;) Я, например себе в угол экрана вывожу LA/num_cores * 100% и меня устраивает, т.к. числа до 100 как-то нагляднее.
                  0
                  Например, одно ядро загружено на 100%, и ещё одно на 68%.
                    +2
                    Да это круче Путина :)
                      0
                      Интересующимся подробнее о мониторинге равномерности загрузки CPU
                      0
                      Баг с ВНЕЗАПНОЙ перезагрузкой страницы, к сожалению, не дает насладится игрой :(
                        +2
                        Браузер, детали?
                        +4
                        жду отчетов от читеров :)
                          +30
                          Играть удобно с геймпадом. Примерно вот так :-D



                          Софтин для эмуляции нажатий клавы с джойстиков/геймпадов много, я обычно Joy2Key пользуюсь.
                            +17
                            так вот кто меня постоянно убивает)
                              0
                              под Mac что посоветуете?
                              0
                              К сожалению, на Firefox 13 дикие лаги (при передвижении двигается через секунд 5 после нажатия кнопок. Играть нереально так.
                                +2
                                Chrome 19.0.1084.46 — тоже самое.
                                  +1
                                  Закончилась загрузка файла на сайт, игра стала работать побыстрее. Уже вполне реально поиграть. Спасибо.
                                  0
                                  Не играет что-то, в консоль пишет: Unexpected response code: 200. Браузер Chrome 19.0.1084.52 m
                                    0
                                    Кто-то режет траффик на пути до сервера, вот вебсокеты и не работают.
                                    0
                                    Жаль не получилось сыграть.
                                    OS: Ubuntu 11.04
                                    Браузер: Chrome Версия 19.0.1084.52
                                      0
                                      А как такие красивые графики рисовать?
                                        +4
                                        Кеп подсказывает, что на графиках внизу есть имя софтины — Munin.
                                          0
                                          Точно, спасибо копетану )
                                        +3
                                        Здорово!
                                        Молодцы!

                                        Ощущение что в топе есть боты.
                                          +2
                                          Очень классно! И ведь реально затянуло.
                                            +1
                                            А мне Clanbomber нравился )
                                              0
                                              Использование памяти: 1.65 ГБ

                                              О боже! Почему так много?
                                                +2
                                                Дык ява… Было бы оно на сервере на чистом си, тогда может и в 1,65 Mb уложились.
                                                  +1
                                                  Основное место занимают не явовские структуры а различные буфера. Тем не менее, она просто кушает -Xmx1024M, а использует лишь малую часть этого.
                                                    +3
                                                    Значит, в подобных графиках ещё разумно отражать состояние java heap. Я так понимаю, он все отведённые 1024М отжирает, чтобы реже запускать GC?
                                                      0
                                                      Да, всё так. Руки пока не дошли показывать состояние jvm. Но я иногда пробегался jmap-ом и видел что утечек и диких выделений памяти нету.
                                                +6
                                                Ну всё. Работа встала.
                                                  +3
                                                  Для тайлов удобнее использовать не drawImage, а createPattern и fillRect. fillRect также удобнее тем, что им можно нарисовать несколько одинаковых подряд идущих тайлов, и это будет быстрее.
                                                  Данный тест раскрывает странный эффект: что для текстур 32×32 есть существенный прирост производительности на айпаде в 2.5 раза:
                                                  jsperf.com/canvas-texture-draw-vs-fill

                                                  Очень важно, чтобы люди, которые прочитали этот пункт не бросались бездумно заменять все drawImage на fill-pattern.

                                                  Картинка отрисовывается начиная с координат, в то время как паттерн начиная с 0-0. Что это значит? Чтобы правильно отрисовать картинку — необходимо сперва сделать translate в нужную координату.



                                                  Но этот баг не заметить если делаешь тайловый движок, потому определённо может быть резон в том чтобы использовать pattern+fillRect.
                                                    +2
                                                    Спасибо автору за статью, было интересно.

                                                    Кстати, не думал о том, чтобы отрисовать тайловую карту в слой, который в случае скроллинга двигать не перерисовывая?
                                                      0
                                                      Думал. Посмотрел на то что даже на айпаде у меня тормозит вовсе не отрисовка больших кусков, и решил не делать.
                                                        0
                                                        А что тормозит даже на айпаде? Лично у меня на айпаде до gpu-ускорения тормозило… clearRect больших участков.
                                                        Кстати, как профилируешь на айпаде?
                                                          0
                                                          Замерял сколько жрут разные части рендеринга и выводил в то окошко с FPS. Лаги смерти возникают когда надо нарисовать несколько только что полученных чанков, много тайлов. Я знаю что это можно сгладить, если я буду рисовать новый чанк в кеш не сразу а по частям, но просто не хочу это кодить. Потрачу сэкономленное время на переход к webgl.
                                                      0
                                                      Здравствуйте

                                                      Скажите я правильно понял что pattern + fillRect быстрее прорисовывает картинку чем drawImage?

                                                      Существуют случаи, когда drawImage быстрее pattern + fillRect?

                                                      Спасибо за ответы.
                                                        0
                                                        Оно действительно быстрее на новом Chrome и на iPAD, но тормознее в опере. Выигрыш зависит от размера картинки, в каждом случае надо тестить. Учтите что при fillRect возможно надо делать translate + scale, и например сочетание scale и rotate на 90 градусов даёт странный эффект на iPAD. Но при рисовании тайлов это всё не нужно, и fillRect работает просто отлично!
                                                        0
                                                        Если у вас критическое к скорости приложение, то стоит попробовать перевести его на fill-pattern и посмотреть, какой будет результат
                                                          0
                                                          Да вот тоже игру делаем и как раз в производительность на клиенте все и упирается.
                                                          Почитав информацию и погуглив дополнительно — ех… буду переделывать клиент :)
                                                            0
                                                            А какой подход в целом? Можно в личку?
                                                            Т.К. я и с drawImage не имею особо проблем с производительностью
                                                              0
                                                              Ми только изучаем все прелести HTML5.

                                                              Ну как у нас сейчас — есть реализован сервер и практически реализован клиент.
                                                              Принцип отрисовки прост — один канвас и FPS 30.
                                                              То есть 30 раз в секунду все перерисовывается — теперь я понимаю насколько єто глупо.

                                                              Смотрю Вы разбираетесь в JS — так как я не очень.
                                                              Если интересно принять участие в проекте — пишите в личку и я дам свои координаты можем больше пообщаться. Сами мы с Украины (Киев — Івано-Франковск).
                                                                0
                                                                А апдейтится состояние игры сколько раз?
                                                                  0
                                                                  Єто хот-сит — потому редко.
                                                                  Графики много
                                                                  0
                                                                  Ну я автор LibCanvas, так что на Canvas разрабатываю уже более 2 лет. И сейчас занят серьёзным комерческим проектом.
                                                                  Могу помочь консультациями и советами, в скайпе, shock13666
                                                                    0
                                                                    Спасибо — отравил запрос в скайп
                                                                      0
                                                                      Напишите сообщение)
                                                                        0
                                                                        отписал ;)
                                                        +18
                                                        4. Веб-функционал — Node.js (packages: express, mysql, request, nodemailer, validator, moment, forever)
                                                        5. Клиентсайд — GWT, транслируемый в javascript

                                                        • UFO just landed and posted this here
                                                        • UFO just landed and posted this here
                                                          • UFO just landed and posted this here
                                                              0
                                                              Через корпоративный прокси-сервер не работает. Почему?
                                                                0
                                                                Значит прокси не поддерживает вебсокеты.
                                                                • UFO just landed and posted this here
                                                              +1
                                                              К сожалению с таким latency играть пока просто не возможно. Жмешь кнопку двигаться, а он двигается в лучшем случае через секунду. Уже несколько раз умер изза этого. Поберегу-ка я свои нервы до следующего бета-теста.
                                                                +1
                                                                Это проблема с каналом до сервера в частном случае… На данный момент движок очень требователен к нему.
                                                                +1
                                                                Интересно конечно, но играть невозможно, каждые 5 мин всевиснет, приходится перезапускать браузер.
                                                                Каждую минуту выскакивает яваскрипт с предупреждением в хроме что некоторые плагины перестали работать (тулбар скайп в частности).
                                                                А в целом очень понравилось. Успехов вам.
                                                                  +8
                                                                  Удалите грёбанный скайп-тулбар для начала. Один из самых долбанутых плагинов для браузера.
                                                                    0
                                                                    Не знаю, все может быть, я не пользуюсь ни хромом ни тулбарами которые на нем стоят, да и если честно впервые узнал что такой бывает.
                                                                    Залез в него лишь потому что в других браузерах поиграть было просто нереально из-за тормозов.
                                                                  0
                                                                  В разных браузерах вижу только это: image
                                                                    0
                                                                    Значит вебсокеты не достучались, что-то режет траффик до 80-ого порта.
                                                                      0
                                                                      Аналогично. Началось такое вчера часов в 18. До этого работало нормально.
                                                                      0
                                                                      Ubuntu 64 Firefox proxy: сайт грузится — игра нет. Javascript и флеш включены.
                                                                        +1
                                                                        proxy должна поддерживать вебсокеты.
                                                                        +2
                                                                        Сделайте приложение для vkontakte и facebook. Не пожалеете.
                                                                          +3
                                                                          И продавать бомбы по рублю :-)
                                                                          +3
                                                                          Очень хочется отдельные карты для игры с друзьями!
                                                                            0
                                                                            Да, это первый запрос в списке всех кому кидал ссылку.
                                                                              0
                                                                              То есть собственная комната, куда можно загнать друзей по приглашению и пофаниться?
                                                                              Мне нравится, что-то мы такую идею упусти ли…
                                                                              0
                                                                              При запуске игры в консоли вот такое:

                                                                              WARNING: error in render com.google.gwt.core.client.JavaScriptException: (NS_ERROR_NOT_AVAILABLE): Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage] QueryInterface: function QueryInterface() { [native code] } result: 2147746065 filename: bombermine.ru/play/app/DD177CA4CF1111D73CCFA09F9901E244.cache.html lineNumber: 6993 columnNumber: 0 inner: null data: null initialize: function initialize() { [native code] }

                                                                              И такого там много.
                                                                                0
                                                                                А браузер какой?
                                                                                  0
                                                                                  FF 13

                                                                                  Попробовал напрямую 141.101.245.117/
                                                                                  Все работает отлично.
                                                                                0
                                                                                До 17-00 ещё далеко, а сервер уже недоступен…
                                                                                0
                                                                                Вход по OpenId прикрутить не планируете?
                                                                                  0
                                                                                  Планируем.
                                                                                  0
                                                                                  Не загружается игра. Напрямую пробовал.
                                                                                    0
                                                                                    Сайт или игра? Какой браузер?
                                                                                      0
                                                                                      Игра, файрфокс 13
                                                                                        0
                                                                                        Что в консоли?
                                                                                          0
                                                                                          Все, разобрались. Там вебсокеты были выключены.
                                                                                    +1
                                                                                    Пара вопросов нуба, который хочет понять как окупать такие игры.

                                                                                    1. Над игрой работало в общей сложности 6 человек, специалистов в своей области. Вопрос. Сколько времени прошло с момента идеи до запуска сервера в продакшен? Сколько оценочно человекочасов потребовалось?

                                                                                    2. Как собираетесь монетизировать? Пока наблюдаю только рекламу вашего же хостера, и все. Планируете ли зарабатывать на этой игре? Или этот проект просто для саморекламы и ислледования возможностей используемых технологий?
                                                                                      0
                                                                                      Рискну за всех ответить.
                                                                                      Пока мы все работаем на голом энтузиазме, бюджета нет. Все работают в разной степени, так художники пока не очень заняты. Связано с сильной загрузкой программиста, который не успевает реализовывать все идеи и параллельно оптимизировать движок.
                                                                                      Так что время оценить очень сложно… Безусловно, все можно было бы сделать в два-три раза быстрее, будь мы полноценной сработавшейся командой.

                                                                                      Сама игра изначально задумывалась как полигон для тестирования движка, но очень полюбилась народу. В какой-то момент мы решили его сделать полноценной игрой.
                                                                                      Собственно говоря, поскольку мы планируем выход в социальные сети, донат все таки появится и будет носить чисто декоративный характер (в основном кустомизация). «Зарабатывать» — вряд ли получится, а вот набрать стартовый капитал вполне возможно. Конечно, есть возможность того, что игра «выстрелит». Но на джекпот рассчитывать не стоит никогда.

                                                                                      0
                                                                                      Прикрутите возможность играть на тач устройствах пожалуйсто.
                                                                                      На первом айпаде приемлимый фпс а вот поиграть не получается
                                                                                        0
                                                                                        Будет реализовано, но пока это не в приоритете.
                                                                                        0
                                                                                        Про самое главное забыли: запилить «Boo Crack»

                                                                                        Only users with full accounts can post comments. Log in, please.