Hужно ли дублировать вычисления на клиенте и сервере?
Делаем игру, сейчас вычисления, например, начался ли новый уровень, или прошелся ли квест делаются и на клиенте и на сервере.
Естественно, велик соблазн повесить все на клиент, но тогда: 1 — _очень легко взломать игру, 2 — данные могут неправильно обработаться (неспрашивайте как), 3 — куча мелких проблем с синхронизацией, сохранением и т.п.
Естественно, велик соблазн повесить все на сервер, но тогда: 1 — _очень много вычислений на сервере, по факту, они нам не нужны, 2 — время ожидания синхронизации увеличивается, 3 — приходится все-таки дублировать функционал на клиенте, без этого никак, 4 — куча мелких проблем с синхронизацией с клиентом.
Естественно, велик соблазн сказать, что мы объединим оба подходы, и получим нечто выдающееся, но… реальность вносит свои коррективы.
По факту, я работал и в компании, где придерживаются первого варианта (все на клиенте), и второго, но, что лучше, для себя самого пока не решил,
Есть ли у уважаемого сообщества какие-нибудь мысли в пользу первого или второго варианта.
Все на сервере и никак иначе. О каких проблемах синхронизации для этого варианта вы говорите, я просто себе не представляю, а вот синхронизация сервера и N взаимодействующих клиентов между собой — это АД.
А в целом опять же все упирается в конкретную задачу и степень доверия клиентским вычислениям, которые оцениваются персонально для каждой отдельной цели приложения — ведь сервер может выполнять только роль роутера или коммуникатора — т.е. клиенты стучат на сервер, сервер их между собой связывает и ждет результата вычислений от обоих(группы), если результаты совпадают — засчитывает результат, если имеет место потеря соединения, оставшийся клиент переключается на сервер и ждет его решения.
В первом случае, про АД — я имел ввиду, что если вычисления производятся в каждом клиенте отдельно и на сервере, то каждый участник такой системы должен знать про результаты вычислений всех остальных участников системы, для этого нужно иметь или соединения между всеми участниками или посредника, т.е. опять возвращаемся к системе, с сервером в центре.
В этом случае несомненно! Естественно все зависит от характера игры. Упоминание сервера и клиента просто практически однозначно наталкивают на мысль о мультиплеере.
В этом случае можно использовать такой подход — для получения доступа к следующему уровню персонажа(раунда игры) по ключевому событию (повышение уровня, переход в следующий раунд) отправлять на сервер пассивную статистику — например время потраченное на этап, количество убитых/собранных вещей, количество своих поражений/смертей, потраченных ресурсов и т.п. — если результаты статистики похожи на реальную игру, выдавать ключ, открывающий доступ к следующему этапу игры, если видим хак, сообщаем, что обнаружено мошенничество, баним либо возвращаем в состояние начала текущего уровня.
И конечно же такая система должна пройти длительное альфа/бета/кандидат тестирование без принятия каких бы то ни было мер, и со временем, по отсутствии багов можно начинать более детальную настройку системы защиты.
отправлять на сервер пассивную статистику — например время потраченное на этап, количество убитых/собранных вещей, количество своих поражений/смертей, потраченных ресурсов и т.п. — если результаты статистики похожи на реальную игру, выдавать ключ
Это ж представляете, какая нагрузка будет ложиться на сервер? А если на сервере 500 000 человек в день играет, все это считать, да еще и каждый раз при сохрании информации, а этих сохранений может быть сотни за сессию.
Насчет тестирования согласен, но, как я уже писал, реальность часто вносит свои коррективы
А если планируется введение платных возможностей, то их использование должно поностью регистрироваться на сервере и вычисления, с этим связанные, так же.
Это ж представляете, какая нагрузка будет ложиться на сервер? А если на сервере 500 000 человек в день играет, все это считать, да еще и каждый раз при сохрании информации, а этих сохранений может быть сотни за сессию.
Если бы хотя бы намекнули на геймплей, можно было бы что-то более конкретное и реальное думать.
Пассивная статистика на то и пассивная, что бы не слишком нагружать. Пример (например RPG):
Чтобы персонаж прокачался с 1-го уровня до 2-го ему нужно 100 опыта. На текущем этапе могут попадатся противники, с которых можно получить от 0 до 20 опыта.
Пассивная статистика будет содержать такие данные:
Текущий уровень — 1
Запрашиваемый уровень — 2
Убито противников — 10
Заработано опыта — 115
Сервер по матрице соответствия проверяет, что для перехода с 1 на 2-й уровень нужно 100 опыта, на этом этапе максимальный опыт за единицу врага — 20, т.е. минимально нужно убить 5 врагов, а убито 10 — Доступ разрешен.
Т.е. задача проанализировать несколько цифр практически без вычислений — помоему это более легкий вариант для сервера, чем параллельное вычисление.
хм, я так понимаю Вы только на этапе проектирования. Регистрировать в любом случае придется все. Что же вы, на стороне клиента планируете хранить во время офлайна данные? Что вы скажите человеку, который ввалил деньги в игру, а потом у него слетела операционка и все данные потерялись. он запускает игру и у него опять все по нолям?
Нет, конечно я не предлагаю хранить локально, но есть различия, между, например, тем что мы регистрируем покупку и проверяем ее на сервере, и тем, что мы просто записываем в базу новый инвентарь, и новое количество монет. Я работал там, где использовался первый вариант, и не могу сказать, что он уж очень сильно плох.
Вот когда дорастете до таких показателей, проект сам подскажет решение, а реализовать такую нагрузочную способность на начальном этапе — потеря денег и времени, спроектируйте свою игру с предпосылкой к масштабированию, а дальше все станет на свои места.
Я дорастал и до таких и до больших показателей, и, как писал, использовал оба варианта, и так и не понимаю, какой из них лучше.
проект сам подскажет решение
Был один проект, довольно популярный, и хорошо монетизированный, его закрыли в том числе из-за проблем с сервером — andryuhell.livejournal.com/42440.html
но есть различия, между, например, тем что мы регистрируем покупку и проверяем ее на сервере, и тем, что мы просто записываем в базу новый инвентарь, и новое количество монет
Давайте тогда посмотрим в сторону очередей сообщений — клиент кидает серверу сообщения, в которых описаны его действия, они копятся в памяти, т.е. при записи никаких вычислений, а сервер отдельным контрольным потоком(ами) периодически обходит все очереди сообщений — например каждые 1-10 секунд
Я дорастал и до таких и до больших показателей, и, как писал, использовал оба варианта, и так и не понимаю, какой из них лучше.
Ну если вы дорастили до таких показателей и Ваш вариант с параллельным вычислением и на сервере и на клиенте справлялся с подобной нагрузкой, я не понимаю, как метод пассивной статистики мог Вам показаться более требовательным к вычислительным ресурсам.
Я исчерпан, спасибо, что выслушали.
Мой итог — отдавайте предпочтение защите и надежности, лучше чуть раньше купить второй сервер, чем за один конкретный провал расплатиться всей своей аудиторией.
Нужно решить что для вас важней.
Безопасность, или производительность.
Я лично за безопасность. НО! Самый оптимальный способ, это проводить вычисления на стороне клиента, и проверять входящие данные на сервере.
Например. Мы знаем, что пользователь не может заработать/выиграть за определённое время определённую сумму. При вхождении на сервер данных проверять это соотношение. если оно ложное (пользователь подменил данные) тогда не записывать ничего в базу. А пользователю предупреждение.
Высчитывать дельту — хорошо звучит на в теории, но, на практике, большая дельта может появиться у хорошо платящих пользователей, а значит, в случае появления багов, именно платящие пользователи будут им подверженны, а значит, будут уходить из игры, и не возвращаться.
Если у вас существенный обсчеты в игре то у вас нет выбора как делать все на клиентах, если не так все сложно то можно считать и на клиенте и на сервере, это позволяет уменьшить лаг.
Создатели EVE Online (онлайн по 50 000 был — сейчас, наверное, уже и больше) решили делать всё (ну кроме 3д графики и т. п. ессно) на сервере, на клиенте обсчитывать только для уменьшения лагов в неизменяющейся обстановке (то есть клиент отправил, грубо говоря, текущее состояние серверу, посчитал на его основе новое состояние, отобразил, и тут приходит ответ от сервера — если локальное состояние и расчётное одинаковы, то ничего не трогает, если различаются, значит на сервере произошло что-то о чём клиент до этого не знал и должен выкинуть нафиг проделанные расчёты, заменив их серверные — при «лагах» интересные эффекты получаются — вылетел, никого нет, летишь себе спокойно, потом бай и убит моментально. — по логам смотришь, оказывается тебя пару минут пинали, просто сервер вовремя сообщить не мог и клиент играл как бы в сингл)
онлайн в EVE Online разбросан по разным системам/локациям, ктороые крутятся на разных серверах.
На одном сервере пока не больше двух-трех тысяч человек. (впрочем пару лет назад было меньше).
Судя по тем заметкам о багфиксах и оптимизации, что они публикуют в девблоге, у них там в серверной части какой-то адовый пиздец, извинте за выражение.
Вопрос что и как считается, например в варкрафте 3 и старкрафте, нет рандома в игре, любое действие на любой машине произойдет одинаково, за счет этого все дублируется на клиентах и на сервере и систему обмануть нельзя. И обмен данными за счет этого становится минимальным, уменьшается лаг и расчетов на самом деле в таком случае не много.
А в чем смысл дублировать на сервере синглплеер игру? Какая така великая беда случится от того, что кто-то накрутит себе уровень? На худой конец можно отправлять на сервер информацию об убитых противниках, изменении денег, патронов, инвентаря, и иногда их контролировать (при сохранении, левелапе или смене локации например).