¿Cuál es un buen formato de archivo plano para almacenar un mapa de mosaico 2D que puede crecer infinitamente en cualquier dirección?

9

Estoy creando un motor de mapas simple que se expandirá automáticamente en cualquier dirección con contenido generado por procedimientos según sea necesario.

¿Cuál es una buena manera de almacenar datos de mapas, anclados en un origen 0,0 para que un subconjunto rectangular de datos de mapas se pueda cargar de manera rápida y eficiente desde cualquier punto del mapa?

Tengo una idea de que tal vez debería fragmentar el mapa en distintos sectores y luego usar algún tipo de formato de encabezado para identificar en qué parte del archivo se almacena un sector específico. ¿Es esta una buena técnica o existen técnicas mejores y más eficientes que puedo ver?

Nathan Ridley
fuente

Respuestas:

7

Aconsejaría no usar un solo archivo plano para cantidades teóricamente infinitas de datos.

Si tiene una cantidad de datos teóricamente infinita, entonces necesita acceso aleatorio , lo que significa múltiples archivos o una base de datos, o un formato de archivo plano indexado, que implica volver a resolver los problemas de indexación ya resueltos por los sistemas de archivos o una base de datos.

Si distribuye sus fragmentos en varios archivos, obtener el fragmento en (-110, 5000) es solo una cuestión de decir "% APPDATA% / game / map / -110 / 5000.dat" (o algún otro nombre de archivo si lo desea comenzar a comprimirlos). Las bases de datos solo necesitan una consulta. Si un fragmento no tiene ningún dato, simplemente no puede almacenar nada. Un solo archivo plano no ofrece la velocidad y la conveniencia del acceso aleatorio desde el principio.

En un solo archivo de tamaño arbitrario, para un acceso aleatorio rápido debe tener una garantía para la posición de cualquier fragmento de datos, lo que significa usar un índice (ya que una búsqueda binaria sin procesar a través de sus fragmentos de datos perjudica el rendimiento y crea una cuadrícula en su archivo con puntos "en blanco" le da el problema de Byte56 ). Una vez que desarrollas un sistema de indexación, le das eficiencia y escribes una API, has recreado algo como el sistema de archivos o una base de datos. A menos que realmente ganes algo al hacerlo, probablemente no valga la pena la inversión. Por ejemplo, Steam se beneficia enormemente de sus formatos de archivo GCF / NCF.

Si desea algo de seguridad en sus guardados, aún es posible hacerlo. Por ejemplo, puede cifrar cada fragmento individual. Para evitar que se eliminen, puede tener un hash central basado en los datos guardados existentes. Si los datos guardados no coinciden con el hash (y su programa no causó el cambio), se ha eliminado un fragmento.

doppelgreener
fuente
4

La solución utilizada con más frecuencia parece ser dividirse en muchos archivos, sin embargo, su pregunta implica un solo archivo. La única opción sensata para esto (en mi opinión) es emular un sistema de archivos muy simple dentro de ese único archivo. En realidad, no es terriblemente difícil de hacer, pero debería considerar usar varios archivos si puede.

Si tiene que apegarse a un archivo, entonces puede encontrar inspiración para su implementación desde el ext2 fs. http://en.wikipedia.org/wiki/Ext2 Sé que me ayudó a tomar buenas decisiones cuando tuve que implementar un FS simple para un juego.

Pero realmente, para cualquier mapa en crecimiento, generalmente es mejor usar un archivo para cada porción "accedida".

Richard Fabian
fuente
4

Implementé un sistema de fragmentación para mi juego cuando estaba jugando con mundos infinitos (no estoy seguro de si los mantendré o no). Para usar con un solo archivo, al principio utilicé la posición mundial del fragmento para calcular un desplazamiento de bytes en el archivo. Esto supone un tamaño de fragmento estático, o al menos un máximo estático. Sin embargo, si el usuario se fuera en una dirección por un tiempo, este archivo se volvería bastante escaso para su tamaño, ya que había grandes áreas de tierra que aún no se habían generado, por lo que había espacios en blanco en el archivo.

También probé un sistema de dos archivos. Un archivo contiene un mapa de "posición de fragmento" a pares de "desplazamiento de archivo de fragmento". El segundo contiene todos los trozos. Cuando se genera un nuevo fragmento, simplemente va al final del archivo del fragmento y su desplazamiento se almacena en el archivo de posición-> desplazamiento. Este fue un problema cuando tenía MUCHOS trozos y encontrar el desplazamiento en el archivo de posición-> desplazamiento tomó un poco de tiempo. Si lo encuentra factible, puede cargar los datos de posición-> desplazamiento en un mapa hash en la carga, para tener acceso rápido.

Estoy usando la segunda opción por ahora, pero puedo cambiar a otra cosa si encuentro que falta el rendimiento. Quizás con esta información podrás crear algo que funcione para ti. ¡Buena suerte!

MichaelHouse
fuente
Sugeriría buscar en sqlite sqlite.org . Es muy autónomo, indexado, maneja blobs, etc. Esto ayudaría con el rendimiento y resolvería los "agujeros" en su archivo.
Daniel Blezek