3
\$\begingroup\$

Is there a simple way to 'serialize' the game data of my game, but protected it from being unloadable if I add new fields? I have all the data in a single class, GameData.java, and I want to avoid having to manually read/write each field from it. If I serialise it using standard java function, but add new fields to the class, it will render it unserializable.

I'd like to be able to save the class and the reload it from a file, and it use default values for any new fields that are missing from the save file. XML may be a solution, but is there an existing library to automate the process?

Thanks!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ One existing library? There are dozens. But your question is not really game-development related. You will likely find lots of helpful answers to this on stackoverflow.com. \$\endgroup\$ – Philipp Apr 18 '16 at 10:37
  • \$\begingroup\$ Have you tried to serialize into JSON format? Maybe Gson will work for you. \$\endgroup\$ – JordiVilaplana Apr 18 '16 at 10:41
  • \$\begingroup\$ What game development library are you using? LibGdx has built-in JSON parsing capabilities. \$\endgroup\$ – JDSweetBeat Apr 18 '16 at 13:35
  • \$\begingroup\$ I'm currently using JMonkeyEngine to develop the game. This has its own way of saving data, but is analogous to standard serialization and comes with the same problems. \$\endgroup\$ – Steve Smith Apr 18 '16 at 15:12
3
\$\begingroup\$

I use the libGdx Json functionality to save my game state to JSON;

public class GameInstance
{
    //Some fields, constructors, utilities
    
    public void saveState(GameState state)
    {
        String save = json.prettyPrint(state);
        
        //Save to the file using FileHandle
    }
    
    public void loadState(FileHandle file)
    {
        String stateText = file.toString();
        json.setIgnoreUnknownFields(true);
        state = json.fromJson(stateText);
    }
}

In my GameState I store the version of my app;

public class GameState
{
    //some fields
    public final String versionID = "0.1.1";
    
    //game access functions
}

Before I access the modified field, I check to see if the versionID is correct and will allow me to read it. This allows me to write simple fallback mechanics that help provide as much of the new functionality as possible.

EDIT:

I keep a field-changes.txt file that I use to log changes that I make in my fields for each class. I almost never remove a field entirely for compatability reasons. When I do I try to add functions that can work out a suitable replacement value.

Now, without libGdx you can just use the Jackson JSON API(link to tutorial on how to use Jackson). The details can be found in this Stack Overflow question. In short, there is apparently an annotation that you can use that has this purpose in mind specifically.

The accepted answer says you should do this;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Foo
{
    //...
}

Also check out the next best answer. Either way, the idea is still the same; to store the version of your GameState in each saved state and refactor the code to use the old data in alternative ways that makes the newest functionality possible.

Note: I only use libGdx and its Json library. Alternatively, if you wanted to use its Json library you could go and get the Json sourcecode. You would also need to copy the libGdx-specific collections and primitive collections to your project and fix the setup. You would have to do some minor editing to make it work.

\$\endgroup\$
0
-2
\$\begingroup\$

To parse the Json in java we use jsonparser. To use jsonparser in java we have to add below dependency in our pom.xml file.

<dependency>
    <groupId>com.googlecode.json-simple</groupId>
    <artifactId>json-simple</artifactId>
    <version>1.1.1</version>
</dependency>

Now suppose you have to parse the below complex json.

{
    "name": "vasu",
    "age": 26,
    "email": "vasu@gmail.com",
    "educationDetail": {
        "college": "GEHU Dehradun",
        "course": "B.Tech",
        "Branch": "CSE"
    },
    "matrixEducation": [{
        "10ClassBoard": "Pass 10 class from UP Board"
    }, {
        "12ClassBoard": "pass 12 class from UP Board"
    }]
}

So for this we create a JsonParser and make below code to parse data using this parser.

private JSONParser parser = new JSONParser();
   JSONObject jObj = (JSONObject) parser.parse(payload);
            String name = jObj.get("name").toString();
            String age = jObj.get("age").toString();
            String email = jObj.get("email").toString();
 
            JSONObject educationObj = (JSONObject) jObj.get("educationDetail");
            String collegeName = educationObj.get("college").toString();
            String course = educationObj.get("course").toString();
            String branch = educationObj.get("Branch").toString();
 
            JSONArray matrixDetail = (JSONArray) jObj.get("matrixEducation");
             
            JSONObject highSchoolObj = (JSONObject)matrixDetail.get(0);
            String highSchoolboard = highSchoolObj.get("10ClassBoard").toString();
             
            JSONObject interSchoolObj = (JSONObject)matrixDetail.get(1);
            String interSchoolboard = interSchoolObj.get("12ClassBoard").toString();

Checkout complete example on jsonparser on below URL

https://www.javadream.in/jsonparser-in-java/

\$\endgroup\$
0

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.