Teoria de jogos Multiplayer – Interpolação de Objectos

Teoria de jogos multiplayer - Interpolação de ObjectosEsta é a terceira parte de uma série da série de artigos “Teoria de jogos Multiplayer” onde irei explicar os conceitos e algoritmos fundamentais e para a criação de jogos multiplayer rápidos e fluídos.  Neste artigo iremos explorar as consequências de ter várias personagens controladas por diferentes jogadores também conectados ao servidor e falar de interpolação de objectos.

 

Servidor Multiplayer

No artigo anterior o servidor só tinha um cliente conectado e por isso funcionava de forma muito simples. Basicamente ele efectuava o três passos seguintes em loop:

  1. Ler os inputs dos cliente;
  2. Actualizar o estado do jogo;
  3. Enviar o novo estado do jogo para o cliente.

Contudo, quando vários jogadores estão conectados e interagem entre si o loop so servidor torna-se um pouco diferente.

Vamos considerar o cenário em que vários clientes podem estar a enviar simultaneamente input’s para o servidor. Vamos supor também que eles fazem isto à máxima velocidade que conseguem. Actualizar o mundo do jogo sempre que um input de um utilizador é recebido e voltar a enviar o estado do jogo para todos os jogadores utilizaria demasiado CPU e largura de banda (bandwith).

Uma das soluções para este problema (a mais comum), é guardar uma lista ordenada dos inputs recebidos, sem os processar e actualizar o mundo numa frequência mais baixa, normalmente de 10x por segundo. Sempre que o servidor actualizar o mundo, ele lê essa lista dos inputs recebidos processa-a pela ordem de chegada. E finalmente, volta a enviar o novo estado do jogo para todos os clientes. Nesta abordagem ao problema o mundo do jogo é actualizado independentemente da presença e quantidade de inputs recebidos.

 

Problemas de fluidez

No ponto de vista do jogador, o exemplo explicado acima funciona com a mesma fluidez quanto a do artigo anterior uma vez que a previsão de movimento pelo cliente funciona de forma independente da frequência de actualização do servidor.

Contudo, como o estado do jogo é enviado numa frequência mais baixa (uma vez a cada 100ms), o cliente tem muito pouca informação acerca das outras entidades (jogadores, bots, etc…) que se movem no mundo.

Uma implementação de cliente mais primitiva iria actualizar a posição de cada entidade no mundo sempre que um novo estado fosse recebido do servidor. Este tipo de implementação leva a que aconteçam algumas falhas durante o movimento, havendo alguns saltos a cada 100ms em vez de movimento fluído.

Falhas no Movimento
Saltos repentinos no movimento da personagem controlada pelo cliente 1 aos olhos do cliente 2.

Existem várias formas de resolver este problema. Neste artigo irei apenas falar de um método com o nome de “Dead reckoning”, conhecido em português por “Navegação estimada”. Existem outros métodos também muito bons tais como: Entity interpolation. Os mais interessados neste assunto podem pesquisar no Google por “métodos de interpolação de objectos”, “interpolação de objectos” ou “interpolação”.

 

Navegação estimada

Imagine que está a construir um jogo de carros multiplayer. O movimento de um carro que se move muito rapidamente é também muito previsível. Por exemplo, se o carro se move a 150 metros por segundo, 1 segundo mais tarde estará 150 metros à frente da sua posição inicial.

Bem, durante esse segundo o carro pode desacelerar ou acelerar um pouco, ou pode mesmo mudar a sua direcção um pouco. Mas o que realmente interessa é que a velocidades tão altas um carro não é muito manobrável é quase como se fosse independente das acções do jogador que o controla. Noutras palavras, a velocidades muito altas um carro não pode fazer uma curva de 180º instantaneamente. 

Funcionamento num servidor que envia actualizações a cada 100ms

Num servidor com uma frequência de 10Hz, o cliente recebe uma velocidade e uma posição autoritária para cada carro na competição. Ora, após a recepção de um pacote o cliente não irá receber mais nada durante 100ms mais ainda assim precisa de mostrar os carros a competir no ecrã. A forma mais fácil de resolver o assunto é assumir que a velocidade do carro se irá manter constante durante esses 100ms e processar a física do jogo localmente com esses dados. Após os 100ms, um novo pacote é recebido e a posição e velocidade do carro são corrigidas.

O problema é que a correcção pode ser pequena ou pode ser grande, dependendo de diversos factores. Se o jogador manter o carro em linha recta e não mudar a sua velocidade, então a posição prevista será exactamente igual à posição correcta. Por outro lado se o jogador colidir com alguma coisa, a posição prevista estará muitíssimo errada (provocando um salto desagradável na correcção da posição).

 

Correcções suaves no movimento

Nos servidores autoritários, ao utilizar o sistema de navegação estimada que abordamos acima, em algumas situações muito particulares a posição estimada pode ser muito diferente da posição real imposta pelo servidor, sendo que isto pode provocar alguns saltos a cada 100ms,, durante a correcção da posição.

Este problema pode ser minimizado utilizando correcções suaves na posição dos corpos. A correcção suave de movimento consiste em corrigir a posição de um corpo durante um pequeno período de tempo ao invés de o fazer instantaneamente quando um novo estado do jogo é recebido pelo cliente.

Abaixo mostro um exemplo de um jogo multiplayer que criei recentemente onde utilizei o sistema de navegação estimada com correcções suaves de movimento. Eu controlo a roda que não se está a mover. A bola que se move é controlada por outro jogador do qual eu não consigo prever os inputs. A frequência de actualização é a normal de 10Hz (10 vezes a cada segundo).

 

Neste segundo video a correcção suave de movimento foi desactivada. Ao analisarmos com cuidado podemos detectar alguns saltos na roda em movimento.

 

Neste terceiro video a correcção suave de movimento e a navegação estimada estão desactivadas.

 

No próximo artigo iremos abordar algumas soluções para o problema do LAG de input em jogadores com um elevado ping.

Gostou deste artigo sobre interpolação de objectos? Então partilhe com os seus amigos e deixe um comentário abaixo!

Deixar uma resposta