Resumo para quem não gosta de respostas longas ...
Isso pode ser feito, mas é impossível fazer uma física multiplayer perfeita, se houver alguma latência. Por que a latência afeta a física é explicada e, em seguida, são fornecidas dicas para reduzir o impacto da latência em sua simulação de física.
Criar um jogo de física multiplayer pode ser cheio de perigos. É impossível criar uma experiência física multiplayer "perfeita" online. Há coisas que você pode fazer para melhorar, mas não há como fazer uma física perfeita assumindo alguma latência.
O problema é que a física precisa ser rápida e responsiva para ser realista, mas ao mesmo tempo deve ser calculada com base nas ações combinadas de TODOS os fatores - significando as ações combinadas de todos os jogadores. E se houver latência, isso não pode ser feito em tempo real.
Cabe a você, como desenvolvedor, decidir se pode manter os diferentes fatores sob controle e entender que a experiência do jogador se degradará se a latência se tornar muito alta. Se você pode viver com isso (e seus jogadores podem), então vá em frente. Veja no final deste post algumas notas sobre como você pode manter as coisas funcionando de maneira mais suave.
Um exemplo para mostrar como as coisas podem ficar confusas
Imagine um jogo em que dois jogadores (clientes) estejam conectados a um servidor. Leva 100 milissegundos (1/10 de segundo) para que uma mensagem passe pela Internet do cliente para o servidor. Quando um jogador faz alguma coisa, uma mensagem é enviada ao servidor dizendo o que eles fizeram. O servidor então transmite a mensagem aos outros jogadores, para que todos saibam o que o jogador interino fez.
Agora crie um cenário em que dois jogadores tenham uma caixa no chão, que é um objeto de física. O jogador A bate de um lado, enviando-o em alguma direção. No entanto, ao mesmo tempo, o jogador B bate no outro lado, enviando outra direção.
Vejamos maneiras diferentes de lidar com isso e quais seriam os resultados ...
E se a física for calculada apenas no servidor?
Suponha que tenhamos a física calculada apenas no servidor. O jogador A envia a mensagem "Eu bati na caixa desta maneira" para o servidor, 1/10 segundo depois o servidor recebe a mensagem. O jogador B envia a mensagem "Eu bati na caixa dessa outra maneira". O servidor calcula a alteração física a partir da combinação das duas ações e envia uma mensagem de volta aos dois jogadores dizendo: "OK, ele se move dessa maneira". Física perfeita é realizada, com base nas ações de ambos os jogadores combinados.
Mas o problema é que levará dois décimos de segundo para que um dos jogadores veja a caixa reagir. As mensagens de ambos os jogadores levam 1/10 de segundo para chegar ao servidor e, em seguida, 1/10 de segundo para que os resultados do cálculo dos servidores sejam enviados aos dois jogadores.
Bottom line, jogabilidade atrasada.
E se a física for calculada apenas no cliente?
Suponha que tenhamos física calculada apenas no cliente. Vamos dar uma olhada no ponto de vista do jogador A. O jogador A bate na caixa e imediatamente começa a ir na direção deles. Uma mensagem também é enviada ao servidor informando o que o Jogador A fez.
Ao mesmo tempo, B fez o golpe e viu o caixote indo em sua direção e enviou uma mensagem ao servidor sobre o que eles fizeram.
2/10 de segundo depois, chega uma mensagem do servidor para os clientes. A é informado do que B fez, e B é informado do que A fez. O problema é que os dois clientes dizem: "Bem, o jogador X pode ter atingido esse ponto neste local, mas não há mais uma caixa nesse local, portanto o impacto não fez nada".
Resumindo, dois jogos estão fora de sincronia e os jogadores não têm uma experiência compartilhada. Qual é o sentido do multiplayer se ambos vêem coisas diferentes?
E se a física for calculada no cliente e no servidor?
Nesse caso, a física é calculada no cliente para que os jogadores vejam uma reação imediata sem atraso, mas também é calculada no servidor para que seja "correta" para todos os jogadores.
Ambos os jogadores acertam o engradado em suas respectivas direções e cada um vê o engradado se mover com base apenas no acerto. Mas, então, 2/10 de segundo depois, o servidor volta e diz: "Bem, na verdade, vocês dois estão errados. A caixa foi por esse caminho". De repente, ambos os jogadores vêem a caixa mudar drasticamente de direção e se mover para um novo local.
Bottom line é, um jogo glitchy.
Conclusão
Basicamente, não há como fazer um jogo de física perfeito com vários jogadores quando existe algum tipo de latência. Você pode fazer um jogo muito bom, mas sempre terá o risco de latência excessiva, criando uma experiência ruim para alguns jogadores. No entanto, existem coisas que você pode fazer para manter uma experiência de jogo agradável.
O que você pode fazer para que um jogo multiplayer corra bem
Use volumes de colisão simples. Não se preocupe em modelar todos os detalhes de uma forma com a física quando uma forma simples de cubo for adequada. Uma bola de espigão não precisa ser modelada como uma bola de espigão para a física. Em vez disso, apenas modele-o como uma esfera.
Crie pequenos objetos inconseqüentes itens somente para o cliente. Um exemplo pode ser pedaços de vidro quebrado de uma janela quebrada. Você pode permitir que cada cliente simule por conta própria, e isso realmente não importa se eles são diferentes.
Crie objetos físicos apenas se eles precisarem ser objetos físicos para manter baixo o número de objetos físicos ativos.
Execute seu jogo em câmera lenta ao fazer física para vários jogadores. Pense em "tempo de bala", talvez. Jogos em câmera lenta compensam a latência e permitem que vários jogadores interajam com a física juntos.
Permita que os jogadores configurem uma situação de algum tipo juntos, e então, de alguma maneira, a física é simulada para ambos os jogadores e ambos assistem ao resultado de suas ações combinadas. Os jogadores não podem interferir com a sequência até que ela seja concluída.
Jogadores físicos separados para que eles não possam interferir um com o outro. Isso seria ótimo para um jogo como boliche ou sinuca, onde apenas um jogador de cada vez tem controle ou cada jogador tem sua própria "caixa de areia" (como uma pista de boliche).
Se você não pode vencê-los, junte-se a eles e faça com que o atraso na física faça parte do seu jogo. Imagine uma história sobre estar em um universo glitchy com leis de física violadas ou algo do tipo :)
Apêndice: Como os jogos de tiro lidam com isso
Os jogos de tiro lidam com isso não fazendo física excessivamente complexa. Eles usam efeitos colaterais do cliente para que os jogadores vejam as coisas rapidamente, mas o servidor faz a chamada final sobre o que aconteceu.
Imagine um cenário em que o jogador A atire no jogador B. Seu jogo de tiro típico fará algo assim ...
- A calculará localmente se eles acertarem B e, se parecer que houve um golpe, ele executa um efeito de "golpe" como uma baforada de sangue. Isso é feito do lado do cliente para que o jogador veja imediatamente uma reação à sua ação. Se você não fizer isso, o jogo parece lento.
- A também envia uma mensagem ao servidor dizendo: "Eu atirei nesse vetor"
- Quando o servidor recebe a mensagem, ele analisa onde a equipe de TI pensa que estão os jogadores e decide se o vetor de tiro de A atinge B.
- Se o servidor decide A hit B, decide que B é atingido e envia uma mensagem para os dois clientes dizendo o que aconteceu.
- Se o servidor decidir que A NÃO atingiu B, B está bem e A "falha". Pode parecer que A bateu ("Eu vi o sangue soprar!"), Mas são os servidores que eles perdem.
Então, como A miss B pode parecer que eles os atingiram? Porque B pode ter sido movido, mas A ainda não o viu porque o servidor ainda não enviou uma mensagem "B mudou-se para aqui" para o cliente.
A Valve tem uma boa descrição em seu site sobre isso. Consulte http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking