Difs de estado de envio (deltas) e conexões não confiáveis

8

Estamos criando um jogo multiplayer em tempo real, no qual cada jogador é responsável por relatar seu estado em todas as iterações do ciclo do jogo.

As atualizações de estado são transmitidas usando UDP não confiável .

Para minimizar o envio de dados de estado, criamos um sistema que enviará apenas deltas (quaisquer que sejam os dados de estado que foram alterados).

Este método, no entanto, é falho, pois um pacote perdido significa que outros jogadores não receberão o delta, fazendo com que o jogo se comporte de maneira inesperada.

Por exemplo:

Suponha que o estado seja composto por: {positionX, positionY, health}

Frame 1  - positionX changed --> send a packet with positionX only.
Frame 2 - health changed // lost !
Frame 3 - positionY changed --> send a packet with positionY only.

// Outros jogadores não sabem sobre mudanças de saúde.

Como alguém pode superar esse problema então? nem sempre é possível enviar dados completos.

spaceOwl
fonte

Respostas:

7

Mesmo que você esteja enviando dados usando o UDP, você ainda precisará adicionar sua própria forma de confiabilidade para lidar com situações como essa. O UDP apenas oferece a flexibilidade de fazer o que você deseja, em vez de lidar com o formato confiável, mas menos flexível da comunicação TCP. Mensagens de confirmação ou pacotes de reconhecimento de uma classificação devem ser usados ​​quando o recebimento de informações for necessário; caso contrário, seu cliente não terá como saber se os dados enviados precisam ser reenviados. Por exemplo, se você enviar informações críticas e não receber uma resposta dentro de um período definido, confirmando o recebimento desses dados, reenvie-os.

Evan
fonte
2
Bata-me para isso. No entanto, deve-se notar que valores bastante voláteis, como posição e outros dados físicos, não precisam ser garantidos. Mesmo com a chance de estar errado em um determinado quadro, ele será corrigido de qualquer maneira.
jmegaffin
11
Bom ponto, isso é visto com mais frequência nos jogos quando, de repente, um personagem se muda para um novo local muito rapidamente (ou se teleporta para lá todos juntos). A maioria dos jogos lida com isso de maneiras diferentes, mas o objetivo é o mesmo. O servidor simplesmente atualizou a posição da entidade e seu cliente está atualizando imediatamente ou atualizando-o com um tempo delta muito alto em alguns quadros.
Evan
3

Você também pode solucionar o problema enviando uma atualização de estado completa do servidor para os clientes, digamos a cada segundo. Se um cliente não recebeu um pacote, ele se comportará incorretamente até receber a atualização completa do estado. Em seguida, ele estará sincronizado novamente.

Matthias
fonte
3

Muitos jogos usam UDP e TCP / IP para enviar / receber dados e, dependendo da frequência com que os dados são enviados, um protocolo diferente é usado.

Por exemplo:

UDP: atualizações posicionais e qualquer outra coisa que possa ser enviada / recebida várias vezes por segundo.

TCP / IP: ações de inventário, ações de feitiço / habilidade (a maioria das ações executadas pelo usuário)

Realmente depende da quantidade de tráfego de cada item. Se você achar que está enviando atualizações da HP com bastante frequência, talvez elas precisem estar no UDP.

UnderscoreZero
fonte
11
O TCP geralmente não é usado para qualquer coisa que exija precisão em tempo real, porque sua capacidade de causar grandes picos de atraso.
TheNickmaster21
É bom se você quiser garantir que seu pacote chegue lá. Coisas como atualizações posicionais não são boas para isso, mas se você quiser ter certeza de que o usuário pressionou um botão em um horário específico, o TCP lida com toda a verificação de erros e outras coisas que você teria que implementar no UDP para evitar a perda de pacotes.
carregar
Ponto válido; Eu preferiria modificar o UDP.
TheNickmaster21
1

Se você ler a revisão do código-fonte do Quake 3 , ele explica o modelo de rede que é muito semelhante ao seu design, mas com uma solução para os pacotes descartados.

Essencialmente, no seu modelo você está enviando deltas contra o estado diretamente anterior. No modelo quake3, você envia deltas contra o último estado reconhecido do par.

minismo
fonte