dima9595
@dima9595
Junior PHP

Как восстанавливать энергию через определённое время?

Доброго времени суток! Интересует вопрос со стороны лучшего, более производительного варианта. Суть такова - есть игроки, у них используется "энергия" для определённых действий (не важно каких). Я хотел, что бы через какое-то определённое время "энергия" восстанавливалась, при этом нужно учитывать тип аккаунта (простой или премиум, название не важно), так же в условие необходимо учесть, пользователь онлайн или нет.

У меня на данный момент 3 варианта:
1. Cron. При этом, на мой взгляд, тут будет много запросов в БД (если будет много игроков), так как учитывается ещё и онлайн.
2. WebSocket. Данный вариант, на мой взгляд, идеален для восстановления энергии онлайн пользователей. Но как мне кажется, ужасен для расчёта энергии в остальном.
3. Cron + WebSocket. Вот этот вариант более лучший. Т.к. cron выполняет просчёт кол. восстановленной энергии для типов пользователей. А соккет будет расчитывать энергию для онлайн-пользователей с учётом типа аккаунта.
Но тут есть одно "но" - нужно будет учесть так, что бы 2 разных алгоритма не работали с одними же пользователями, иначе о онлайн пользователей будет преимущество в восстановлении энергии.

Если есть какой-то лучший вариант, то прошу Вас написать об этом. Если же один из моих вариантов подходит для данной реализации, но нужно его как-то доработать, то прошу об этом написать (желательно с пояснением). Заранее спасибо!)
  • Вопрос задан
  • 509 просмотров
Решения вопроса 3
be_a_dancer
@be_a_dancer
Backend/Fullstack Developer
Можно очень просто. Сохраняешь в бд последнее время, когда игрок обновил энергию. Потом, при следующем запросе ты смотришь, пора? Далее, если необходимо, проверяешь, сколько раз стоило восстановить энергию. Ну и добавляешь необходимое количество пунктов.
Ответ написан
saboteur_kiev
@saboteur_kiev Куратор тега Разработка игр
software engineer
Сохраняйте timestamp последнего обновления и обновляйте энергию при каждом обращении к информации для этого игрока (или даже при каждом обращении к информации игрока, которому нужно вернуть энергию).
Ответ написан
Комментировать
@HellWalk
Как и обещал - сделал руководство по созданию системы регенерации энергии в браузерной игре (делал для своей игры, но почему бы и не поделиться наработками с товарищами по ремеслу):

Демо
Код на github
Подробное руководство

Используется: PHP, MySQL, JS
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Kubatai
@Kubatai
Техник-программист
Раз уж вы используете MySQL, то наилучший вариант будет использование MySQL Event Scheduler вместе с полем "Дата последнего обновления энергии".
По теме есть хорошая статья на хабре и rldp + официальная документация.
Ответ написан
@azShoo
"Оптимальный" путь зависит многих факторов.
Например, от архитектуры игр: предполагается постоянный коннект клиента с сервером, или можно жить в оффлайне?
Например, от UI и игровой логики: должен ли у пользователя быть постоянный real-time доступ к состоянию таймера восстановления, или оно просто должно тикать где-то в фоне?
Может ли он взаимодействовать с этим таймером (напр. дебаффать других игроков, что бы замедлить восстановление, или задонатить что бы сократить время)

В целом детерминированная по определенным правильнам, регулярно случающаяся активность идеально попадает под Scheduled Job \ Timer внутри игровой логики.
У вас есть момент инициализации таймера, в который вы рассчитываете с какой скоростью и в каком объеме у вас должен происходить "тик" восстановления энергии.
У вас есть момент окончания таймера - объект из буффера кидается в очередь на передачу клиента, обрабатывается клиентом, происходит так.
У вас есть критерии его окончания - пользователь ушел в оффлайн? Грохнули все таймеры для него, например. Или, наоборот, зафризили.

Самое сложное тут - правильно отслеживать состояние таймера и апдейтить его при необходимости.
Для этого надо правильно проработать условия возникновения, истечения и обработки таймеров и сложить их в прозрачное и пригодное для дебаггинга-тестирования хранилище.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы