Que dados trocar nos jogos multiplayer em tempo real?


8

Eu sou um programador amador e agora estou curioso sobre quais dados são trocados em uma sessão multiplayer em jogos em tempo real como o starcraft 2. Eu fiz várias pesquisas. Encontrei gafferongames.com oferecendo uma visão geral muito boa dos problemas a serem considerados.

Glenn, em seu artigo e comentários, oferece um argumento muito forte para o uso de UDP sobre TCP, mas o SC2 obviamente usa TCP. Para qoute Gleen,

O problema do uso do TCP para jogos é que, diferentemente dos navegadores da Web, e-mail ou da maioria dos outros aplicativos, os jogos multiplayer têm um requisito em tempo real na entrega de pacotes. Para muitas partes do seu jogo, por exemplo, entrada de jogadores e posições de personagens, isso realmente não importa o que aconteceu um segundo atrás, você se preocupa apenas com os dados mais recentes.

Portanto, a partir de sua declaração, acho que sua abordagem é enviar o estado completo do jogo de todas as unidades em cada quadro. Se o servidor não receber uma entrada do jogador no quadro atual, será apenas uma má sorte para ele. Para God of War: Acension, no qual ele é desenvolvedor de rede líder, isso deve funcionar muito bem, eu acho.

Para o SC2, devido à sua capacidade de reprodução, meu pressentimento me diz que o mecanismo subjacente é uma "máquina de reprodução de entrada de usuário" determinista, com timestamp fixo, onde os únicos dados trocados são as entradas do player . Daí a afirmação de Glenn ser completamente irrelevante para o SC2. A entrada do jogador é importante e a sequência de entrada é ainda mais importante. Eu não acho viável para o SC2 enviar o estado do jogo de 200 unidades e mais a 30 - 60 FPS.

Pergunta: Eu posso estar errado, mas tentei identificar dois tipos possíveis de dados. Quais são as outras técnicas? Será bom qoute o jogo, se você quiser.

EDIT: encontrou este link sobre o modelo de rede starcraft


11
Uma razão para muitos jogos usarem o TCP é simplesmente porque o UDP é frequentemente bloqueado.
Matsemann

Respostas:


12

Glenn, em seu artigo e comentários, oferece um argumento muito forte para o uso de UDP sobre TCP, mas o SC2 obviamente usa TCP.

Glenn fala principalmente sobre jogos baseados em física, ie. atiradores em primeira pessoa e jogos de condução. Eles têm requisitos diferentes dos jogos de estratégia em tempo real, onde são importantes posições precisas das unidades em cada etapa lógica. Portanto, as estratégias de comunicação são necessariamente diferentes.

"Tempo real" significa coisas diferentes em diferentes contextos. Os jogos não são "difíceis" em tempo real, pois, se uma mensagem chegar atrasada, tudo será interrompido. (Pelo menos, não há boas razões para um jogo ser tão exigente, pois um sistema somente de software deve poder se recuperar de atrasos no processamento, diferentemente de uma usina nuclear ou de um equipamento médico, por exemplo.) Os jogos são realmente tempo real 'suave' ou 'firme'. ( Definições na Wikipedia, como de costume .) O tipo de jogo faz a diferença na rapidez com que você precisa das informações, se pode perdê-las e se safar delas, etc. Basta dizer que o TCP é bom o suficiente para muitos jogos, mas para outros jogos, o UDP é preferível.

Eu estou supondo que sua abordagem é enviar o estado completo do jogo de cada unidade em cada quadro.

Ele enviaria informações suficientes para reconstruir o estado relevante do jogo de qualquer unidade que mudou.

  1. Você não precisa enviar nenhuma informação sobre algo que não foi alterado.
  2. Você não precisa enviar o estado completo se puder enviar informações suficientes para o destinatário construir o novo estado a partir do estado antigo. (por exemplo, basta enviar um valor delta em relação a um estado antigo. Ou apenas enviar as partes do estado que foram alteradas e não o restante.)
  3. Se dois jogos executarem exatamente o mesmo algoritmo e tiverem exatamente os mesmos dados, você poderá enviar entradas e o destinatário reativar os efeitos localmente para derivar o novo estado.

