php - как заставить работать очередь событий в автономном режиме в браузерных играх

Размышляя о создании браузерных игр, я столкнулся с тревожной проблемой. Во многих играх есть так называемая "очередь событий", которая работает следующим образом. У меня есть "армия", и я посылаю ее своему противнику. Я занимаю некоторое время. Когда моя "армия" получает расположение "армии" противника, происходит бой, рассчитанный на то, чтобы моя "армия" проиграла или выиграла. Все хорошо, когда я или мой оппонент в игре. Какая-то Ajax-работа может управлять вызовом php-скрипта и вычислять бой, а затем сохранять его результат в базе данных. Но как это может работать, если ни я, ни противник не вошли в систему, когда происходит битва? Хорошим примером такой игры является Ogame, когда вы отправляете корабли на другую планету, и он может встретить свое предназначение, когда вы выйдете из системы, проведете бой, получите источники информации о вашем враге и возвращаетесь, поэтому он рассчитывает не только космические корабли на планете, но и количество ресурсов в этот конкретный момент.

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

Есть ли у вас идеи, как сделать такую ​​очередь событий? Я думаю, что использование cron также не очень хорошая идея - его иногда можно использовать редко, и, если есть тысячи игроков, тысячи экземпляров cron могут быть причиной снижения производительности. Любая концепция будет оценена - надеюсь, я достаточно хорошо описал свою проблему:)

2 ответа

Решение

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

Затем каждый раз, когда кто-нибудь (!) Загружает какой-либо сайт (даже стартовую страницу), скрипт проверяет наличие заданий в очереди, которые уже должны были быть выполнены. Если есть какие-либо задания, в которых EXPIRE меньше, чем NOW, он выполняет эту работу (или, для больших заданий, запускает процесс php cli для выполнения этой работы).

Если предположить, что это 2012-12-28 12:00, в игре есть два игрока A и B, где A начинает атаку на B, которая занимает 6 часов. Задание создается с EXPIRE=2012-12-28 18:00 и контентом "Fleet foobar attack B".

Случай A: Теперь A выходит из системы и ничего не происходит до 19:00. B входит в систему, и, прежде чем что-либо еще произойдет (это важно для того, чтобы "уведомления" или входящие сообщения не появлялись несинхронно), сценарий видит, что задание находится в таблице и просрочено. Сценарий выполняет задания и создает уведомление для B о том, что он был захвачен огромным флотом из A. Задание выполнено, все в порядке (кроме настроения B).

Случай B: A выходит из системы. В 18:30 анонимный пользователь заходит на стартовую страницу. Сценарий снова просматривает таблицу заданий и выполняет задание. Б входит в 19:00 и видит уведомление о его потере. Работа выполнена.

Идея создания очереди событий без CRON в моем проекте заключается в следующем:

  1. Все события имеют время окончания. Я использую сырые временные метки UNIX time() для простых операций сравнения.

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

  3. Если в игре нет пользователей - никому не нужны события. Просто так просто:) Игра спит до тех пор, пока кто-нибудь не войдет в игру и не откатится в очередь событий, как описано во втором шаге.

Вы можете добавить такую ​​же функциональность на любой веб-сайт, который имеет периодические события и достойный ежедневный трафик сайта.

(На самом деле я также сделал cron.php по требованию)

Другие вопросы по тегам