Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

i have a problem with serialization (saving and loading game variabiles), when i save evreything seems to be saving correctly but when i try to load it only detects first 3 objects i saved and the rest are null. Am i using serialization wrong or am i saving it wrong.

Saving objects with this:

FileOutputStream f_out = new 
                FileOutputStream("c:\\save.data");

            // Write object with ObjectOutputStream
            ObjectOutputStream obj_out = new
                ObjectOutputStream (f_out);

            // Write object out to disk

                obj_out.writeObject ( player.currentPerson );
                obj_out.writeObject ( player.gold );
                obj_out.writeObject ( Global.currentJob );
                obj_out.writeObject ( Global.currentWifeJob );
                obj_out.writeObject ( Global.currentWife );
                obj_out.writeObject ( Global.currentFood );
                obj_out.writeObject ( Global.currentCity );
                obj_out.writeObject ( Global.childList );
                obj_out.writeObject ( Global.generationList );
                obj_out.writeObject ( Global.currentPortrait );
                obj_out.writeObject ( Global.maxGeneration );
                obj_out.writeObject ( Global.currentGeneration );
                obj_out.writeObject ( Global.bloodlineRanking );
                obj_out.writeObject ( year ); 

Loading objects:

  // Read from disk using FileInputStream
                    FileInputStream f_in = new 
                        FileInputStream("c:\\save.data");

                    // Read object using ObjectInputStream
                    ObjectInputStream obj_in = 
                        new ObjectInputStream (f_in);

                    Object obj = (Object) obj_in.readObject();

                        do{
                            if(obj == null){
                                System.out.println("Skipped" + i);
                                i++;
                                continue;
                            } 
                            else{
                                    if(i==0)
                            player.currentPerson  =  (Person) obj;
                        else if(i==1)
                            player.gold = (int) obj;
                        else if(i==2)
                            Global.currentJob = (Job) obj;
                        else if(i==3)
                            Global.currentWifeJob = (Job) obj;
                        else if(i==4)
                            Global.currentWife = (Wife) obj;
                        else if(i==5)
                            Global.currentFood = (Food) obj;
                        else if(i==6)
                            Global.currentCity = (String) obj;
                        else if(i==7)
                            Global.childList = (ArrayList<Child>) obj;
                        else if(i==8)
                            Global.generationList = (ArrayList<Generation>) obj;
                        else if(i==9)
                            Global.currentPortrait = (Portrait) obj;
                        else if(i==10)
                            Global.maxGeneration  = (Integer) obj;
                        else if(i==11)
                            Global.currentGeneration  = (Integer) obj;
                        else if(i==12)
                             Global.bloodlineRanking = (Integer) obj;
                        else if(i==13)
                            world.year = (Integer) obj;

                            }
                            System.out.println(obj.getClass());
                            System.out.println(i);

                            i++;
                            obj = obj_in.readObject();
                        }
                        while(i < 20);

Here is the print output

class javagame.Father
0
class java.lang.Integer
1
class javagame.Job
2
Skipped3
Skipped4
Skipped5
Skipped6
Skipped7
Skipped8
Skipped9
Skipped10
Skipped11
Skipped12
Skipped13
share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

There is a mismatch with the objects you write (currentPerson thru year, 14 objects) and those you read back (currentPerson thru generationList, 9 objects). And once you've completed a player, you need to reset i to zero. You can break the loop, when the object is null.

share|improve this answer
    
nothing changed , i edited the code and added printout –  Matthew Jul 8 '13 at 12:39
    
What is the file format of the serialized data? If it's xml, can you add the first 20 lines? –  ott-- Jul 8 '13 at 12:56
    
pastebin.com/we4DwpKY this is what is inside the file that is made –  Matthew Jul 8 '13 at 13:00
    
It won't work that way. Compare your coding with the example from tutorialspoint.com/java/java_serialization.htm - only 1 write and read per object. –  ott-- Jul 8 '13 at 13:40
add comment

So my solution for this is that i created a SAVE class that stores all variabiles that i need

