Estou trabalhando em um sistema de entidades para um jogo em rede e atribuindo a cada entidade um ID inteiro de 32 bits exclusivo que posso usar para serializar referências a entidades e às próprias entidades.
Atualmente, estou apenas incrementando um contador toda vez que uma entidade é criada. Acho que os IDs acabarão, mas não espero ter 4 bilhões de entidades. Isso também evita o problema se a entidade nº 5 for destruída e obtivermos um ID igual a 5. Ele deve se referir ao novo nº 5 ou ao antigo nº 5 excluído?
O problema é que não tenho certeza de como lidar com / evitar colisões. Atualmente, se um cliente recebe uma atualização para uma entidade com um ID maior que o "ID gratuito" atual, ele apenas esbarra no ID gratuito. Mas isso não parece muito robusto.
Pensei em talvez atribuir intervalos a cada cliente para que eles possam alocar entidades sem conflitar (digamos que os n bits superiores sejam o número do jogador), mas estou preocupado com o que acontece se os intervalos começarem a se sobrepor ao longo do tempo.
Existe uma maneira melhor de lidar com isso? Devo me preocupar com ids transbordando ou ultrapassando o final do intervalo permitido? Eu poderia adicionar código para detectar esses casos, mas o que faria se eles acontecessem além da falha.
Outra opção é usar algo com maior chance de ser único, como um GUID de 128 bits, mas que parece realmente pesado para um jogo que está tentando minimizar o tráfego de rede. Além disso, realisticamente, eu nunca precisaria de mais entidades ao mesmo tempo, então caberia em um número inteiro de 32 bits ou mesmo 24 bits.
Obrigado!
fonte
Respostas:
O que eu fiz foi fazer o servidor fazer tudo . O (s) cliente (s) pode apenas pedir ao servidor para fazer alguma coisa, mas não pode fazer nada sozinho. Nesse caso, o servidor sempre atribuirá IDs e o problema será resolvido.
Não lidei com a previsão do lado do cliente enquanto esperava o servidor aprovar ações como: "Disparar um foguete" ou "Fazer uma estação solar aqui". Essas ações desejam criar entidades, e as entidades têm IDs. Até o momento, estou apenas aguardando pelo servidor, mas acredito que o que precisa ser feito é criar uma entidade temporária enquanto você aguarda a aprovação do servidor. Quando você recebe a aprovação do servidor, o servidor atribui um ID e você pode atualizar ou substituir o objeto temporário.
Eu também não lidei com um estouro de ID, mas se o servidor estiver no controle total e detectar um estouro, ele poderá fazer o que você achar necessário (reinicie em 0, escolha entre uma pilha livre, falha, etc.) e todos os clientes nem sabem ou se importam. Os clientes aceitarão apenas os IDs distribuídos pelo servidor.
fonte
Quando fiz isso para um jogo multiplayer comercial, fiz exatamente o que você propõe: use um inteiro GUID de 32 bits, onde os oito bits principais são o número do jogador e os vinte e quatro bits inferiores contêm um número localmente único.
Se / quando o número local estourar (no meu caso, quase nunca aconteceria; sob uso normal, levaria quatro a cinco dias de reprodução contínua em uma única sessão de rede para que isso acontecesse), o proprietário enviaria uma Mensagem "Redefinindo todos os meus objetos" e renumerar todos os objetos ainda existentes a partir de zero atrás. A mensagem dizia a todos os colegas para descartar os objetos que haviam recebido e consultá-los novamente.
Uma abordagem mais sofisticada seria a mensagem "Objeto com GUID 'n' agora é Objeto com GUID 'm'" para cada objeto existente. Mas no meu caso, era improvável que isso realmente acontecesse, e eu não achava que as pessoas realmente se importariam com objetos remotos desaparecendo do mundo por meio segundo, depois de cinco dias de reprodução sem parar em uma única sessão de rede. ;)
fonte
Se seus clientes podem gerar suas próprias entidades, suponho que você tenha um jogo multiplayer ponto a ponto.
Se for esse o caso, você provavelmente não tem muitos clientes. Certamente não mais que 256. E seu ID de entidade é garantido para caber em 24 bits (16000000+ entidades são suficientes para todos!). Portanto, apenas faça o byte mais alto do seu ID igual ao do cliente:
ou alguma coisa.
E se eu estiver errado e você tiver um servidor autorizado, nunca crie novas entidades nos clientes.
fonte
Estou usando o método 'mais ingênuo' (apenas incremente um número inteiro para cada novo ID) no meu jogo multiplayer persistente e funciona bem porque não deixo o cliente criar novos ID: s.
Se você deixar o cliente decidir (usando uma espécie de técnica GUID explicada), o cliente também poderá introduzir vários erros atribuindo um ID antigo a um novo item (isso é exatamente o que eu pensei em cima da minha cabeça pensando em 5 segundos , pode haver muitas outras brechas).
Como de costume, para evitar trapaças , o servidor deve criar e validar TODAS as informações .
fonte