1
\$\begingroup\$

I'm working on a 2d adventure game where the player can explore a random generated map. It's working perfectly if I set it to be about 3000x1000 blocks (my array is 3000x1000x2), but this is TOO SMALL. When I want to make a bigger map it trows an OutOfMemory error.

I store my map in a 3d float array where the first two dim shows the position on the world plus I need 2 more data (3rd dim) for each block the type (int blockID) and the stored last update time (float elapsedTime).

Can it be better if I make it 2 separeted 2d array?

This 3d array is the one what is too big and trows OutOfMemory error. The blocks that have made Objects are the ones that can be seen(~32x14 block) the other are just two number ID and elapsedTime.

How should I store the map data?

EDIT:

This code: int x = 10000; int y = 10000; float[][][] ft; ft = new float[x][y][2]; It trows OutOfMemory error.

\$\endgroup\$
  • \$\begingroup\$ Something doesn't add up here. 3000x1000x2 are just 8 million entries. A float is 4 byte. So a float[3000][1000][2] would just consume about 24 MB. Sure, java being java there can be a lot of hidden memory hogs. But I think you aren't telling us the whole story. Can you show us the declarations of your data structures? \$\endgroup\$ – Philipp Aug 2 '18 at 13:05
  • \$\begingroup\$ As I writed it is OK its enough! but I want bigger where its a problem. \$\endgroup\$ – pocokknight1 Aug 2 '18 at 14:33
1
\$\begingroup\$

When your game has a map which is too large to fit into memory, then the default solution to the problem is to use chunks.

Divide your map into rectangular chunks which are about as large as the screen. Only load the chunk the player is in and the adjacent chunks into memory. When the player moves to a different chunk, persist the no longer needed chunks to the hard drive and unload them (which you do in Java by making sure that there are no variables anymore which point to them). When the player returns, load the chunks from the hard drive back into memory.

When your map is randomly-generated, then you can use the fact that the Java Random class can be initialized with a seed value. When you call new Random(seed) with the same seed, you get the same sequence of random numbers from it. So when you use a new Random object for each chunk you generate, then all you need to save about a chunk is the seed value and any changes to the chunk which happened over the course of the game.

\$\endgroup\$
  • 1
    \$\begingroup\$ I understand the chunk mechanics I'm asking how should which is the best/fastest/cheapest way to store the unloaded parts? Like maybe in a file structure? Is there a tryed best solution? \$\endgroup\$ – pocokknight1 Aug 2 '18 at 14:04
0
\$\begingroup\$

You have a three dimensional float array of the size [3000,1000]? Well thats two dimensions?

Ignoring that: that are 3 million floats with 8 bytes each (there seems additional overhead if you use Float insead of float) = 24 million bytes = 24 mega byte. Seems not too much for a usual memory in a pc.

May tunning the memory settings will help you temporarily: Java memory settings

To calculate the actual size you store may that SO question will help you.

From my experiences with tilemaps: yes, they can become large in memory even if you trim down every single byte possible. (think I was up to 8 - 12 GB ram in my experiments for the tile map array only.)

But in fact you most likely do not need all the data in memory all the time. Since you generate a map may try to store that created map in a file and load (and update on demand) only the area near the player. So you can limit your memory demand.


Possible improvements of the data structure of the tilemap

If you have a 3 dimensional map where the third dimension are tiles stacked up you still could use a short or integer array (depending on the needed amount of tiles) instead of a float array saving some bytes. The short/int indicates the tile type.

The tiles themselves can be stored in a seconds structure like an array which holds all the data needed for this specific tile type.

I have to guess but I think you used the float "as drawing position"? Iterating over the array while drawing gives you the x,y,z tile indizes and you could calculate the drawing position out ouf the tile index you already have at this point. Which makes it unnecessary to store them.

\$\endgroup\$
  • \$\begingroup\$ No you dont get it, but yes i writed it wrong. So its a 3D array 3000x1000x2. I dont store the positions of the tiles because its the same as the position in the array. The 3rd dim is becouse i need 2 informations for each block 1) the ID what type of tile it is, 2) the last time it was updated. when a block came into the screen I make the Object from that 2 data. And my problem is as I writed this map is too little I need a lot more bigger, but it results in OutOfMemory error. And I need a method to prevent that like save the map in a file or somthing? \$\endgroup\$ – pocokknight1 Aug 2 '18 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.