Estou tentando implementar um sistema físico de cliente / servidor usando o Bullet, mas estou tendo problemas para sincronizar as coisas.
Eu implementei um estado de movimento personalizado que lê e grava a transformação dos meus objetos de jogo e funciona localmente, mas tentei duas abordagens diferentes para jogos em rede:
- Objetos dinâmicos no cliente que também estão no servidor (por exemplo, detritos não aleatórios e outras coisas sem importância) são tornados cinemáticos. Isso funciona corretamente, mas os objetos não se movem muito bem
- Os objetos são dinâmicos nos dois, mas após cada mensagem do servidor que o objeto foi movido, defino a velocidade linear e angular para os valores do servidor e chamo btRigidBody :: continueToTransform com a transformação no servidor. Também chamo btCollisionObject :: enable (true); para forçar a atualização do objeto.
Minha intenção com o método 2 era basicamente fazer o método 1, mas seqüestrar o Bullet para fazer a previsão de um pobre, em vez de fazer o meu para suavizar o método 1, mas isso não parece funcionar (por razões que não são 100% claras para eu mesmo percorrendo Bullet) e os objetos às vezes acabam em lugares diferentes.
Estou indo na direção certa? O Bullet parece ter seu próprio código de interpolação embutido. Isso pode me ajudar a melhorar o método 1? Ou meu código do método 2 não está funcionando porque estou acidentalmente pisando nisso?
EDIT: Outro problema com o método 1 que acabei de notar é que a resposta à colisão estará muito longe de colisões contra objetos não sincronizados. Os corpos cinéticos meio que disparam coisas até o infinito às vezes, uma vez que não podem ser repelidos.
fonte
Respostas:
Você precisa de uma previsão adequada do lado do cliente .
Você realmente deve ler em detalhes o link que Roy T. forneceu em seu comentário . Ele descreve o que fazer com a entrada do jogador e a física dos personagens, mas o princípio permanece o mesmo para a "física orientada ao servidor".
Isso não é trivial de implementar, mas em poucas palavras, para objetos de jogo que precisam estar sincronizados:
Então, sim, você está caminhando na direção certa com o seu método 2. Porém, apenas sobrescrever os valores, você obterá saltos no cliente, o que você precisa fazer é interpolar de forma suave e contínua com os valores do servidor.
Para o seu bug atual, eu não estou familiarizado com o Bullet, mas você provavelmente está perdendo alguns valores, por exemplo, você definiu as velocidades linear e angular, mas definiu as acelerações?
fonte
O que eu faço pessoalmente é quem está hospedando o jogo, cria o mundo phsyics e sincroniza objetos com os clientes. Mesmo que seja um esquema de rede p2p, ainda baseio o mecanismo de física em um dos clientes dos jogadores.
Outra física que uso puramente como colírio para os olhos nem precisa ser sincronizada.
Em um protótipo que criei um tempo atrás chamado "boilerzerker", executei a física no host e os efeitos das partículas (também usando a física) não foram sincronizados em uma rede, mas independentes para cada cliente, porque eram agradáveis para os olhos.
fonte
É impossível implementar mundos de física síncrona em rede. Pequena diferença no passo N, diferença muito maior no passo N + 1 Você não pode aplicar forças ou impulsos para mantê-lo sincronizado e parecer realista.
Soluções: -
Você pode sincronizar apenas alguns objetos, como personagens ou carros de corrida, especialmente se eles forem cinemáticos. Mas a maior parte do mundo não estaria sincronizada para parecer realista.
Você pode ter mundos físicos no servidor e transmitir posições e velocidades de objetos para clientes.
fonte