# Voxel Game Memory Problems

**URL:** https://discourse.processing.org/t/voxel-game-memory-problems/43231
**Category:** Coding Questions
**Created:** [November 17, 2023, 12:37am UTC](https://discourse.processing.org/t/voxel-game-memory-problems/43231 "2023-11-17T00:37:05Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Noodlybanan](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlybanan/32/18897_2.png) [@Noodlybanan](https://discourse.processing.org/u/Noodlybanan)
#### Post date: [November 17, 2023, 12:37am UTC](https://discourse.processing.org/t/voxel-game-memory-problems/43231/1 "2023-11-17T00:37:05Z")

</div>

Hi! I recoded my voxel game, and now it gets 700 Fps with as many chunks as i want, the only problem is memory. 32 chunks that are meshed take up almost 2 gb (a chunk is 32x32x32) without the mesh data load it takes up around 700 mb. Is there a way or different ways to store mesh data more efficiently?

> **This is my chunk generation code, which is executed for 32 chunks in an PShape array. (image textures can be replaced with empty images, they are not relevant!)**
>
> ```auto
> PShape createChunk() {
> PShape chunk;
> chunk = createShape(GROUP);
> triangles = 0;
> 
> //generate chunk data
> int size = 32;
> noiseSeed(round(random(0, 255)));
> 
> data = new int[size][size][size];
> for (int x = 0; x < size; x++) {
> for (int y = 0; y < size; y++) {
> for (int z = 0; z < size; z++) {
> if (y > noise(x*0.02, z*0.02)*16) data[x][y][z] = 1;
> }
> }
> }
> 
> //mesh cunk
> for (int x = 0; x < size; x++) {
> for (int y = 0; y < size; y++) {
> for (int z = 0; z < size; z++) {
> tint(#FFFFFF, 555);
> if (data[x][y][z] != 0 && shouldShowCube(x, y, z, size)) {
> //boolean showTopFace = false, showBottomFace = false, showFrontFace = false, showRightFace = false, showBackFace = false, showLeftFace = false;
> boolean showTopFace = true, showBottomFace = true, showFrontFace = true, showRightFace = true, showBackFace = true, showLeftFace = true;
> 
> if (y > 0) showTopFace = data[x][y-1][z] == 0;
> if (y < size-1) showBottomFace = data[x][y+1][z] == 0;
> if (z < size-1) showBackFace = data[x][y][z+1] == 0;
> if (z > 0) showFrontFace = data[x][y][z-1] == 0;
> if (x < size-1) showRightFace = data[x+1][y][z] == 0;
> if (x > 0) showLeftFace = data[x-1][y][z] == 0;
> 
> chunk.addChild(voxel(x, y, z, imgs[0], imgs[0], imgs[0], imgs[0], imgs[0], imgs[0], showTopFace, showBottomFace, showFrontFace, showRightFace, showBackFace, showLeftFace));
> }
> }
> }
> }
> println("TRI_COUNT: "+triangles);
> return chunk;
> }
> 
> boolean shouldShowCube(int x, int y, int z, int size) {
> if (x > 0 && y > 0 && z > 0 && x < size-1 && y < size-1 && z < size-1) {
> if (data[x-1][y][z] == 0 || data[x+1][y][z] == 0 ||
> data[x][y-1][z] == 0 || data[x][y+1][z] == 0 ||
> data[x][y][z-1] == 0 || data[x][y][z+1] == 0) {
> return true;
> }
> } else {
> return true;
> }
> return false;
> }
> 
> PShape voxel(int x, int y, int z, PImage front, PImage back, PImage right, PImage left, PImage top, PImage bottom, boolean showTopFace, boolean showBottomFace, boolean showFrontFace, boolean showRightFace, boolean showBackFace, boolean showLeftFace) {
> PShape voxel = createShape(GROUP);
> voxel.translate(x, y, z);
> 
> if (showFrontFace || showBackFace || showTopFace || showBottomFace || showLeftFace || showRightFace) {
> PShape quad;
> 
> // Front face
> if (showFrontFace) {
> quad = createShape();
> quad.beginShape(QUADS);
> quad.texture(front);
> quad.tint(enviromentLight);
> quad.vertex(0, 0, 0, 0, 0);
> quad.vertex(1, 0, 0, 1, 0);
> quad.vertex(1, 1, 0, 1, 1);
> quad.vertex(0, 1, 0, 0, 1);
> quad.endShape();
> 
> voxel.addChild(quad);
> 
> triangles += 2;
> }
> 
> // Back face
> if (showBackFace) {
> quad = createShape();
> quad.beginShape(QUADS);
> quad.texture(back);
> quad.tint(enviromentLight);
> quad.vertex(0, 0, 1, 0, 0);
> quad.vertex(1, 0, 1, 1, 0);
> quad.vertex(1, 1, 1, 1, 1);
> quad.vertex(0, 1, 1, 0, 1);
> quad.endShape();
> 
> voxel.addChild(quad);
> 
> triangles += 2;
> }
> 
> // Right face
> if (showRightFace) {
> quad = createShape();
> quad.beginShape(QUADS);
> quad.texture(right);
> quad.tint(enviromentLight);
> quad.vertex(1, 0, 0, 0, 0);
> quad.vertex(1, 0, 1, 1, 0);
> quad.vertex(1, 1, 1, 1, 1);
> quad.vertex(1, 1, 0, 0, 1);
> quad.endShape();
> 
> voxel.addChild(quad);
> 
> triangles += 2;
> }
> 
> // Left face
> if (showLeftFace) {
> quad = createShape();
> quad.beginShape(QUADS);
> quad.texture(left);
> quad.tint(enviromentLight);
> quad.vertex(0, 0, 0, 0, 0);
> quad.vertex(0, 0, 1, 1, 0);
> quad.vertex(0, 1, 1, 1, 1);
> quad.vertex(0, 1, 0, 0, 1);
> quad.endShape();
> 
> voxel.addChild(quad);
> 
> triangles += 2;
> }
> 
> // Top face
> if (showTopFace) {
> quad = createShape();
> quad.beginShape(QUADS);
> quad.texture(top);
> quad.tint(enviromentLight);
> quad.vertex(0, 0, 0, 0, 0);
> quad.vertex(1, 0, 0, 1, 0);
> quad.vertex(1, 0, 1, 1, 1);
> quad.vertex(0, 0, 1, 0, 1);
> quad.endShape();
> 
> voxel.addChild(quad);
> 
> triangles += 2;
> }
> 
> // Bottom face
> if (showBottomFace) {
> quad = createShape();
> quad.beginShape(QUADS);
> quad.texture(bottom);
> quad.tint(enviromentLight);
> quad.vertex(0, 1, 0, 0, 0);
> quad.vertex(1, 1, 0, 1, 0);
> quad.vertex(1, 1, 1, 1, 1);
> quad.vertex(0, 1, 1, 0, 1);
> quad.endShape();
> 
> voxel.addChild(quad);
> 
> triangles += 2;
> }
> }
> 
> return voxel;
> }
> 
> ```

-Libby

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [November 17, 2023, 5:03am UTC](https://discourse.processing.org/t/voxel-game-memory-problems/43231/2 "2023-11-17T05:03:41Z")

</div>

Your chunk PShape would be much simpler as a single list of QUADS rather than as a GROUP of separately transformed PShapes. Instead of using voxel.translate, do the additions yourself to position the xyz of each vertex for each quad. Create just one PShape of QUADS for the visible faces of the entire chunk.

Put all of your textures together into one single texture (called an “atlas”) and use the texture coordinates to read out the piece you want for each face of each block type. For instance, if your textures are 16x16, then make the texture 16 \* 6 pixels wide, for each side of the voxel, and 16 \* number of block types high. Then use the side number and the block type to compute the texture coordinates for each quad face. All of your chunks then only need a single texture call for drawing the whole world.

---

<div class="post-metadata">

### Author: ![Noodlybanan](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlybanan/32/18897_2.png) [@Noodlybanan](https://discourse.processing.org/u/Noodlybanan)
#### Post date: [November 17, 2023, 3:02pm UTC](https://discourse.processing.org/t/voxel-game-memory-problems/43231/3 "2023-11-17T15:02:48Z")

</div>

Thank you!  
I optimised the code from 2gb of memory down to 800mb which is 200mb for 32 meshes.  
Someone probably needs the code so here is it 🙂

> **The fixed code**
>
> ```auto
> PShape createChunk() {
> PShape chunk;
> chunk = createShape();
> 
> //generate chunk data
> int size = 32;
> noiseSeed(round(random(0, 255)));
> 
> data = new int[size][size][size];
> for (int x = 0; x < size; x++) {
> for (int y = 0; y < size; y++) {
> for (int z = 0; z < size; z++) {
> if (y > noise(x*0.02, z*0.02)*16) data[x][y][z] = 1;
> }
> }
> }
> 
> //mesh cunk
> chunk.beginShape(QUADS);
> chunk.texture(imgs[0]);
> for (int x = 0; x < size; x++) {
> for (int y = 0; y < size; y++) {
> for (int z = 0; z < size; z++) {
> tint(#FFFFFF, 555);
> if (data[x][y][z] != 0 && shouldShowCube(x, y, z, size)) {
> //boolean showTopFace = false, showBottomFace = false, showFrontFace = false, showRightFace = false, showBackFace = false, showLeftFace = false;
> boolean showTopFace = true, showBottomFace = true, showFrontFace = true, showRightFace = true, showBackFace = true, showLeftFace = true;
> 
> if (y > 0) showTopFace = data[x][y-1][z] == 0;
> if (y < size-1) showBottomFace = data[x][y+1][z] == 0;
> if (z < size-1) showBackFace = data[x][y][z+1] == 0;
> if (z > 0) showFrontFace = data[x][y][z-1] == 0;
> if (x < size-1) showRightFace = data[x+1][y][z] == 0;
> if (x > 0) showLeftFace = data[x-1][y][z] == 0;
> 
> //chunk.addChild(voxel(x, y, z, imgs[0], imgs[0], imgs[0], imgs[0], imgs[0], imgs[0], showTopFace, showBottomFace, showFrontFace, showRightFace, showBackFace, showLeftFace));
> if (showFrontFace) {
> chunk.vertex(x, y, z, 0, 0);
> chunk.vertex(x+1, y, z, 1, 0);
> chunk.vertex(x+1, y+1, z, 1, 1);
> chunk.vertex(x, y+1, z, 0, 1);
> }
> 
> if (showBackFace) {
> chunk.vertex(x, y, z+1, 0, 0);
> chunk.vertex(x+1, y, z+1, 1, 0);
> chunk.vertex(x+1, y+1, z+1, 1, 1);
> chunk.vertex(x, y+1, z+1, 0, 1);
> }
> 
> if (showRightFace) {
> chunk.vertex(x+1, y, z, 0, 0);
> chunk.vertex(x+1, y, z+1, 1, 0);
> chunk.vertex(x+1, y+1, z+1, 1, 1);
> chunk.vertex(x+1, y+1, z, 0, 1);
> }
> 
> if (showLeftFace) {
> chunk.vertex(x, y, z, 0, 0);
> chunk.vertex(x, y, z+1, 1, 0);
> chunk.vertex(x, y+1, z+1, 1, 1);
> chunk.vertex(x, y+1, z, 0, 1);
> }
> 
> if (showTopFace) {
> chunk.vertex(x, y, z, 0, 0);
> chunk.vertex(x+1, y, z, 1, 0);
> chunk.vertex(x+1, y, z+1, 1, 1);
> chunk.vertex(x, y, z+1, 0, 1);
> }
> 
> if (showBottomFace) {
> chunk.vertex(x, y+1, z, 0, 0);
> chunk.vertex(x+1, y+1, z, 1, 0);
> chunk.vertex(x+1, y+1, z+1, 1, 1);
> chunk.vertex(x, y+1, z+1, 0, 1);
> }
> }
> }
> }
> }
> chunk.endShape();
> return chunk;
> }
> 
> boolean shouldShowCube(int x, int y, int z, int size) {
> if (x > 0 && y > 0 && z > 0 && x < size-1 && y < size-1 && z < size-1) {
> if (data[x-1][y][z] == 0 || data[x+1][y][z] == 0 ||
> data[x][y-1][z] == 0 || data[x][y+1][z] == 0 ||
> data[x][y][z-1] == 0 || data[x][y][z+1] == 0) {
> return true;
> }
> } else {
> return true;
> }
> return false;
> }
> 
> ```

-Libby
