Problemas ao criar um servidor para MMOG

3 respostas
Michel.Montenegro

Bom, como alguns já devem saber, a um tempo atrás comecei um projeto em Java tanto no lado cliente como no servidor (Estava tudo indo bem), fizemos um ( Login Server -> Game Server -> Jogo (2D)), inclusive funcinava com mais de um player logado, recentemente fomos tentar melhorar o servidor (Inclusive por necessidade, tivemos alguns problemas), no final resolvi postar aqui umas duvidas:

Informações:
Trabalhamos com Socket (TCP) em tudo.

  1. Como seria o fluxo correto de conexões ou bons metodos para a criação de um Servidor?
    ex:
    Executa Login Server (Valida usuarios e transfere para o Servidor correto (Ex: Server 1, Server 2, Server 3) ).

Executa Game Server ( Game server se conecta via socket com Login, validando usuarios ainda logados).

Executa Cliente (valida no Login Server e abre conexão com o Login e Game server (E mantem aberta conexão em ambos)).

Cliente fica enviando e recebendo dados (Conexão só encerra quando o jogo fecha).

Game Server:

  • Pra cada cliente logado criamos uma thread (50 players = 50 threads = 50 conexões diferentes NO SERVIDOR).
    Obs: Inclusive antes o cliente ficava a 67+ “FPS” e localmente ainda fica, mas em rede (internet apenas com 2 clientes o FPS cai para 20 FPS) como se o cliente tivesse um delay violento causado pela resposta do servidor ou … (Lembrando que testando tudo na mesma maquina (Login->Server->Jogo) o FPS fica normal, mas em rede ou internete o FPS do cliente cai bruscamente.

Obs: Agora quando dois clientes logam, ambos travam, só um mesmo lento funciona.

2. Qual protocolo aconselham e quando usalo (TCP, UDP, outros …)?

3. Quais são as boas praticas para este tipo de desenvolvimento (Me referindo ao trabalho na conexão).

4. Serialização, como usar isso corretamente?

Antes que perguntem, pretendo migrar para o RedDwarf (ou outro) em algum momento (Ao menos tudo indica que sim), mas preciso do servidor funcionando nem que seja no minimo de 20 players para que eu possa continuar os trabalhos no lado cliente (Lembrando que ele é apenas um terminal burro, e tudo ocorre no servidor). E não sei até que ponto a curva de aprendizado do RedDwarf é longa (Não sei nada dele, exceto que o usam no lado servidor, mas o que ele automatiza para mim? aonde ele agiliza, etc; são estas coisas que podem demorar então resolvemos fazer um servidor do zero, que segure ao menos 20 players).

Espero que tenha me expressado bem em relação aos nossos problemas.

3 Respostas

ViniGodoy

Michel.Montenegro:
- Pra cada cliente logado criamos uma thread (50 players = 50 threads = 50 conexões diferentes NO SERVIDOR).
Obs: Inclusive antes o cliente ficava a 67+ “FPS” e localmente ainda fica, mas em rede (internet apenas com 2 clientes o FPS cai para 20 FPS) como se o cliente tivesse um delay violento causado pela resposta do servidor ou … (Lembrando que testando tudo na mesma maquina (Login->Server->Jogo) o FPS fica normal, mas em rede ou internete o FPS do cliente cai bruscamente.

Isso é extremamente ineficiente. Pois você sobrecarrega o servidor com trocas de contexto nas threads.
Procure se informar sobre as classes do pacote java.nio, em especial o SocketChannel e os Selectors. E aí use uma thread só.

TCP durante o login, com um protocolo de criptografia e em chats durante o jogo. Se tiver serviço de update ou download de arquivos, use TCP também.
UDP para o jogo.

  1. Use protocolos binários;
  2. Use dead reckoning (movimentação no cliente antes da resposta no servidor). Lembre-se que o maior problema na internet é atraso de pacotes, não tanto largura de banda.
    Por isso, é importante usar um protocolo sem muita confirmação (UDP), associado a técnicas que disfarçam atraso (dead reckoning, vida e danos subjetivos, poderes com efeitos longos, etc).

Não usando. :slight_smile:

Provavelmente a curva será bem menor do que aprender a fazer seu próprio servidor usando UDP na unha.

E, bem-vindo. Como eu te falei no Ponto V!, quando você disse que foi “relativamente fácil” montar um MMOG, enquanto vc não conseguir suportar milhares de jogadores (e você nem chegou nas dezenas), não pode chamar de "M"MO.

Michel.Montenegro

ViniGodoy:

Isso é extremamente ineficiente. Pois você sobrecarrega o servidor com trocas de contexto nas threads.
Procure se informar sobre as classes do pacote java.nio, em especial o SocketChannel e os Selectors. E aí use uma thread só.

Vou dar uma olhada, nisso hoje.

ViniGodoy:

TCP durante o login, com um protocolo de criptografia e em chats durante o jogo. Se tiver serviço de update ou download de arquivos, use TCP também.
UDP para o jogo.

Entendi.
Mas me tira uma duvida, salvo engano, dizem que o WoW e alguns MMOGs atuais jáestão usando TCP em quase tudo.

Tem algum site que fale sobre isso (PT ou PT-BR preferencialmente, rsrsrsr…)

Não curte, mesmo um RMI, nestes casos rsrsr… (Mas compreendo)

Pelo que to estudando, o que disseste confere, achei uns videos tutoriais da epoca do DarkStar (Nome anterior ao RedDwarf)
Sabe me dizer quantos players o RedDwarf já conseguiu aguentar em seu servidor?

ViniGodoy:

E, bem-vindo. Como eu te falei no Ponto V!, quando você disse que foi “relativamente fácil” montar um MMOG, enquanto vc não conseguir suportar milhares de jogadores (e você nem chegou nas dezenas), não pode chamar de "M"MO.

Não louco, entendeste completamente errado o que disse, mas praque não haja mais duvida vou por em topico:

  1. Sem exagero, da maioria (Salvo alguns que conheci) falavam que fazer um jogo em Java é o “Cão chupando manga”.
  • Bom, achei fácil fazer. O que não achei nada e nem um pouco fácil foi achar informações, documentações (Atualizadas) e exemplos.
  1. Uma penca surgiu randomicamente falando algo como “faz um joguinho da velha pra começar”, pra qualquer pergunta feita logo quando comecei a fazer algumas perguntas, mas graças teve aqueles que respondiam direto (este foi o teu caso e continua sendo, por isso agradeço).
  • Mas consegui evoluir muito mais rapido, graças aos prototipos iniciais, mas o que fez diferença real foi quandocomecei o projeto e mantive o foco (E mantenho até agora)
  1. Quando pensei, vou fazer um MMOG, mas o 1° M com certeza vou levar muito tempo pra atingir, mas se não tiver um foco, um objetivo a ser alcansado, vou me contentar com migalhas (Mesmo sem perceber). Como resultado todo o projeto vem sendo feito em cima disso (MMOG), tem os que não acreditam nele, tem os que acreditam, mas no final, sei que comecei algo bem interessante e quem sabe evolua da forma correta e atinga seu objetivo.
  • Mas até onde o projeto chegou eu só tenho a agradecer a alguns foruns e blogs como GUJ, Ponto V, Unidev, … (Ao criador do nifty-gui que me deu uma força grande) e a dois colaboradores (Antonio que vem comigo olhando o Servidor e ao Pedro com suas ideias). ViniGodoy posso não ter me expressado bem (Principalmente pela empolgação, mas atualmente estou bem pé no chão e ainda sim confiante que chego lá (^^) ). E agradeço muito a força dada aqui, pois são poucos os que ainda contribuem de verdade mesmo em um projeto open-source. :slight_smile:
ViniGodoy

“Quase tudo”. O que não está nesse “quase” é justamente o jogo em si, ou tudo que dependa de atualização praticamente em tempo real. Chat, transações de compra e venda e outros detalhes podem e são melhor implementados via TCP.

O problema do TCP é que ele trabalha com confirmação de pacotes. Veja o que pode acontecer:

a) O jogador manda um pacote indicando seu status no instante T-1;

b) O pacote se perde;

