Solução de rede otimizada (Unity) para muitos objetos em movimento

8

Atualmente, estou empreendendo um projeto bastante ambicioso. Em suma, é um jogo de estratégia multiplayer em tempo real que possui mecânica de bactérias.

Essencialmente, eu tenho dois jogadores remotos no ambiente, e eles podem gerar unidades semelhantes a bactérias que se atacam e se multiplicam, duplicando-se até que um limite de recurso seja atingido. Isso geralmente resulta em mais de 200 objetos de jogo renderizados na tela, cada um com seu próprio estado e movimento. Parece ruim, mas a jogabilidade local contra um bot é realmente muito boa, e eu consegui fazer com que ele tivesse um bom desempenho.

No entanto, o problema surge quando tento criar um jogo em rede. Já tentei seguir este guia para implementar esse recurso: http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/

Isso produz uma experiência de jogo bastante lenta e desagradável, mesmo com a melhor latência. Provavelmente, isso é causado pela necessidade de transmitir dados de movimento para centenas de unidades.

A pergunta que estou fazendo:

Como otimizar a rede e a sincronização de muitas unidades móveis entre dois clientes?

Eu já pensei em uma maneira de fazer isso. Depois de gerar uma unidade, eles só viajam em uma direção até atingirem algo - talvez eu possa sincronizar apenas quando as unidades são geradas e quando elas interagem com outro objeto? Isso teria muito benefício? Qual é a maneira ideal de implementar isso?

Agradecemos antecipadamente por respostas!

Rachel Cabot
fonte
É provável que um modelo de passo a passo seja o que eu preciso? clintonbrennan.com/2013/12/lockstep-implementation-in-unity3d
Rachel Cabot
Estou atrás de um firewall e não consigo acessar o exemplo que você vinculou, mas você tentou serializar apenas os vetores de ID, posição e velocidade de objeto a cada quadro? Dependendo da inteligência do algoritmo de serialização, você pode reduzir as informações de estado para 7 bytes por objeto. Se você garantir que o cliente assuma um ID ausente da atualização como uma morte e novos como uma desova, não deverá ter problemas.
10139 Stephan

Respostas:

1

Para mais de 200 objetos em movimento, você definitivamente vai querer fazer o seu jogo travar. Com o locktep, surge a necessidade de determinismo, mas isso não deve ser muito difícil para as bactérias (que podem ser simuladas com colisões círculo-círculo).

Se você não se importa com meu auto-plug descarado e deseja um exemplo com a lógica de rede e simulação de um jogo de bloqueio, confira este recurso gratuitamente: https://www.assetstore.unity3d.com/en/#!/ content / 36206 . Infelizmente, essa versão não inclui todo o código-fonte, mas sinta-se à vontade para cortá-lo com minha benção;). Aqui está um vídeo de um teste inicial do DPhysics: https://www.youtube.com/watch?v=NEzOghxfMdU .

A essência do lockstep está sincronizando a entrada em vez da saída. Isso ocorre porque, com uma simulação síncrona, a única coisa que todos os clientes desconhecem são as entradas de outros clientes. O artigo que você vinculou no seu comentário explica muito bem. Não tenho certeza de como você gostaria que eu explicasse o passo a passo, então cortarei aqui e expandirei esta resposta se tiver mais alguma pergunta.

Atualização: pense nele como um servidor autorizado, exceto que o servidor envia entrada em vez do estado do jogo. Como todo jogador pode produzir o estado do jogo para si mesmo a partir da entrada, não há necessidade do servidor distribuir o estado do jogo.

JPtheK9
fonte
11
Essa abordagem pode levar à dessincronização, mesmo que tudo seja determinístico, apenas por causa da latência entre as entradas que estão sendo compartilhadas. Como exemplo, considere um jogo em que os jogadores tentam bloquear o movimento de um objeto colocando paredes. Na tela de um jogador, ele pode ter cronometrado o posicionamento corretamente, e o objeto está bloqueado. Mas a replicação disso para o outro cliente pode chegar atrasada e, uma vez colocada a parede, o objeto já passou por esse local. Dependendo da mecânica do jogo, talvez seja necessário enviar periodicamente atualizações "gerais" para sincronizar novamente os clientes.
Acidictadpole
Bom ponto. Existe 0 potencial de dessincronização se isso for feito corretamente. Se um pacote for perdido ou chegar muito tarde, o cliente não poderá avançar para o próximo quadro - ele terá que esperar até que o pacote chegue para executar o quadro atual. Os quadros podem ser representados com números inteiros. O servidor distribui pacotes marcados com um número inteiro para cada quadro.
9788 JPYK9
Confira a lógica de rede e quadro por si mesmo.
9788 JPYK9
11
@ JPtheK9 "ele terá que esperar até o pacote chegar para executar o quadro atual" E se o pacote nunca chegar?
1013 Stephan
Peça um novo.
JPtheK9