É possível que um servidor envie apenas uma área baseada em bloco para um cliente?

8

Para começar, eu tenho uma boa experiência em redes (hardware, roteadores, ex.), Mas muito pouco conhecimento além dos conceitos básicos de programação de rede. Isso pode parecer uma pergunta estúpida, mas eu quero saber no que estou me metendo enquanto estuda a implementação do multiplayer no meu jogo.

Estou criando um mundo baseado em blocos, que é gerado através de uma simples matriz 2D. Digamos algo como Mundo [100] [100], por uma questão de simplicidade.

Atualmente, o método de renderização processa apenas os blocos com base na resolução da janela, além de um bloco (para renderização suave durante o movimento.) Não importa o tamanho do mundo, (10x10, 1 milhão x 1 milhão), a renderização é perfeita no desempenho.

A jogabilidade precisa de nada mais do que saber o que está atualmente visível (renderizado na tela +1) e, possivelmente, ALGUMAS informações de peças em uma área ao redor do jogador.

Portanto, qualquer coisa mais enviada pelo servidor não seria a informação completa do bloco. Ex. Itens colocados no chão, tipo de terreno, árvores, etc. não seriam importantes na área fora da vista do jogador, mas seriam apenas o que o Cliente / Jogador precisa saber nesses ladrilhos. (Por exemplo, os "nomes recebidos" de Ultima Online, onde os jogadores podiam conhecer um personagem [jogador ou monstro], estavam além dos ladrilhos em sua exibição renderizada.)

Eu não sei muito sobre redes, então talvez, ao descobrir isso, possa responder à minha pergunta. No entanto, estou curioso para saber se essa é uma solução viável ou se a idéia é simplesmente risível.

As informações enviadas seriam sobre uma área de 10x15 de blocos e cada bloco contém informações sobre o que está no bloco. Mais eficientemente, tudo seria um Objeto, onde o bloco contém todos os Objetos no bloco. Ex. Lado a lado [4] [4] contém Espada # 23452, Pedra2, Árvore5, Jogador3, Monstro4.

Ladrilhos vazios não enviariam nada além do tipo de terreno [Grama, Areia, Água] se ainda não estiver carregado durante a Inicialização / Carregamento. Algumas peças teriam um punhado de objetos [Árvore2, Espada # 924, Ouro, Cadáver, Rocha3].

Portanto, não consigo imaginar que um bloco tenha muitas informações para enviar ao cliente do servidor, pois o cliente precisa conhecer apenas a textura que precisa ser carregada e a posição para colocá-lo na tela. Posicione sendo apenas dois números inteiros e Texture sendo um número inteiro para uma lista de arquivos a serem solicitados ao cliente para renderização.

Na pior das hipóteses, o Servidor teria que enviar 150 blocos com informações de apenas um punhado de Objetos OnLOAD e, a partir de então, atualizar apenas alterações em blocos (se houver) e novos blocos (10 a 15 sempre que um jogador se mover em uma direção) ) e a direção do movimento dos caracteres na tela (para que o cliente possa simular movimentos suaves entre peças).

Suponho que estou certo ao pensar que se trata de uma quantidade incrivelmente baixa de informações enviadas pela Internet ou entre colegas, por isso deve ter pequenos problemas de desempenho, mesmo em conexões atrasadas? Ou sou tão ignorante em relação a redes que minha mente ficará abalada quando finalmente abrir meu livro sobre redes para vários jogadores?

Se houver uma quantidade muito baixa de informações sendo enviadas entre Cliente / Servidor, faria mais sentido simplesmente carregar o mundo inteiro na inicialização? Ou 'Mapa' se o mundo for excessivamente grande. E depois de LOAD, envie apenas blocos que são atualizados?

Ainda estou pensando em como devo lidar especificamente com dados. O livro que estou usando como referência deseja que eu tenha uma Lista Vinculada, onde adiciono e removo objetos, para que tudo seja booleano. "Existe um personagem? Existe uma árvore?"

Eu estava pensando em uma abordagem diferente, como um contêiner que contém objetos e a lógica do servidor que envia apenas o necessário para informar ao cliente o que renderizar. Possivelmente com objetos que contêm informações de rede em si, que são enviadas quando solicitadas pelo servidor.


