Привет, Хабр! Представляю вашему вниманию перевод статьи Don’t use Lockstep in RTS games.
Lockstep проиграл! Клиент-серверная модель победила и стала стандартом для большинства игр. Стратегии в реальном времени были последними, но в них Lockstep используется все реже и реже. Давайте узнаем почему, но сначала, что такое Lockstep?
В играх есть несколько игроков, играющих игру на клиенте. Но как же удостоверится, что они играют одну и ту же игру? Используя Lockstep все клиенты запускают один и тот же код, с одинаковыми параметрами и входными данными. Например, если один из игроков приказывает армии идти в указанную точку, эта команда передается всем клиентам и у всех эта армия двигается в указанную точку. Даже генератор случайных псевдо-случайных чисел должен быть одинаковым у всех, обычно это делается с помощью использования одинакового seed в начале игре и выполнения всего в одинаковом порядке. Это очень эффективно с точки зрения сети, потому, что передаются только команды. Такие вещи, как приказ или действие занимают очень мало места в сетевом пакете.
Lockstep — очень эффективная модель сетевого взаимодействия, но сложна в реализации из-за проблем рассинхронизации или различий компиляторов/разных платформ. Lockstep использовался в прошлом потому, что пропускная способность сети была очень низкой. Это отлично работало. Концептуально, его очень легко добавить в существующую игру. К примеру, DOOM, которая уже была написана и все работало. Чтобы добавить мультиплеер, John Carmack должен был запускать команды на каждом компьютере. Это очень легко в теории, до того, как задержки или отличия архитектур испортят все. На практике, это сложно сделать. Программист должен убедится, что все команды исполняются в одинаковом порядке на каждом клиенте. Что если кто-то не получил команду вовремя? Клиент должен ждать подтверждения получения команды от всех клиентов. Что случится, если кто-то переподключился? Первое, что приходит на ум — симулировать всю игру с самого начала, что может занять довольно много времени.
С использованием Lockstep'а, программист должен убедится, что компилятор не оптимизирует операции с числами с плавающей точкой, потому, что разные архитектуры процессоров могут иметь небольшие различия в результате одинакового вычисления. Это особенно заметно, если вы пробуете синхронизировать PC и iPad. Различия архитектур — кошмар для Lockstep. Если вы работаете с HTML5?-Javascript, JIT может оптимизировать вычисления по разному, делаю небольшие погрешности, которые могут повлечь за собой большие изменения. Программирование Lockstep — как удерживать большой вес на кончику ножа.
Если этого вам недостаточно, Lockstep использует p2p, наследуя все проблемы второго. Если вы используете TCP, вы не сможете соединить два любых компьютера через интернет из-за брандмауэров, NAT'ов, прокси, VPN… и т.д. С UDP есть шанс сделать hole punching. К счастью, браузеры поддерживают webRTC, который работает через UDP и имеет API для hole punching через STUN-сервер. Хотя-бы эта часть может быть сделана с помощью HTML5.
А что такое Клиент-Серверная модель? Это просто когда клиент присоединяется к серверу и сервер отправляет клиенту обновления. Готово! Сервер и клиент может использовать разный код, на разных языках и даже платформах. Сервер имеет полный контроль над игрой. Здесь нет ножа, на кончику которого нужно что-то держать. Основная проблема в том, что сервер должен отсылать больше обновлений. Это потому, что перемещение каждого юнита, выстрел пули, изменение здоровья должны быть синхронизированы. К счастью, сетевой канал пользователей расширяется и дешевле, чем время программиста.
Причиной, почему RTS использовали Lockstep была ширина канала. В FPS движение 32 людей не требует большого количества трафика. В RTS движение 1000 требует больше трафика, но ширина канала позволяет это.
Клиент-Серверная модель более устойчивая к читерам. Используя Lockstep, каждый клиент знает все обо всей игре. Например туман войны — клиентская часть, клиент в реальности знает, что за туманом, но не показывает его. Также каждый знает IP и открытый каждого из клиентов и может заспамить врагов — микро DDOS. В Клиент-Серверной модели сервер просто не отсылает обновления за туманом войны, а IP других клиентов знает только сервер. Конечно, клиент может сделать DDOS-атаку на сервер, но сервера легче могут противодействовать атаками и могут блокировать клиентов с подозрительной активностью.
Недостаток серверов — они стоят денег, в то время как для Lockstep не нужны сервера, все — p2p. Хорошо, что есть провайдеры, у которых можно арендовать сервера. Но если это все еще слишком дорого, вы можете запускать один сервер на одном из клиентов … это похоже на Lockstep … кроме того, что есть один полномочный клиент, и что на него больше нагрузка.
Примеры:
- StarCraft 1 использовал Lockstep, в то время как StarCraft 2 использует Клиент-Серверную модель.
- Supreme Commander 1 использует Lockstep когда более новые игры, например Planetary Annihilation, использует Клиент-Серверную модель.
- DotA запускалась на движке Warcraft 3 который использовал Lockstep, но Valve используют Клиент-Серверную модель для Dota 2.
- DOOM использовал Lockstep но Quake использует Клиент-Серверную модель, Lockstep вообще не пользовался популярностью в FPS.
- MMO никогда не использовали Lockstep потому, что он неприменим для такого большого количества игроков.
Развитие программирования, удешевление компьютеров, и современная скорость интернета делают Клиент-Серверную легче применимой, чем Lockstep. Lockstep будет использоваться все меньше и меньше.
Комментарии (24)
OlegKozlov
07.09.2017 14:29Что мешает использовать Lockstep в клиент-серверной модели взаимодействия? Все клиенты выполняют детерминированную игровую модель и передают команды через сервер.
siziyman
07.09.2017 17:56Насколько я вас понял, это или а) не Lockstep в том представлении, в котором понимает/использует его автор, или б) создаёт простор для читерства — если у вас есть детерминированная модель, на стороне клиента можно её абьюзить.
Tarik02 Автор
07.09.2017 17:56-4Это и есть тот Lockstep, который описан в статье. Какая разница, как обмениваться данными: каждый между собой, или через сервер? Это убирает только один недостаток, который не является самым критическим.
mayorovp
08.09.2017 09:27Разница в том, что именно такой вариант Lockstep использует StarCraft 2, а вы его почему-то отнесли к клиент-серверным.
rkfg
07.09.2017 16:04+1В Factorio используют Lockstep, но там наверно без него и не получится, слишком большой масштаб всего.
wataru
07.09.2017 17:20На сколько я помню, там были проблемы при большом количестве игроков, поэтому они перешли на микс из lockstep и клиент-серверного решения. Все клиенты выполняют одни и те же команды, но передают их друг-другу через сервер.
rkfg
07.09.2017 17:33+1Да, сервер выделенный есть, но lockstep всё же более важный аспект, чем p2p (который был в упомянутых в статье играх, скорее, как дань времени, когда выделенные серверы были дороги и сложны в установке). Десинки в Factorio нередки на экспериментальных версиях, а ещё они почему-то случаются с некоторыми модами. Казалось бы, моды работают на куда более высоком уровне абстракции, чем движок, но вот такая ситуация.
А проблемы там не только при большом числе игроков, но и в самом масштабе симуляции: по конвеерам ездят тысячи объектов, передавать все их данные даже на 10 UPS — это прорва трафика, и оптимизации с группировкой объектов в батчи вряд ли сильно улучшат ситуацию. Так что даже если использовать клиент-серверную модель для игроков, байтеров и поездов, фабрику всё равно надо симулировать локально. А раз 90% игры использует lockstep, чего уж переусложнять остальное.
mayorovp
08.09.2017 06:43Казалось бы, моды работают на куда более высоком уровне абстракции, чем движок, но вот такая ситуация.
Моды в Factorio могут менять состояния любых игровых объектов. Если это сделать на разных хостах не синхронно — то и получится десинхрон. В этом плане Factorio куда меньше продумана чем, к примеру, Warcraft 3, где десинхрон "официально" могла вызывать лишь одна функция (GetLocalPlayer кажется).
rkfg
08.09.2017 09:14Ну моды всё же дёргаются игрой, и слежка за синхронизацией состояний — дело движка, а не модов. Хоть я и не знаю всех подробностей, но припоминается, что такие десинки в модах чинили именно на стороне движка.
mayorovp
08.09.2017 09:25Тем не менее, моды имеют доступ именно к "сырому" состоянию, и писать код так, чтобы он работал одинаково на разных компьютерах — задача именно автора мода.
ShadowTheAge
07.09.2017 17:53+1Lockstep и P2P это не связанные понятия.
В статье говорится про lockstep но рассказываются минусы как lockstep так и P2P.
В «примерах» про Starcraft написано что Starcraft 2 не использует lockstep, но в пруф статье написано что Starcraft 2 не использует P2P и ничего не написано про Lockstep.
Игра «Heroes of the storm» основана на движке SC2 и использует Lockstep.Tarik02 Автор
07.09.2017 18:21-2Ну почему не связанные? В Lockstep'е заложены принципы P2P — все игроки равноправны и все обмениваются данными, хотя сам P2P может вовсе не использоваться технически, а использовать сервер, который будет ретранслировать трафик между клиентами.
ShadowTheAge
07.09.2017 19:31+2Lockstep означает «У всех игроков есть полное игровое состояние и оно изменяется у всех одинаковым образом». Немного похоже на блокчейн.
Оно не означает что все игроки равноправны (Главное чтобы все знали кто из игроков «равнее»), не означает что нет центрального сервера (Эталонная симуляция, все кто с ней несогласны дисконнектятся)
У lockstep есть проблема принципиальной невозможности скрытия информации.
И есть плюс в виде что количество передаваемых по сети данных — это О(количество игроков), тогда как у несинхронных систем — О(количество объектов).
Если в игре количество игроков и объектов сравнимо (например шутеры) — в нем нет смысла. А если несравнимо — есть.
Еще lockstep позволяет бесплатно получить реплеи.
Starcraft 2 и warcraft 3 точно используют lockstep но без P2P.Tarik02 Автор
07.09.2017 19:58-3Эталонная симуляция, все кто с ней несогласны дисконнектятся
Ну тут не очень хорошо так делать… а вдруг какая-то неплановая рассинхронизация(баг в коде): тут бац, тебя выкинуло.
А вообще, как по мне, сейчас очень хорошое подобие Lockstep'а в игре Clash Royale(только вот сервера официальные): по сети гонятся только где ставится какой юнит, а также чексуммы от сервера до клиента. Если клиент видит, что чексумма не совпадает — просит полный статус карты от сервера(что случается крайне редко).
Tarik02 Автор
07.09.2017 19:59Если в игре количество игроков и объектов сравнимо (например шутеры) — в нем нет смысла. А если несравнимо — есть.
Далеко не во всех шутерах количество объектов равно количеству игроков(особенно если много снарядов)
BigD
08.09.2017 13:35Оффтоп: люди, посоветуйте плиз хорошие RTS под windows, которые пойдут на слабом железе (Core i5, интегрированная карта Intel Graphics HD 5500)
Sladkozub
08.09.2017 21:22Понравилась деталь: написание «DotA» и «Dota 2».
Я бы даже лойс поставил за такую педантичность и внимательность, но, насколько я понял, я смогу поставить только когда сам наберу определенное количество в копилку.Tarik02 Автор
08.09.2017 21:25Только сейчас заметил, что в оригинале используется «Dota 1», а я перевел как «DotA». Я сам не поклонник Warcraft и DotA/Dota2(в них вообще не играл), но недавно интересовался, что это за игра и почему она такая популярная.
Sladkozub
10.09.2017 00:43Нет, Вы верно написали.
Первая дота была просто (модифицированной) картой в WarCraft III. Расшифровывается как "Defense of the Ancient", поэтому верное написание аббревиатуры — "DotA".
Во второй доте, уже отдельной игре, об этом успешно забыли, и в Steam пишется "Dota 2".
Так что, Ваш перевод получился в этом месте лучше оригинала :) спасибоTarik02 Автор
10.09.2017 11:01Спасибо. Valve не просто забыли про название, а они практически «создали» слово Dota.
FadeToBlack
Ну… ок, не буду, спс.