c) O jogador manda um pacote indicando seu status no instante T. Esse pacote chega;

d) O TCP segura a entrega do pacote T, e solicita a retransmissão do pacote do instante T-1;

e) O jogador transmite o pacote da sua situação em T-1. O pacote chega;

f) O TCP encaminha para sua aplicação java os pacotes T-1 e T.

Qual o problema disso? A perda do pacote T teve impacto muito negativo no lag. Foi necessário confirmá-lo, e retransmiti-lo. Como o TCP também garante ordenação, o pacote T, mais atualizado, também não pode chegar e teve que esperar essa retransmissão. Provavelmente o pacote T-1 chegaria junto com o pacote T+1… Ou seja, se sua rede tiver um atraso de 0.3s, todo esse processo atrasou os pacotes em 0.9s.

Sendo que, supondo, o pacote T-1 dizia ao servidor que o char estava em x=10 y=10 e foi para x=10 y=11, enquanto o pacote T dizia que ele estava em x=10 y=11 e foi para x=11 y=11. Era mesmo necessário aguardar T-1 chegar? O melhor seria fazer o servidor tolerar alguma perda de pacotes, e aceitar diretamente o pacote T se estivesse num limite tolerável.

Em jogos, geralmente mandamos diversos status de jogadores a cada segundo. Se um status desse falhar, não tem porque ficar esperando ele ser retransmitido. Simplesmente ignoramos o fato e partimos para o próximo status.

