Eu tenho 2 a 3 clientes, que podem trocar mensagens através do Apple Game Center.
A única sincronização que eu preciso é: inicie o jogo no mesmo momento.
Eu acho que isso envolve sincronização de relógio. Como conseguir isso?
networking
multiplayer
game-center
GameCoder
fonte
fonte
now
e você enviar uma mensagem para começar exatamentenow + halfSecond
então, desde que todos recebam a mensagem em meio segundo e, enquanto os relógios do sistema estiverem sincronizados corretamente, todos serão iniciados ao mesmo tempo.Respostas:
O comentário de Steven está certo: isso é teoricamente impossível de fazer.
Felizmente, na prática, você pode se aproximar, e é assim que coisas como o NTP funcionam.
Por exemplo, melhor do que apenas enviar uma mensagem para três clientes dizendo "iniciar agora", você pode trocar algumas mensagens de ping com antecedência para medir o tempo que leva para receber uma mensagem para o cliente e, quando você envia a mensagem inicial, em vez de "iniciar agora", diga "iniciar em X milissegundos" e ajuste X para os diferentes momentos necessários para que uma mensagem chegue.
por exemplo.:
Isso não pode garantir a sincronização porque o tempo gasto para enviar uma mensagem pela Internet varia e porque pode ser diferente em cada direção. Na primeira, você pode reduzir os efeitos realizando a medição várias vezes e fazendo uma leitura mediana. O segundo é mais complicado e pode ser teoricamente impossível de resolver (embora não me lembre da prova no momento). A boa notícia é que você provavelmente não precisa de tanta precisão.
fonte
Como mencionado, isso é impossível, então eu tentaria outra abordagem:
Se você não tiver um servidor dedicado, escolha um cliente participante para se tornar o host (isso pode ser transferido se necessário).
O host agora executará toda a lógica importante do jogo, como detecção de hits, controles de IA, manipulação de inventário etc., bem como rastreamento de tempo (por exemplo, ditar o tempo do jogo).
Os outros clientes apenas tentarão permanecer sincronizados com o host, tentando estimar ou aproximar o valor esperado. Se o atraso aumentar ou houver perda de pacotes, as coisas podem ficar instáveis, mas é trivial recuperar o atraso, basicamente apenas aguardando a próxima atualização.
A maioria dos jogos (especialmente o FPS) oculta esse fato fazendo seu próprio cálculo local para o próprio movimento do jogador, tiros sendo disparados etc. para evitar que o jogo fique lento. Tudo ainda é corrigido com base nos dados do servidor. Isso pode levar a alguma confusão, por exemplo, você se vê atirando no inimigo, mas no mesmo momento em que cai morto (sem que o inimigo seja atingido), mas ainda é uma abordagem muito melhor do que a sincronização completa.
Se você ainda insistir em manter tudo em sincronia, provavelmente desejará criar algum tipo de etapa ou contador de quadros, para que todos os clientes processem apenas uma etapa lógica e depois sincronizem seus dados, etc. Lembre-se de que essa pode ser a largura de banda intensivo e lento, então eu não recomendaria fazer isso, a menos que você tenha muitos dados e sua jogabilidade seja baseada em turnos (por exemplo, jogos no estilo de artilharia / worms).
fonte
Eu recomendo sincronizar os cronômetros do sistema em todos os clientes e no servidor por meio do protocolo NTP [Stratum 2]; o servidor envia um comando para iniciar o jogo no horário especificado, por exemplo, quando todos os cronômetros atingem 0:05:00. Essa abordagem deve fornecer uma sincronização precisa de 3-4 ms, acredito.
fonte