Вопрос к коллегам

Собственно есть у меня такое хобби как разработка браузерных игр. Когда то в своё время я на этом деле перешёл от Си к php. Но суть дела не в этом. Есть такая задачка которую хотел бы попробовать решить с вами вместе.

Вкратце я хочу организовать движение людей по карте в режиме онлайн. К примеру у нас есть карта в виде матрицы со своими координатами:


|  1  |  2  |  3  |  4  |


|  5  |  6  |  7  |  8  |


Предположим что у нас в клетке 1 сейчас находится один пользователь (А), а в клетке 7 находится пользователь Б:


|  A  |  2  |  3  |  4  |


|  5  |  6  |  Б  |  8  |


Я хочу сделать что б при движении пользователя A к примеру в клетку 4, у пользователя Б с минимальной задержкой отобразилось движение юзера А. В идеале к примеру я стою на месте - и вижу как движутся другие пользователи по карте.

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

  1. При движении пользователя А заносится информация в базу данных что

А с клетки 1 движется в клетку 7.

  1. Пользователь Б постоянно сканируют базу данных на изменение в ней. И в случае если видят что в базе записано что кто то куда то движется - тогда какае то там функция запускается на стороне юзера Б и двигает картинку пользователя А в указанную в базе точку.

  2. Ну и тоже самое на оборот. Т.е. по той же самой системе пользователь А будет видить что пользователь Б начал своё движение.

В принципе такая система работает и в реализации весьма простая но я есть ОЧЕНЬ БОЛЬШОЙ минус, это конечно же БД. Из-за того что постоянно надо сканировать её на изменение данных - будет очень большая нагрузка. Вариант с двумя пользователями на карте конечно нагружать сильно не будет, но что если их будет не два, а хотя бы 500? если предположить что конектимся к базе за новой информацией раз в 1 секунду, то база получит 500 обращений в сек постоянно что весьма туго.

Прошу у вас помощь в решении данной проблемы. Может кто знает еще какие то варианты решения данной задачи (не обязательно на пхп, без разницы на чем, главное алгоритм).

Хотя в принципе 500 запросов в сек не так уж и много если подумать…

Все равно интересно услышать может у кого другие идеи есть по решению данной задачи :) всем буду весьма благодарен. А если у кого есть данные как это решают те же разработчики обычных пк-шных многопользовательских игр - буду в двойне благодарен :)

Удачное решение будет, если при шаге, сервер говорит куда он пошел)) Http это не поддерживает, но люди это обошли, как еще сам не разобрался и не использовал, но читал про это на хабре)

http://habrahabr.ru/…s/webdev/60803/

Не бейте сильно ногами. :slight_smile:

А если сделать так:

Персонаж А двигается, скрипт на сервере определяет кто из присутствующих персонажей видит это движение и, если персонаж В его видит, создает в файл (к примеру "В.move") определенного формата, К примеру:

Броузерный скрипт персонажа В периодически запрашивает данные с сервера через еще 1 серверный скрипт. Если файл "В.move" существует - …

Дальше понятно…

Quote

Не бейте сильно ногами. :-)

А если сделать так:

Персонаж А двигается, скрипт на сервере определяет кто из присутствующих персонажей видит это движение и, если персонаж В его видит, создает в файл (к примеру "В.move") определенного формата, К примеру:

Броузерный скрипт персонажа В периодически запрашивает данные с сервера через еще 1 серверный скрипт. Если файл "В.move" существует - …

Дальше понятно…

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

Quote

Удачное решение будет, если при шаге, сервер говорит куда он пошел)) Http это не поддерживает, но люди это обошли, как еще сам не разобрался и не использовал, но читал про это на хабре)

http://habrahabr.ru/…s/webdev/60803/

спасибо,

почитаю

Zolter [Ozzy]

В свое время делал подобную вещь (реализовывал игру по жанру Baldur’s Gate). Так вот, если брать во внимание современные веб-технологии то есть отличное и простое решение и его тебе подсказал товарищ 3an - это server push. Как пример реализации технологии это Aptana Ajaxer (www.aptana.com/ajaxer) и Ext.Direct (www.extjs.com).

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

