o aplicativo falha quando atinge 1,5 GB.
Isso sugere fortemente que você não está representando seus blocos corretamente, pois isso significa que cada bloco tem aproximadamente 80 bytes de tamanho.
O que você precisa entender é que é preciso haver uma separação entre o conceito de jogo de um bloco e o bloco visual que o usuário vê. Esses dois conceitos não são a mesma coisa .
Veja Terraria, por exemplo. O menor mundo de Terraria ocupa 4200x1200 peças, ou seja, 5 milhões de peças. Agora, quanta memória é necessária para representar esse mundo?
Bem, cada ladrilho tem uma camada de primeiro plano, uma camada de fundo (as paredes do fundo), uma "camada de arame" para onde os fios vão e uma "camada de móveis" para onde os itens de móveis vão. Quanta memória cada bloco ocupa? Mais uma vez, estamos apenas falando conceitualmente, não visualmente.
Um bloco de primeiro plano pode ser facilmente armazenado em um curto não assinado. Não existem mais de 65536 tipos de blocos em primeiro plano, portanto, não faz sentido usar mais memória que isso. Os blocos de plano de fundo podem facilmente estar em um byte não assinado, pois existem menos de 256 tipos diferentes de blocos de plano de fundo. A camada de arame é puramente binária: ou um ladrilho tem um arame ou não. Então isso é um bit por bloco. E a camada de móveis poderia novamente ser um byte não assinado, dependendo de quantas peças de móveis diferentes fossem possíveis.
Tamanho total da memória por bloco: 2 bytes + 1 byte + 1 bit + 1 byte: 4 bytes + 1 bit. Portanto, o tamanho total de um pequeno mapa de Terraria é 20790000 bytes, ou ~ 20 MB. (nota: esses cálculos são baseados no Terraria 1.1. O jogo se expandiu muito desde então, mas mesmo o Terraria moderno pode caber dentro de 8 bytes por local de bloco, ou ~ 40MB. Ainda é bastante tolerável).
Você nunca deve ter essa representação armazenada como matrizes de classes C #. Eles devem ser matrizes de números inteiros ou algo semelhante. A estrutura do AC # também funcionaria.
Agora, quando chega a hora de desenhar parte de um mapa (observe a ênfase), o Terraria precisa converter esses blocos conceituais em blocos reais . Cada ladrilho precisa realmente escolher uma imagem de primeiro plano, imagem de fundo, uma imagem de mobília opcional e ter uma imagem de arame. É aqui que o XNA entra com suas várias folhas de sprite e tal.
O que você precisa fazer é converter a parte visível do seu mapa conceitual em blocos de folhas de sprite XNA reais. Você não deve tentar converter a coisa toda de uma só vez . Cada bloco que você armazena deve ser apenas um índice dizendo "Eu sou o tipo X do bloco", em que X é um número inteiro. Você usa esse índice inteiro para buscar qual sprite você usa para exibi-lo. E você usa as folhas de sprite do XNA para tornar isso mais rápido do que apenas desenhar quads individuais.
Agora, a região visível dos ladrilhos precisa ser dividida em vários pedaços, para que você não construa constantemente folhas de sprite sempre que a câmera se mover. Portanto, você pode ter pedaços de 64x64 do mundo como folhas de sprite. Quaisquer pedaços de 64x64 do mundo que são visíveis na posição atual da câmera do jogador são aqueles que você desenha. Quaisquer outros pedaços nem sequer têm folhas de sprite; se um pedaço cair da tela, você joga fora essa folha (nota: você realmente não o exclui; você o mantém por perto e o resecifica para um novo pedaço que pode se tornar visível mais tarde).
Eu gostaria de ter o mapa inteiro processado pelo menos no aplicativo do servidor (e no cliente, se possível).
Seu servidor não precisa conhecer ou se preocupar com a representação visual de blocos. Tudo o que precisa é se preocupar com a representação conceitual. O usuário adiciona um bloco aqui, por isso altera esse índice.