A maioria dos jogos não cumpre os critérios de 3, então eles usam 1 e 2. Muitos jogos RTS, no entanto, podem e fazem uso de 3.

Além disso, não precisa necessariamente ser "todos os quadros". O conceito de quadro também é nebuloso. É um quadro de renderização? É um lote de lógica? É um quadro de dados de rede sendo enviado? Os três sempre alinham um a um ou você obtém uma taxa gráfica variável com taxas lógicas fixas? Alguns jogos, especialmente jogos de estratégia em tempo real como Starcraft 2, ou jogos com capacidade de repetição (à medida que você toca) gostam de manter tudo em perfeita sintonia com atualizações regulares da rede (que podem ou não corresponder a 'quadros' em outros sentidos), mas isso não é um requisito para todos os jogos. Muitos jogos apenas enviam atualizações semi-regulares, dependendo de quanto tempo eles estão dispostos a deixar os clientes correrem.

A entrada do jogador é importante e a sequência de entrada é ainda mais importante. Eu não acho viável para o SC2 enviar o estado do jogo de 200 unidades e mais a 30 - 60 FPS.

Muitos jogos não necessariamente tratam um quadro de renderização como um quadro lógico. Eles podem ter 60FPS em gráficos, mas apenas 10 atualizações lógicas por segundo e enviar 1 atualização de rede para cada uma. Mas até 30 atualizações de rede por segundo são razoáveis ​​se você usar o método 'enviar entrada', certamente.

Eu tentei identificar 2 tipos possíveis de dados. Quais são as outras técnicas? Será bom qoute o jogo, se você quiser.

Não é tanto o fato de existirem técnicas distintas, mas várias restrições diferentes nos sistemas, e a importância de cada restrição varia de jogo para jogo. Então você só precisa escolher um sistema que funcione para você.

  • Poucas unidades, movendo-se de forma rápida e irregular pela entrada do usuário, a latência é sensível, a sincronização exata entre os sistemas não é importante - transmite posições por meio de um protocolo não confiável (por exemplo, UDP) para obter velocidade máxima e as mensagens perdidas não importam, como uma nova venha logo. Simule a física localmente para melhorar a qualidade da renderização, mas corrija as posições quando novas informações chegarem. Bom para atiradores e jogos de condução.
  • Muitas unidades, mas a maioria é irrelevante, e elas se movem lentamente - apenas enviam atualizações para as unidades próximas ao destinatário, enviam-nas como alterações em vez de estados completos, enviam-as com relativamente pouca frequência e enviam um protocolo confiável (por exemplo, TCP) para evitar se preocupar em como lidar com as atualizações perdidas. Bom para MMOs.
  • Muitas unidades, movidas pela IA com base na entrada anterior do usuário, são muito importantes na sincronização exata entre sistemas - enviam a entrada do usuário com carimbo de tempo por um protocolo confiável e são estimuladas localmente para que os algoritmos do jogo mantenham o estado sincronizado. Bom para RTSes e jogos baseados em turnos.

4

A principal técnica que você precisa conhecer é a técnica "1500 arqueiros". Foi famoso por Age of Empires, mas também é usado em outros jogos, como o OpenTTD (de código aberto) (baseado no Transport Tycoon Deluxe).

Para ser claro: usando esta técnica, você não precisa enviar QUALQUER estado do jogo enquanto estiver jogando. Todo o estado do jogo é enviado na inicialização, na conexão e na ressincronização. As únicas coisas que você precisa enviar regularmente são sinais de tempo e verificações de sincronização. Somente comandos do jogador são normalmente enviados do cliente para o servidor e vice-versa. Se um jogador não executar nenhum comando (como é o caso na maioria dos ticks), nenhum dado precisará ser enviado.

Veja este link.

http://www.gamasutra.com/view/feature/3094/1500_archers_on_a_288_network_.php

Atualização: Kylotan chama isso de "técnica 3" na resposta.


Sim, eu esqueci o link habitual dos 1500 Archers, então estou feliz que você tenha fornecido!
Kylotan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.