fonte
Eu sugiro que você dê uma olhada no freemmorpgmaker.com, esse mecanismo me ajudou muito quando eu comecei. O script é relativamente simples e divertido de se trabalhar. O código me ensinou tudo o que eu precisava saber para criar meu próprio jogo / mecanismo 2D. O que você não deve aprender com eles é como proteger seu servidor / cliente.
Nick

Respostas:

6

Você está no caminho certo.

Considere o Minecraft. O Minecraft carrega apenas as áreas (também chamadas de pedaços) imediatamente ao redor dos jogadores. É assim que o servidor pode executar sem ficar sem memória e por que os clientes não ficam atolados no tráfego de rede.

Se houver uma quantidade muito baixa de informações sendo enviadas entre Cliente / Servidor, faria mais sentido simplesmente carregar o mundo inteiro na inicialização? Ou 'Mapa' se o mundo for excessivamente grande. E depois de LOAD, envie apenas blocos que são atualizados?

É exatamente isso que você deve fazer. Envie apenas os dados que você precisa enviar.

  1. Quando um cliente entra, envie um pedaço do mapa de blocos (ou todo, se estiver, se você estiver lidando com pequenas áreas)
  2. Quando o jogador tentar modificar um bloco, envie esses dados para o servidor.
  3. Quando um bloco muda de estado, envie um pacote com essas informações a todos os clientes relevantes.

Se você está apenas enviando uma matriz 2D de IDS de bloco, o tamanho dos dados pode ser muito baixo, especialmente se você tiver menos de 256 tipos diferentes de bloco. Nesse caso, você pode usar um único byte (ou caractere não assinado). Então, se você estiver enviando 100x100 blocos para o jogador, e cada bloco consiste apenas em um único byte ... Você entendeu. Não são muitos dados.

A comunidade Minecraft fez um trabalho maravilhoso ao documentar seu protocolo: http://mc.kev009.com/Protocol

http://www.minecraftwiki.net/wiki/Classic_server_protocol

Nick Caplinger
fonte
11
Uau, muito obrigado! Este é um grande impulso de confiança que me disseram que estou no caminho certo, quando sei tão pouco. Isso me diz que estou entendendo as coisas corretamente e desenvolvendo o melhor que posso. Estou confiante de que, se continuar aprendendo, farei o suficiente. É tão satisfatório ouvir conselhos positivos, e não "Você está fazendo errado!" lol :)
Demorei muito tempo antes de reunir coragem para jogar jogos multiplayer e 3D. :)
Nick Caplinger
Além disso, conselhos positivos são o que essa comunidade vive. Encorajo todos a contribuir da maneira que puderem!
precisa saber é o seguinte
3

Geralmente, é uma boa idéia enviar apenas as informações para o cliente, que devem ser mostradas ao jogador. Seguir esse princípio reduz o tráfego na rede e evita trapaças.

Mas lembre-se de que quando o jogador move seu personagem, você certamente deseja iniciar a jogada no lado do cliente antes de receber a confirmação do servidor para fazer com que o jogo pareça menos lento e mais responsivo. Isso provavelmente significa que você também deseja começar a rolar a tela para uma área que ainda não foi carregada. Isso força você a deixar esta parte do mapa em branco e substituí-la pelo mundo real quando estiver carregado. Isso seria um grande quebra-imersão. Por esse motivo, você deve pré-carregar a área em um determinado raio ao redor da tela dos jogadores.

O tamanho da área pré-carregada depende da rapidez com que seus jogadores podem se mover e de quanto tempo será a latência média.

Philipp
fonte
-1

A quantidade de dados que você está enviando do servidor para o cliente pode ser incrivelmente insignificante. Se isso é tudo o que você precisa enviar, sugiro veementemente carregar o máximo possível no Load, portanto, são necessários menos dados ainda. A quantidade enviada no carregamento será pequena o suficiente para justificar o tempo de carregamento, o uso da memória será quase inexistente, a menos que seu mundo seja ridiculamente superdimensionado e você precise atualizar quase nenhum dado.

Eu imagino que você também possa fazer alguns truques para otimizar a previsão de atraso, o que compensa o atraso médio que um usuário experimenta, permitindo movimentos previsíveis com os personagens.

Também a priorização de dados insignificantes, com movimentos e ações / reações de personagens com maior prioridade, pode ajudar a garantir que até jogadores atrasados ​​sintam muito pouco atraso.


fonte