Qual é um bom formato de arquivo simples para armazenar um mapa de blocos 2D que pode crescer infinitamente em qualquer direção?

9

Estou criando um mecanismo de mapa simples que se expandirá automaticamente em qualquer direção com o conteúdo gerado pelo procedimento, conforme necessário.

Qual é uma boa maneira de armazenar dados do mapa, ancorados na origem 0,0, para que um subconjunto retangular de dados do mapa possa ser carregado com rapidez e eficiência a partir de qualquer ponto do mapa?

Tenho uma ideia de que talvez eu devesse dividir o mapa em setores distintos e depois usar algum tipo de formato de cabeçalho para identificar onde no arquivo um setor específico está armazenado. Esta é uma boa técnica ou existem técnicas melhores e mais eficientes que eu posso olhar?

Nathan Ridley
fonte

Respostas:

7

Eu desaconselharia o uso de um único arquivo simples para quantidades teoricamente infinitas de dados.

Se você tem uma quantidade teoricamente infinita de dados, precisa de acesso aleatório , o que significa vários arquivos ou um banco de dados - ou um formato de arquivo simples indexado, que envolve a resolução dos problemas de indexação já resolvidos por sistemas de arquivos ou banco de dados.

Se você distribuir seus pedaços em vários arquivos, obter o pedaço em (-110, 5000) é apenas uma questão de "% APPDATA% / game / map / -110 / 5000.dat" (ou outro nome de arquivo, se você quiser comece a comprimi-los). Bancos de dados só precisam de uma consulta. Se um pedaço não tiver nenhum dado, você não poderá armazenar nada. Um único arquivo simples não oferece a velocidade e a conveniência do acesso aleatório logo de cara.

Em um único arquivo de tamanho arbitrário, para acesso aleatório rápido, você deve ter uma garantia para a posição de qualquer parte dos dados, o que significa usar um índice (uma vez que uma pesquisa binária bruta através de seus blocos de dados prejudica o desempenho e a criação de uma grade em seu arquivo com manchas "em branco" apresenta o problema do Byte56 ). Depois de desenvolver um sistema de indexação, aumentar a eficiência e escrever uma API para si mesmo, você recriou algo como o sistema de arquivos ou um banco de dados. A menos que você realmente ganhe algo com isso, provavelmente não vale o investimento. Por exemplo, o Steam se beneficia enormemente de seus formatos de arquivo GCF / NCF.

Se você quiser segurança em seus salvamentos, ainda é possível fazer isso. Por exemplo, você pode criptografar cada bloco individual. Para impedir que eles sejam excluídos, você pode ter um hash central com base nos dados salvos existentes. Se os dados salvos não corresponderem ao hash (e seu programa não causou a alteração), um pedaço foi excluído.

doppelgreener
fonte
4

A solução usada com mais frequência parece ser dividida em muitos arquivos, no entanto, sua pergunta implica apenas um único arquivo. A única opção sensata para isso (na minha opinião) é emular um sistema de arquivos muito simples dentro desse único arquivo. Não é realmente terrivelmente difícil de fazer, mas você deve considerar o uso de vários arquivos, se puder.

Se você precisar manter um arquivo, poderá encontrar inspiração para sua implementação no ext2 fs. http://en.wikipedia.org/wiki/Ext2 Sei que me ajudou a tomar algumas boas decisões quando tive que implementar um FS simples para um jogo.

Mas, realmente, para qualquer mapa em crescimento, geralmente é melhor usar apenas um arquivo para cada bloco "acessado".

Richard Fabian
fonte
4

Eu implementei um sistema de chunking para o meu jogo quando estava mexendo com mundos infinitos (não tenho certeza se vou mantê-los ou não). Para uso com um único arquivo, primeiro usei a posição mundial do pedaço para calcular um deslocamento de bytes no arquivo. Isso pressupõe um tamanho de pedaço estático, ou pelo menos um máximo estático. No entanto, se o usuário seguisse em uma direção por um tempo, esse arquivo se tornaria bastante escasso por causa do tamanho, pois havia grandes áreas de terra que ainda não haviam sido geradas e, portanto, havia espaços em branco no arquivo.

Eu também tentei um sistema de dois arquivos. Um arquivo contém um mapa de pares de "posição de bloco" para "deslocamento de arquivo de bloco". O segundo contém todos os pedaços. Quando um novo pedaço é gerado, ele simplesmente segue no final do arquivo do pedaço, e seu deslocamento é armazenado no arquivo de posição-> deslocamento. Esse foi um problema quando você teve MUITOS blocos e encontrar o deslocamento no arquivo position-> offset levou um pouco de tempo. Se você achar viável, poderá carregar os dados de posição-> deslocamento em um mapa de hash em carga, para ter acesso rápido.

Estou usando a segunda opção por enquanto, mas posso mudar para outra coisa se achar que o desempenho está faltando. Talvez com essas informações você possa criar algo que funcione para você. Boa sorte!

MichaelHouse
fonte
Eu sugeriria olhar para o sqlite sqlite.org . É muito independente, indexado, manipula blobs, etc. Isso ajudaria no desempenho e resolveria "buracos" no seu arquivo.
Daniel Blezek