Objetos enormes e estáticos, como o ambiente, são transmitidos do servidor para o cliente nos modernos jogos multiplayer?

18

Eu tenho um sistema autoritário, onde quando o jogador entra na partida, ele recebe todos os objetos já gerados - gerados em si (o cliente).

Se parece com isso:

  1. Client envia o token de acesso para o Server
  2. Client recebe a aceitação do Server
  3. Client muda a cena para a cena do jogo
  4. Serverenvia jogadores, caixas, objetos com os quais você pode interagir, para que eles clientpossam aparecer e exibi-los.

Mas e o objeto do solo? Por enquanto, tenho exatamente a mesma cena no servidor e no cliente - com um plano estático atuando como um piso. Atualmente, estou adicionando coisas novas, árvores, escadas e construindo coisas juntas.

Eu pensei - estamos bem. Mas o ambiente não deveria ser sincronizado também? Ser conectado de alguma forma? Propriedade do servidor?

Vamos dar League of Legends:

insira a descrição da imagem aqui

É um ambiente estático, provavelmente uma malha combinada (escadas, grama, paredes, loja). Mas ele realmente é mantido no cliente ou é enviado pelo servidor durante a tela de carregamento?

Jacob
fonte
11
Você pode até pensar nisso a partir do ponto em que pode adicionar skins personalizadas aos personagens e ao ambiente da liga. Você não os envia para corte, eles são exibidos localmente; portanto, faz sentido concluir que eles são armazenados e renderizados localmente. Além disso, eles não afetam a jogabilidade; se você está perguntando sobre colisões, eles são uma mistura de servidor e cliente, para que o jogador não possa trapacear e atravessar paredes.
Candid Lua _Max_

Respostas:

41

Na maioria das vezes, não, os ativos de arte de qualquer tipo não são enviados rotineiramente pela rede. Geralmente todos os clientes terão os mesmos ativos de conteúdo localmente. Pode haver código para garantir que esse seja o caso através da soma de verificação do conteúdo ou similar. Se você está preocupado com a violação de parte do conteúdo de seus clientes, é possível implementar um sistema semelhante.

O servidor pode enviar diretivas ao cliente indicando que ele deve exibir ou ocultar determinados ativos, mas não enviará os dados reais do ativo. Na prática, isso é muito desperdício e lento, e pode causar problemas reais com pessoas com dados limitados disponíveis.

Em certos casos, ativos menores podem ser transmitidos na íntegra se o ativo for de alguma forma considerado um "spoiler" ou qualquer outra coisa. Mas isso é incomum. Geralmente, o que você vê é que um jogo pode baixar novo conteúdo de um patch, ou o que for, mas isso só acontecerá uma vez, durante o processo de patch na inicialização. Não durante o jogo.


fonte
21
Observe que esta resposta aborda apenas ativos estáticos. Recursos dinâmicos / gerados por jogadores (por exemplo, blocos do mundo Minecraft ou logotipos de guildas do MMORPG que os jogadores podem carregar) terão que ser transmitidos. Mas mesmo assim, geralmente tenta-se minimizar a quantidade de dados necessária (para continuar o exemplo do Minecraft: enviando atualizações de blocos em vez de blocos inteiros, indicando apenas o tipo / estado e coordenada do bloco que foram alterados) e / ou armazenar em cache os dados no lado do cliente .
Hoffmale 19/07
@hoffmale Sim, bom argumento; a pergunta mencionou que a paisagem era estática no final, então não pensei em levantar esse ponto, mas é bom.
3
Se um ativo é um spoiler, geralmente ele está no cliente, criptografado e a chave de descriptografia é transmitida do servidor para o cliente quando o ativo é necessário.
Grant Davis
4
E, por exemplo, se você precisar colocar árvores aleatoriamente em um mapa, em vez de enviar as coordenadas das árvores para o cliente, ele enviará a semente (do gerador de números aleatórios) para o cliente.
Grant Davis
5

