Libgdx JSON saving problem?

Hi guys.

I’m making a game where I have some JSON serializable objects that I can save to a file, and load up at the next time the game is played.

The save structure is like this:

First, an arraylist containing all of the buildings on the map.

A building contains a couple of values unimportant to this issue, and a currentTask variable and an arraylist of tasks (tasks are their own custom class, FacilityTask.java). This is a real-time game, so if you schedule a task and close the game it will technically still be going on.

So upon opening a saved game, it checks to see if any tasks have been completed:

		if(performing && getRemainingTime() <= 0){ //if the facility is performing a task and the remaining the time of the task is <= 0 millseconds
			finishAction(taskScheduled, survivorPerforming); //terminate the current task scheduled
			performing = false; //setting the facility to not performing a task
			startingTime = 0; //reset the starting time of the current task
			endingTime = 0; //reset the ending time of the current task
		}

In the case of this test, the task we are testing is already completed once i open the game. (Keep in mind that if i never close the game, this feature works perfectly fine).

But opening a game with a completed task, all of the tasks within the facility are different, as if they have generated all new ones (ive taken away any code that generates the array of tasks within a facility).

Output of old task vs. new task:

com.fanger.zombie.FacilityTask@327a5b7f
com.fanger.zombie.FacilityTask@7f0d08bc

Because of this, finishing the task doesn’t change anything because its not even a variable within the facility anymore. I know this isnt a problem with the saving/loading im doing with JSON because if i start a task, close it, and open it before its completed, the progress is saved and in-tact.

I don’t really know what section of code to post, as this issue seems like it could be a problem with a few different classes and thousands of lines of code, so if you’d like to see something please ask me and ill post it.

So what is wrong? Putting value X to json, serializing it, saving it to file, reading it from file, parsing json and getting value X somehow is a different value than what you put in the json?

It’s also not clear to me what the problem is. Could you specify what you mean by “all of the tasks within the facility are different, as if they have generated all new ones”? Because I have no idea what the result looks like.

As for this:

This is not unexpected to me. The number you are seeing behind the @ sign is the object’s hash code, which by default in most cases is the object’s internal address. If you serialize an object, then deserialize it, you in fact create a new object (which is identical to the old object, but may be located somewhere else in memory). At least, that’s how I always understood it to be.

As far as I know the LibGDX json serializer is not really smart enough to serialize references to objects (please correct me if I’m wrong), which means that if your save structure contains multiple references to the same object (e.g. many buildings refer to the same task objects) then things will get messed up. While serializing, every single time the task is encountered it is serialized to disk as a seperate object. When deserializing, these objects are instantiated again, but now as many seperate task objects instead of one. Maybe this is the problem you are having.

One way to fix this is to use custom serialization and assign ID’s to your task objects, then reconstruct everything while deserializing. This is a bit messy, though. An alternative, and better, approach would be to use another serialization approach, e.g. just using Java’s default serialization(which is actually quite good and easy to use) or use a library such as Kryo which is really fast.

Thanks for the replies guys, but I managed to figure out the problem last night before I went to sleep.

In line 2 from my first set of code, I call the method:

         finishAction(taskScheduled, survivorPerforming);

That method is what sets a tasks enabled value to false so you cant do it again. The problem was, I was setting the reference to the actual task being performed, not the actual task stored within the facility. I think with saving/loading that becomes a new object which is what caused my problem.