2009-05-01 2 views
15

Для автономных игр, основной цикл игры (источник: Википедия)Алгоритм для клиент-серверных игр

while(user doesn't exit) 
    check for user input 
    run AI 
    move enemies 
    resolve collisions 
    draw graphics 
    play sounds 
end while 

Но что, если я разрабатываю клиент-сервер-подобные игры, как Quake, Ragnarock, Trackmania, и т. д.

Что такое Loop/Algorithm для клиентских и серверных частей игры?

ответ

19

Было бы что-то вроде

Клиент:

while(user does not exit) 
    check for user input 
    send commands to the server 
    receive updates about the game from the server 
    draw graphics 
    play sounds 
end 

Сервер:

while(true) 
    check for client commands 
    run AI 
    move all entities 
    resolve collisions 
    send updates about the game to the clients 
end 
+0

Ninja-psych! +1 – GWLlosa

3

Клиентская часть в основном такая же, за исключением замены

run AI 
move enemies 
resolve collisions 

с

upload client data to server 
download server updates 

И сервер просто делает:

while (game is running) 
{ 
    get all clients data 
    run AI 
    resolve collisions 
    udpate all clients 
} 
3

Вы можете использовать почти то же самое, но большинство из вас логика будет на сервере, вы можете поставить таймеры, звуки, Графика, и другие компоненты пользовательского интерфейса в клиентском приложении. Любое бизнес-правило (AI, Movements) идет на стороне сервера.

4

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

while(user doesn't exit) 
    check for user input 
    run AI 
    send location to server 
    get locations from server 
    resolve collisions 
    draw graphics 
    play sounds 
end while 

Однако необходимо учитывать задержки, так что вы действительно не хотите, чтобы приостановить основной цикл с призывами к сети. Для того, чтобы преодолеть это не редкость увидеть сетевой двигатель, сидя на втором потоке, опроса для данных с сервера так быстро, как это возможно и размещение новых местоположения объектов в общее пространство памяти:

while(connectedToNetwork) 
    Read player location 
    Post player location to server 
    Read enemy locations from server 
    Post enemy locations into shared memory 

Тогда ваш главный цикл будет выглядеть следующим образом:

while(user doesn't exit) 
    check for user input 
    run AI 
    read/write shared memory 
    resolve collisions 
    draw graphics 
    play sounds 
end while 

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

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

while (PlayerConnected) 
    Wait for player to post location 
    Place new location in shared memory 

Когда клиент аппарат запрашивает расположение врагов сервер считывает все остальные игроки места из общего блока памяти и отправляет его обратно.

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

12

Client:

connect to server 
while(user does not exit && connection live) 
    check for user input 
    send commands to the server 
    estimate outcome and update world data with 'best guess' 
    draw graphics 
    play sounds 
    receive updates about the game from the server 
    correct any errors in world data 
    draw graphics 
    play sounds 
end 

сервер:

while(true) 
    check for and handle new player connections 
    check for client commands 
    sanity check client commands 
    run AI 
    move all entities 
    resolve collisions 
    sanity check world data 
    send updates about the game to the clients 
    handle client disconnects 
end 

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

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

Существует также множество вопросов, касающихся разделения разделов этих процессов на отдельные потоки для оптимизации времени отклика.

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

1

Очень полезный, и я бы сказал, соответствующую бумагу, чтобы прочитать это один: Client-Server Architectures

Я дал ему читать и многое узнал от него, было сделано много смысла. Разделив свою игру на стратегически определенные компоненты или слои, вы можете создать более удобную архитектуру. Программа легче кодировать и более надежную, чем обычная линейная программная модель, подобная той, которую вы описали.

Этот мыслительный процесс появился в предыдущем посте об использовании «общей памяти» для разговора между различными частями программы и, таким образом, преодоления ограничений наличия единого потока и логики игрового процесса с последующим шагом.

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

tldr; прочитайте его.

Смежные вопросы