Depende de vários fatores, incluindo o tipo de jogo (eu assumo o RTS aqui, embora o MMO de mundo aberto também venha à mente). Um estado base do terreno local para o jogador é enviado na conexão ou faz parte dos ativos do cliente - pense em um jogo RTS no qual o mapa é enviado com o cliente ou é baixado antes do início do jogo.

De fato, a malha normalmente não seria enviada, como já estaria no cliente na maioria dos casos de RTS. O envio ou não do mapa de colisão, que é realmente crucial para manter os dois sincronizados , é outra questão. Mas na maioria dos RTS, isso seria novamente pré-armazenado no cliente.

Realmente, tudo depende do que o seu RTS envia, se você faz o download de mapas antes do tempo de jogo ou no momento em que o jogo começa.

Depois disso, existem algumas maneiras típicas de se manter sincronizado:

  • Os deltas são enviados ao cliente - a maneira mais comum e eficiente de manter o mundo local / cliente atualizado com o servidor;
  • Às vezes, as somas de verificação são enviadas do servidor para o cliente ou do cliente para o servidor para garantir que o estado mundial realmente corresponda;
  • Ocasionalmente, o estado completo é reenviado para ressincronizar o cliente - geralmente como resultado de preocupações técnicas, como desvio de ponto flutuante.
Engenheiro
fonte
4

Quanto à sua pergunta exata, não sei como o League of Legends lida especificamente com isso. Eu nunca joguei esse jogo, então não posso sugerir se ele precisa ou não.

Mas a resposta para sua pergunta, em geral, é bastante simples e direta:

Se os dados são estáticos e você tem certeza de que nunca será alterado (menos atualizações periódicas do jogo completo, mas separadas), por que você gostaria de enviar esses dados extras? Geralmente você tenta evitar o envio do que pode ser evitado. Envie dados apenas se essa comunicação for necessária .

Por outro lado, se os dados mudarem ao longo do tempo , ou se você apenas quiser deixar essa opção em aberto, você realmente tem alguma opção no assunto? Nesse caso, você deve enviar os dados. Caso contrário, o cliente não tem o que precisa.

Isso se aplica a todas as comunicações de rede, não apenas aos dados do terreno. Tudo .

Aaron
fonte
2

Não.

Eu fiz uma boa pesquisa sobre a fonte de League of Legends e tudo mais, incluindo modelos Champion, lojista, plano geral de mapas e criaturas fofas adicionadas após o fato (como o pequeno esquilo em algumas pedras e um caracol em rio) são mantidos no lado do cliente. O fato de o cliente possuir todos esses modelos é um dos motivos pelos quais o LoL possui muitos gigabytes.

Transferir todos esses dados do servidor para o cliente seria um inferno, sem mencionar o uso da largura de banda apenas para fazer tudo novamente no próximo jogo.

Então, como é resolvido então? Cada jogador envia apenas os dados que são importantes para outros jogadores no jogo para o servidor. Ninguém precisa saber se você tem 5 segundos restantes no tempo de espera Q ou se a Pele de Thresh do Terror Profundo cria bolhas para você. Coisas que são passadas no jogo são coisas como Vel'Koz escalou Q, Viktor se moveu para a esquerda, etc ...

Mais explicitamente, em relação à tela de carregamento, como você mencionou, coisas que acontecem existem coisas como patches intermediários, sobre os quais todos os jogadores precisam conversar com os servidores do motim antes do jogo começar, handshakes de conexão segura e protocolos anti-trapaça.

NOTA:

