/ / Portabilidade é algo para se preocupar ao implementar serialização binária básica para um videogame? - c ++, linux, windows, serialização

A portabilidade é algo com que se preocupar ao implementar serialização binária básica para um videogame? - c ++, linux, windows, serialização

Estou escrevendo um serializador binário simples paragere arquivos salvos para um videogame de 64 bits voltado para plataformas de 64 bits do Windows, Mac e Linux. Os tipos de variáveis ​​selecionados para serialização são: char, short, bool, int não assinado, int, float, possivelmente duplo e possivelmente longo int. Estou compilando no Visual Studio. A serialização é o mais simples possível, sem verificações, apenas gravação simples dos dados binários e desserialização dos dados na mesma ordem. O jogo salva novos dados no arquivo com muita frequência durante o jogo, mas os dados são desserializados apenas uma vez, pouco antes do jogo.

Eu não achava que portabilidade fosse algoque eu precisava me preocupar com uma função simples de salvar jogo; no entanto, tenho lido sobre os muitos problemas de portabilidade associados à serialização binária (por exemplo, representação de ponto flutuante, variações na largura de bit de ints, endianness, alinhamento etc.) e não tenho confiança suficiente na minha compreensão do assunto para ter certeza que esses problemas de portabilidade não irão elevar sua cabeça neste projeto. Talvez alguém tenha a gentileza de compartilhar alguma perspectiva sobre as seguintes suposições:

  1. As variáveis ​​podem ser serializadas para um binário em uma máquina e o O binário pode então ser copiado e desserializado com segurança em um máquina diferente com o mesmo sistema operacional e uma CPU x86-64.
  2. Se eu assumir que todas as máquinas executando ojogo são CPUs estilo x86-64 little-endian que executam sistemas operacionais de 64 bits, posso assumir que o arquivo binário pode ser totalmente portátil entre sistemas operacionais também?
  3. Se eu expandir o desenvolvimento para apoiar umVersão de 32 bits do jogo (ainda assumindo uma arquitetura de CPU x86-64 no destino plataforma, mas SO de 32 bits) e um usuário final de SO de 32 bits decide atualizar para um sistema operacional de 64 bits, instala a versão de 64 bits do jogo e então carrega o antigo arquivo salvo, que foi serializado no 32-bit SO executando a versão de 32 bits do jogo - esses tipos de variáveis em seguida, seja desserializado com segurança na plataforma de 64 bits na ordem em que foram serializados sem nenhuma verificação ou teste para compatibilidade?

É possível que salvar em uma máquina e carregar em outra possa corromper os dados em qualquer um desses cenários?

Muito obrigado antecipadamente.

Respostas:

1 para resposta № 1

Se você usar tipos inteiros de tamanho, como ::std::uint32_t em vez de tipos obscuros, como unsigned long então você será praticamente salvo do inteirovariações de tamanho que podem ocorrer entre plataformas de 32 bits / 64 bits e diferentes compiladores. A largura de bit inteira tecnicamente pode variar, mas apenas em plataformas exóticas que definitivamente não podem ser consideradas adequadas para jogos. O tamanho e a representação do ponto flutuante também não devem ser uma preocupação.

Para garantir que o tamanho e o alinhamento das estruturas de dados que estão sendo lidas / gravadas permaneçam consistentes nas plataformas, você deve usar static_assert no seu código.

No entanto, verificar endianness é obrigatório se vocêdeseja que seus arquivos salvos sejam portáteis. Normalmente, você pode querer serializar dados usando endianness nativo e escrever algum número mágico no início do arquivo indicando sua endianness (como 0x01020304) Então, quando você desserializa, primeiro verifica essa mágica e seleciona o desserializador de endianness nativo (que é mais rápido) ou o desserializador de endianness invertido (que é mais lento).