Что касается Ext.Direct - вышло это дело в начале мая, по сути это набор javascript+php api. Позволяет как использовать функции и классы php в javascript, так и реализовать технологию server push. Толком с ним не разбирался, но буду реализовывать Adobe Air + Ext.Direct для внутрисетевого проекта.

Так что всякие запросы по 500 штук в секунду с учетом века высоких технологий уже отпадают ;)

to Digital God

Спасибо :) Почитаю про Aptana Ajaxer. С extjs раньше был знаком но достаточно поверхностно. Думаю стоит освежить знания :)

С Aptana Ajaxer я не много возился, у себя на серваке я задолбался его настраивать, поэтому погонял у них на хостинге.

Extjs обновился до 3 версии и там много вкусных вещей, так что посмотри)) как они себя позиционируют - новый век Ajax технологий :)

Там еще про плагин к jQ говорили что то, надо будет тоже поискать т.к. с jQ я уже давненько тесно работаю.

п.с. вот тут материала интересного еще нашел, вдруг кому пригодиться. 

п.п.с. как я понял наши деды решали такие вопросы через скрытый фрейм

Правильно понял :)

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

Quote

link=topic=2457.msg13623#msg13623 date=1244011505]

Там еще про плагин к jQ говорили что то, надо будет тоже поискать т.к. с jQ я уже давненько тесно работаю.

п.с. вот тут материала интересного еще нашел, вдруг кому пригодиться. 

п.п.с. как я понял наши деды решали такие вопросы через скрытый фрейм

а  нет ли ссылки  на  плагин для jQ

С Processing.js кто-то сталкивался?

Я вот недавно начал работать (функционал активной графиик понадобился) в связи с чем обнаружил этот продукт. Сам Processing для джавы весьма сильный инструмент, в Processing.js к сожалению еще не перенесены функции работы с 3д, камерами и тп.

Извиняюсь за подъем старой темы, но хочу предложить свое и вовсе не оригинальное решение — лог ходов. При каждом перемещении игроков из локации в локацию, в лог пишется record_id, кто, откуда, куда. Пользователь знает id последней полученной информации (можно в сессии сохранить). Соотв., выбираем из базы по PK > $old_record_id. При таком подходе нет нужды в анализе всего игрового пространства.

К сожалению в таком подходе тоже есть минусы.

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

Ну, во-первых, сканироваться будет лишь индекс, а при частом использовании он будет в кеше СУБД. Во-вторых, можно дополнительно подфильтровать по "откуда" и "куда" (я так понимаю, игрока интересуют только прилежащие локации, а не все), чтобы уменьшить объем выборки. Лог то наверняка полегче будет…

Я бы предложил написать сервер для обработки игровых данных, например питон + twisted, можно даже рассмотреть вариант php scgi сервер http://blog.milkfarmsoft.com/?p=52, при таком раскладе получается игровой сервер, который все хранит в оперативке, делая периодически снапшоты в ту же базу, тогда при первом варианте, веб приложение будет лишь тонким клиентом для самой игры, а во втором варианте, можно при помощи app server хранить игровую карту прям в приложении (суть оперативной памяти), ну и сделать ряд обработчиков непосредственно для отдачи контента  но насчет стабильности этого решения ничего не скажу.

По поводу передачи самих данных трудно что либо сказать, так как опыта нет, но первым бы моим вариантом было бы следующее.

  1. Есть видимая область для игрока.

  2. Инициализация - отправка запроса, получение игровой информации.

  3. Далее стоит задача держать отображение карты в актуальном состоянии.

Вариантов несколько.

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

Или же можно передавать йди объекта, и его направление движения на каждый тик, (это один из вариантов оптимизации первого варианта )

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

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

Ну как то так.

Как будет реализовываться работа клиента с сервером, ну на мой взгляд можно использовать flash + socket, тогда по сокету мы можем лезть непосредственно к игровому серверу (вариант 1) а сайт будет лишь авторизационной оболочкой.

При использовании push технологии, я не знаю как в этом случае организовать обратную связь.

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

Еще вариант flash + fms сервер. Но тут я уже не силен.

ЕЩе вариант activex??