Se você quiser examinar as coisas que o cliente possui e, portanto, o servidor não passar por você, localize a pasta C: \ Riot Games \ RADS \ lol_Game_Client \ Projects (que pode ser um pouco ruim, me desculpe, eu ' estou trabalhando com memória insuficiente) e localize um descompactador de arquivos .RAF on-line. Então você pode ver todas as coisas armazenadas localmente, como carregar salpicos de tela e texturas de pele, até esqueletos campeões.


fonte
11
Parece que a maneira óbvia de implementar isso seria solicitar ao cliente (de um servidor de ativos dedicado) quaisquer ativos que ainda não tenham armazenado localmente e, quando os recebe, os adiciona (semi) permanentemente ao seu armazenamento persistente local no disco. Dessa forma, os ativos são baixados apenas uma vez e somente quando são realmente necessários. (Uma vez que esteja funcionando, uma otimização seria preencher previamente a loja local do cliente com ativos que provavelmente serão necessários. Isso reduziria o tempo de inicialização do jogo na primeira conexão, com o custo de aumentar o pacote instalador do jogo)
Jeremy Friesner
11
@JeremyFriesner Por que essa seria a maneira óbvia? Isso parece pior do que a implementação atual descrita nesta postagem, na qual você instala todos os ativos com antecedência, para que você os disponha imediatamente quando necessário. Pode dar certo para um jogo para um jogador, embora eu ache que muitas pessoas prefiram um tempo de instalação mais longo (e mais uso de espaço em disco) do que ter que esperar constantemente pelo download de novos ativos durante o jogo.
Anthony Grist
2
Para um jogo multiplayer? Desastre absoluto. Você não quer manter todos os outros jogadores esperando para iniciar o jogo, porque uma pessoa precisa fazer o download de alguns recursos que eles nunca precisaram até agora.
Anthony Grist
11
@AnthonyGrist É por isso que muitos jogos como o league of legends exigem que um jogador tenha todos os recursos do jogo baixados antes de entrar na fila para encontrar uma partida. Isso funciona muito melhor do que atrasar o jogo enquanto você espera por um grande ativo. Lembre-se de que, nesse gênero de jogo, os jogadores ficam empolgados com uma redução de 10 ms no ping e geralmente jogam com <50 ms de ping e podem dizer se isso aumenta para o intervalo de 100 a 150. Esperar para buscar um ativo durante um jogo seria um desastre em um MOBA ou FPS e, se acontecesse no momento errado, poderia até alterar o resultado de um jogo.
JustWannaFly
@AnthonyGrist (continuação) Acho que você poderia pensar assim. Em alguns jogos multiplayer / competitivos, os jogadores trocam um tempo maior de carregamento / correção / instalação por uma experiência de jogo mais em tempo real, solicitando que um cliente cuide de todas as atualizações e filas que entram. Isso faz com ativos apenas o jogador específico precisando tem que esperar a menos que (s) que ele está querendo participar de uma festa premade, então todos os jogadores no partido teria que esperar para entrar na fila para encontrar adversários
JustWannaFly
1

Um exemplo de onde isso não foi feito foi o Elder Scrolls Online, onde confiava no cliente sobre a altitude do nível do solo .

Os garimpeiros caíram ao nível do solo vários metros. Eles podiam então andar "embaixo" do terreno e extrair recursos de baixo sem serem vistos pelos PCs ou atacados por NPCs.

Edições semelhantes permitiram suavizar penhascos para que pudessem subir, remover ou rotear sob paredes estáticas, ver através de todos os objetos estáticos etc.

Essencialmente, o servidor confiava no cliente sobre a localização do jogador, o cálculo da colisão no lado do servidor para cada jogador contra todas as estatísticas seria bastante pesado.

Em jogos baseados em blocos como Furcadia, no entanto, é diferente: cada quadrado em que você se muda tem capacidade de locomoção no servidor, e o servidor não precisa confiar no cliente para nada: o servidor conhece e valida todos os movimentos e ações do usuário, e o cliente somente exibe a ação quando o servidor informa o resultado.

Dewi Morgan
fonte
11
TL; DR: Sempre assumir que o cliente é um mentir, enganar, bustard . Mas a validação de tudo o servidor reduz sua capacidade.
Draco18s