libgdx saving map

Okay i have made a random gen map what is tiles the tiles can be changed to different tiles
I want to save the map I have tried xml however it crashes while saving any suggestions

//		try {
//			//int whatisit, int blockID, float x, float y, float width, float height, Vector2 velocity, boolean hasCollision, boolean object, int objectID
//					for(int i = 0;i < 200;i++){
//						for(int j = 0;j < 200;j++){
//							
//							Tile t = Level.tiles[i][j];
//							xml.element("tile").attribute("whatisit", t.getBlockDef()).attribute("blockID", t.getBlockID())
//							.attribute("x", t.getX()).attribute("y", t.getY()).attribute("width", t.getWidth()).attribute("vx", 0).attribute("vy", 0)
//							.attribute("hasCollision", t.isCollision()).attribute("object", t.isObject()).attribute("objectID", t.getObjectID());
//						}
//					}
//			
//			
//					file.writeString(writer.toString(), false);
//		} catch (IOException e) {
//			e.printStackTrace();
//		}

its always good to post the stacktrace of the crash.

else people will have to play manual parser.

I was getting out of memory error

http://s.mlkshk.com/r/D00U

You sure it wasn’t out of bounds exception?

my new wallpaper, thanks! :smiley:

Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: java.lang.OutOfMemoryError: Java heap space
	at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
Caused by: java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Unknown Source)
	at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
	at java.lang.AbstractStringBuilder.append(Unknown Source)
	at java.lang.StringBuffer.append(Unknown Source)
	at java.io.StringWriter.write(Unknown Source)
	at com.badlogic.gdx.utils.XmlWriter.indent(XmlWriter.java:58)
	at com.badlogic.gdx.utils.XmlWriter.element(XmlWriter.java:63)
	at com.hawk.engine.game.xml.XMLMap.saveMap(XMLMap.java:30)
	at com.hawk.engine.game.level.Level.createMap(Level.java:107)
	at com.hawk.engine.game.gamescreens.GameControl.<init>(GameControl.java:27)
	at com.hawk.engine.game.window.Window.create(Window.java:48)
	at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:136)
	at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)

well, increase heap then :slight_smile:

how would i do that then?

also this is for android

Can you dump whole .java file into pastebin?

can you try to make a test with a smaller area to save, to rule out other problems

for(int i = 0;i < 4;i++){
for(int j = 0;j < 4;j++){

if that works, you might think about a saving mechanism that produces a smaller xml
for example by making the attibute names smaller, like “w” instead of “width”.
and without indention.

package com.hawk.engine.game.xml;

import java.io.IOException;
import java.io.StringWriter;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.XmlReader.Element;
import com.badlogic.gdx.utils.XmlWriter;
import com.hawk.engine.game.level.Level;
import com.hawk.engine.game.level.Tile;

public class XMLMap {

	private static XmlWriter xml;
	private static StringWriter writer;
	private static FileHandle file;
	
	public static void saveMap(String name){
		writer = new StringWriter();
		xml = new XmlWriter(writer);
		file = Gdx.files.local(name);
		
		try {
			//int whatisit, int blockID, float x, float y, float width, float height, Vector2 velocity, boolean hasCollision, boolean object, int objectID
					for(int i = 0;i < Level.lengthX;i++){
						for(int j = 0;j < Level.lengthY;j++){
							
							Tile t = Level.tiles[i][j];
							xml.element("t").attribute("w", t.getBlockDef()).attribute("bID", t.getBlockID())
							.attribute("x", t.getX()).attribute("y", t.getY()).attribute("wi", t.getWidth()).attribute("he", t.getHeight()).attribute("vx", 0).attribute("vy", 0)
							.attribute("co", t.isCollision()).attribute("o", t.isObject()).attribute("oID", t.getObjectID());
						}
					}
			
			
					file.writeString(writer.toString(), false);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}

its only a small class

Doing 200x200 tiles as xml will probably result in a 10-20mb string. Don’t know how the xml builder you are using handles that internally and if file.writeString() might create a copy of that. Best bet is to increase the heap to see if it works then or if there is some kind of memleak and use a memory profiler to inspect the size of the actual used memory and if it is stored/copied redundantly.

Can’t you use the xml builder you are using with an FileOutputStream, so you skip the intermediate string in memory completely?

Android is limited to a small heapsize. Not sure if you can increase it.

You are probably trying to load a map that is too big.

Im am not sure how to increase the heap size as i want it to work for android aswell could you add me on skype : tommohawkaction please thanks

He’s trying to serialize his map(s) to XML.

If it has to be xml, try figuring out a way to flush the string after a certain number of tiles, then start writing next group, etc.
Trying to write the entire level in one go is what’s taking far to much memory, so doing it in chunks is what you need.
(Note this is not a “chunking system”, just writing the map in pieces)

Just change it to

package com.hawk.engine.game.xml;

import java.io.IOException;
-import java.io.StringWriter;
+import java.io.Writer;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.XmlReader.Element;
import com.badlogic.gdx.utils.XmlWriter;
import com.hawk.engine.game.level.Level;
import com.hawk.engine.game.level.Tile;

public class XMLMap {

-	private static XmlWriter xml;
-	private static StringWriter writer;
-	private static FileHandle file;
	
	public static void saveMap(String name){
-		writer = new StringWriter();
-		xml = new XmlWriter(writer);
-		file = Gdx.files.local(name);
+		FileHandle file = Gdx.files.local(name);
+		Writer writer = file.writer(false);
+		XmlWriter xml = new XmlWriter(writer);

		try {
			//int whatisit, int blockID, float x, float y, float width, float height, Vector2 velocity, boolean hasCollision, boolean object, int objectID
					for(int i = 0;i < Level.lengthX;i++){
						for(int j = 0;j < Level.lengthY;j++){
							
							Tile t = Level.tiles[i][j];
							xml.element("t").attribute("w", t.getBlockDef()).attribute("bID", t.getBlockID())
							.attribute("x", t.getX()).attribute("y", t.getY()).attribute("wi", t.getWidth()).attribute("he", t.getHeight()).attribute("vx", 0).attribute("vy", 0)
							.attribute("co", t.isCollision()).attribute("o", t.isObject()).attribute("oID", t.getObjectID());
						}
					}
			
			
-					file.writeString(writer.toString(), false);
		} catch (IOException e) {
			e.printStackTrace();
		}
+		finally {
+			try { writer.close(); } catch (Exception ignore) { /*ignored*/ }
+		}
	}
}

and no I dont have to do it in xml all I want is to be able to save and load the map

its still doing the same thing dude :confused: i think i need a saving chunk system however i dont know how to do it