public class Save implements java.io.Serializable{


    Person person = null;
    int gold = 0;
    Job currentJob = null;
    Job currentWifeJob = null;
    Wife currentWife = null;
    Food currentFood = null;
    String currentCity = null;
    ArrayList<Child> childList = null;
    ArrayList<Generation> generationList = null;
    Portrait currentPortrait = null;
    int maxGeneration = 0;
    int currentGeneration = 0;
    int bloodlineRanking = 0;
    int year = 0;


    public void refresh(Player player,int yearr){
        person = player.currentPerson ;
        gold = player.gold ;
        currentJob = Global.currentJob ;
        currentWifeJob = Global.currentWifeJob ;
        currentWife = Global.currentWife ;
        currentFood = Global.currentFood ;
        currentCity = Global.currentCity ;
        childList = Global.childList ;
        generationList =  Global.generationList ;
        currentPortrait = Global.currentPortrait ;
        maxGeneration = Global.maxGeneration ;
        currentGeneration = Global.currentGeneration ;
        bloodlineRanking =  Global.bloodlineRanking ;
        year = yearr ; 
    }

}

This is for saving

public void save(Player player,Save s){
        s.refresh(player, year);
        try {
            FileOutputStream f_out = new 
                FileOutputStream("c:\\save.data");

            // Write object with ObjectOutputStream
            ObjectOutputStream obj_out = new
                ObjectOutputStream (f_out);

            obj_out.writeObject (s);
            // Write object out to disk


            obj_out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

This for loading

if(Global.loadEnable){
    try {

        // Read from disk using FileInputStream
        FileInputStream f_in = new 
            FileInputStream("c:\\save.data");

        // Read object using ObjectInputStream
        ObjectInputStream obj_in = 
            new ObjectInputStream (f_in);

        Object obj = (Object) obj_in.readObject();

        save = (Save) obj;

        player.currentPerson = save.person;
        player.gold = save.gold;
        Global.currentJob = save.currentJob;
        Global.currentWifeJob = save.currentWifeJob;
        Global.currentWife = save.currentWife;
        Global.currentFood = save.currentFood;
        Global.currentCity = save.currentCity;
        Global.childList = save.childList;
        Global.generationList = save.generationList;
        Global.currentPortrait = save.currentPortrait;
        Global.maxGeneration = save.maxGeneration;
        Global.currentGeneration = save.currentGeneration;
        Global.bloodlineRanking = save.bloodlineRanking;
        world.year = save.year;


    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    // Read an object
}
share|improve this answer
    
+1 Having one class is overall the best solution. –  sm4 Jul 10 '13 at 6:00
add comment

Instead of using your own class to implement the save/restore, you should do one of the following:

  • implement Serializable in your classes, and use transient to mark fields to be skipped
  • implement Externalizable and define its readExternal and writeExternal methods
  • use a library, for instance, a JSON parser (Jackson is fairly good java library for that)
share|improve this answer
    
but what is wrong with the current code i have compared to this ones you mentioned –  Matthew Jul 8 '13 at 16:33
    
What's wrong with it is that you are not using the language's features correctly. Serialization can be a very useful tool, but it is only useful if you do it correctly. –  AJMansfield Jul 8 '13 at 16:36
    
I looked into those three, im too scrubby to do complex stuff, also what is the worst thing that could happen if i keep it my way ? –  Matthew Jul 8 '13 at 16:46
1  
The worst that could happen: You will cobble together a ad-hoc solution, then you or another developer use it for a 'online multiplayer' version of the game, and then an attacker exploits a vulnerability in the save system to break into the server or user's computers. While that scenario is somewhat extreme, bad coding is never a good idea. If you do it correctly the first time, you will never have to fix it later when you try to change something. While bad code doesn't take as long to design, you will spend many times as long debugging it. –  AJMansfield Jul 8 '13 at 16:53
    
Can we do that live chat i want to ask some stuff –  Matthew Jul 8 '13 at 17:04
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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