Essa característica (garantir ordenação e entrega) é extremamente interessante para a transmissão de arquivos, comunicação via chat. Mas é extremamente indesejável para tempo real (updates do jogo, voz e vídeo).

Não que eu conheça. Eu conheço boas referências para isso em livros, como o de redes do Tanembaum. Mas dicas mais específicas só em livros importados, como o Effective TCP/IP.

Não, você precisa de um protocolo leve. Embora largura de banda não seja o maior problema na comunicação até o cliente, ela é um problema na entrada do servidor. Lembre-se, seu servidor estará se comunicando com 1000 ou 2000 jogadores. Portanto, 1k de informação num pacote já exigirá 2MB de conexão. Um protocolo baseado em texto (xml, por exemplo), ou mais gorduroso pode facilmente congestionar o seu servidor. E estamos falando do congestionamento da linha de comunicação, não de software.

Faz tempo que vi um projeto de 400 jogadores. Mas nunca acompanhei o DarkStar de perto, pq meu principal interesse em jogos é computação gráfica e IA.

Michel.Montenegro:
1. Sem exagero, da maioria (Salvo alguns que conheci) falavam que fazer um jogo em Java é o “Cão chupando manga”.

  • Bom, achei fácil fazer. O que não achei nada e nem um pouco fácil foi achar informações, documentações (Atualizadas) e exemplos.

Concordo. Não é muito complexo, mas não é a linguagem mais adequada. Principalmente pela falta de documentação e suporte. E pela total falta de interoperabilidade. Se quer um jogo multiplataforma, ironicamente, não use Java.

Michel.Montenegro:
2. Uma penca surgiu randomicamente falando algo como “faz um joguinho da velha pra começar”, pra qualquer pergunta feita logo quando comecei a fazer algumas perguntas, mas graças teve aqueles que respondiam direto (este foi o teu caso e continua sendo, por isso agradeço).

  • Mas consegui evoluir muito mais rapido, graças aos prototipos iniciais, mas o que fez diferença real foi quandocomecei o projeto e mantive o foco (E mantenho até agora)

É que vc não tem noção da quantidade de gente que mal programou algo na vida e vem querendo fazer um MMORPG. Na PDJ, forum de programação de jogos eu administro, temos um caso desses por mês, no mínimo.

Criado 7 de julho de 2011
Ultima resposta 7 de jul. de 2011
Respostas 3
Participantes 2