Lógica do jogo no servidor! Bom ou mal?


25

Atualmente, estou planejando um simples jogo multiplayer online. E aqui está a questão. Faz sentido criar toda a lógica do jogo no servidor e apenas enviar a entrada do cliente para o servidor? Quais são os prós e os contras ou há alguma razão para eu não fazer isso?

Respostas:


37

Você não deseja enviar a entrada do player para o servidor. O que você provavelmente quer fazer é enviar uma representação abstraída do que o jogador deseja fazer para o servidor e, em seguida, executar a lógica.

Da mesma forma, você não deseja necessariamente enviar tudo o que o cliente precisa fazer. Por exemplo, você pode enviar algum tipo de mensagem dizendo "NPC X morreu" e o cliente determina que animação / sons reproduzir. Coisas assim.

O truque é encontrar a linha na qual a largura de banda e o poder de processamento (no servidor) são superados, impedindo que as pessoas trapaceiem. Geralmente, você toma qualquer tipo de decisão autoritativa de mudança de jogo apenas no servidor e deixa todo o material visual auxiliar para o cliente.

Existem muitas perguntas mais específicas sobre esse tópico em todo o site. Por exemplo:

A detecção de colisão deve ser feita no servidor ou em cooperação entre cliente / servidor?

Quem faz os cálculos de IA em um MMO?

O host do jogo deve ser a autoridade ou outro cliente burro?


4
+1 Bata-me para isso. Além disso, dependendo do estilo do jogo, você pode querer / precisar fazer alguma previsão do lado do cliente.
John McDonald

14

Bem, você tem respostas, mas sua resposta real é "tente você mesmo". As coisas diferem de jogo para jogo.

Eu fiz alguns jogos multiplayer para algum curso de design de jogos em rede distribuído. O mais desafiador foi fazer um jogo de ação em tempo real, onde muitos jogadores se envolveram e enviaram informações como o inferno. Quando chega a esse ponto, tudo se torna problema. Como você vê o primeiro link enviado pelo Tetrat, até determinar um conluio se torna um problema. E você lerá termos como lag, interpolação, extrapolação, previsão ... Mas se você nunca se tentou codificar do zero, apenas aceitará essas palavras e não saberá o que elas realmente significam.

Minha recomendação é:

Etapa 1
Comece agora com um design baseado em servidor totalmente autorizado por enquanto. Como você disse, basta enviar as entradas do usuário ao servidor e deixar o servidor fazer tudo e os clientes obterem os resultados. Seu jogo funcionará totalmente consistente. Mas quando você olha para seus clientes, notará alguns atrasos, alguns problemas de teletransporte, não movimentos suaves ... etc.

Etapa 2
Comece a corrigir os problemas no lado do cliente. Os problemas de teletransporte, por exemplo. Seu personagem estava em (0,0) e o servidor disse que agora você está em (100,100). Seu personagem irá se teleportar para (100.100), o que não é legal. Aí vem a interpolação. Você deve ter um código no lado do cliente que deslize o caractere de (0,0) para (100, 100) de maneira suave. Sim, você moverá seu personagem de (0,0) para (100,100), mas com que rapidez? Por enquanto, você pode apenas usar a diferença de horário entre cada atualização do servidor. Se o seu servidor enviar 10 pacotes em um segundo, o que significa um atraso de 100 ms entre cada pacote.

etapa 3
Agora seu jogo já é bom para redes rápidas, onde há um atraso de (1 a 50) ms. Mas fica condenado se houver perda de pacotes, alta latência ou cálculo demorar muito no servidor ... ect. Nessas situações, você notará que quando pressionar a seta esquerda, verá seu personagem se movendo para a esquerda com um atraso de 200 ms. O atraso entre o pacote vai para o servidor, o tempo de cálculo e volta para você com sua última posição. Isso é ruim, a pior desvantagem do design autorizado pelo servidor. O jogador quer que seu personagem se mova para a esquerda assim que ele pressiona para a esquerda, você não pode fazê-lo esperar. Felizmente, o cliente também tem o mesmo código que o servidor. Por que não executá-lo no cliente imediatamente e corrigir o resultado final com a resposta do servidor? Isso é o que basicamente é a previsão de entrada. O cliente pressiona para a esquerda, o código ao seu lado o move para a esquerda, depois de algum tempo digamos 200 ms, a posição real vem do servidor e o cliente corrige sua posição com ele. Se tudo der certo, o cliente não notará nada, a "etapa 2" também nos ajudará com isso.

Bem, a net tem muitos tutoriais e coisas sobre esse assunto. Mas existem 2 que eu realmente gosto:

Realmente bom, cobre manchas escuras: rede multijogador do mecanismo da fonte de válvulas
Tipo de história, diversão para ler e vale a pena: 1500 arqueiros em 28,8 ,


3

Prós:

  • essa abordagem é mais (a maioria) prova de pirataria
  • você pode aplicar as atualizações mais facilmente
  • comunidade centralizada

Contras:

  • enormes requisitos de largura de banda
  • alguns usuários podem odiar essa abordagem (privacidade e outras coisas)
  • problemas com a jogabilidade local (LAN parties), singleplayer

Os problemas com a jogabilidade da LAN podem ser evitados fornecendo um servidor binário dedicado ou permitindo que um dos clientes atue como servidor. Uma solução que corrige os problemas de um jogador e da LAN seria hospedar um servidor de forma transparente no computador cliente (se for apenas um jogo para um jogador, não deve haver nenhuma diferença significativa no poder de computação entre essa abordagem e um binário tradicional). Isso pode não funcionar para todos os tipos de jogos
3Doubloons

2

A lógica do servidor também cria problemas de escalabilidade - você precisa fazer todo o trabalho para todos os clientes em seu servidor - versículos permitindo que cada cliente faça sua própria parte do trabalho total.


É engraçado quando eu fiz perguntas semelhantes aqui em 2016, todo mundo me disse "nunca confie no cliente".
Newguy 28/11/16

Depende do jogo, mas os clientes trapaceando não são uma preocupação séria, e os clientes trapaceando contra outros clientes honestos; o que quer que o servidor tenha feito para não confiar no cliente, os clientes honestos podem fazer isso.
Ddyer 02/12/16

2

Depende do jogo que você deseja criar e qual parte do jogo. Se estiver desenvolvendo um RTS (ou qualquer jogo com um modelo com bloqueio de bloqueio), você definitivamente deve enviar apenas a entrada e qual etapa de simulação a entrada foi recebida.

Se você quiser fazer um jogo de tiro, poderá usar as funções de entrada e abstratas. Se você tomar o Unreal Tournament 3 como o caso, eles criaram o multiplayer principalmente por meio de chamadas de função replicadas.
Para o movimento, eles pegam a entrada do jogador (compactada em um único bit para cada ação) rotação delta, aceleração e carimbo de data e hora e enviam para o servidor.
Para outros fins, como a arma que eles sincronizam quando você dispara (AFAIK, ainda não analisamos essa parte em profundidade).
Para valores mais estáticos / menos alterados, como integridade, eles enviam a variável ao cliente ou servidor, dependendo do que o programador especificou.

E para jogos não RTS, lembre-se da previsão do cliente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.