How to save C++ Structure in Cocos2d-x 2.1.4, to save game state

How to save game state ?
I know we can do so using CCUserDefault, but then it supports only five basic data types. Is there any way where I can store c++ structures in the CCUserDefault or in any other storage ? Please share your thoughts.

Hi Gautam,

We use our own files to store game state. Maybe you can build some XML structures to save/load game status from local files.

Cheers!

Maybe using a CCDictionary object? Easy to create and will write an XML alike file.

check it out [[http://www.cocos2d-x.org/wiki/CCDictionary]]

Thanks for sharing your thoughts guys. Xml or Dictionary is what I thought of using.But wanted to know how other developers are saving game states :).I know how to read dictionaries but no clue about writing to it. Any reference will be very helpful.

There is a method called “writeToFile”

Imagine that you have your CCDictionary object called “myDictionary” you should be able to do this:

myDictionary->writeToFile(“complete_path_to_save_your_file”);

If I am not mistaken, CCDictionary uses TinyXML library to read / write data, what means that behinds the scenes all the magic happens in XML format :).

I hope this helps.

I just wrote a piece of code to show how it works:

        // Create a new dictionary
        CCDictionary * myDictionary = new CCDictionary();

        // Add the data you would like to store
        CCString testValue ="test_value1";
        myDictionary->setObject(&testValue,"test_key1");

        testValue = "test_value2";
        myDictionary->setObject(&testValue,"test_key2");

        // Save your dictionary to a file
        myDictionary->writeToFile("test.plist");

This will create a file test.plist in your resources directory with this content:

        test_key1
        test_value2
        test_key2
        test_value2
1 Like

I just found a way to write to the Dictionary ,[[http://www.cocos2d-x.org/reference/native-cpp/V2.2/d7/d5f/classcocos2d_1_1_c_c_dictionary.html#a19b573cf7b57a57c824ca70eae909343]]
But then here also we need to set values one by one. So it looks more or less like using CCUserdefault. Am I missing something ?

I think that you are right, you can use CCUserdefault and use the following:

CCUserDefault::createXMLFile();

to save the file. At the end, no matter what you have to add the values one by one ……

thanks for the code snippet! and I will check CCUserDefault::createXMLFile(), and let you know if we can use it. :slight_smile:

I use sqlite3 and find it to be an excellent saved game format.

but then is there any significant increase in bundle size by using SQLite ?

Shouldn’t be too big (the increase of bundle) as you will start creating & inserting data in your small database as soon as the game is installed, not before.

Alejandro Santiago wrote:

I just wrote a piece of code to show how it works:
[…]
>
This will create a file test.plist in your resources directory with this content:
>
[…]

I tried this code , but I can’t find my .plist file anywhere. Please see code below , I tried.

   char key[20];
    short shapeCount=0;
      for(short i=0;i<4;i++)
        for(short j=0;j<4;j++)
        {
          shapeCount++;
          sprintf(key,"Shape%d",shapeCount);            
          cdMatrixDictionary->setObject( CCString::create("tony"), key);
        }

 if( cdMatrixDictionary->writeToFile("test.plist") )
       CCLOG("Written");
    else
       CCLOG("Written falied");

So it should have created test.plist with value “tony” for every key.It even logs Written , which mean writeToFile was successful.
But when I tried to read back , it crashes here. Which means test.plist was not created.

 CCDictionary *readDict=CCDictionary::createWithContentsOfFile("test.plist");

Don’t know whats happening… ! Help needed!

I just tried your code in my windows project and it worked fine.

It creates the document “test.plist” into the Resources folder.

Are you trying this in Android or IOS perhaps?

Try to save / load like this

       std::string _path = CCFileUtils::sharedFileUtils()->getWritablePath();
       _path.append ("test.plist");

       if( cdMatrixDictionary->writeToFile(_path.c_str()))
           CCLOG("Written");
       else
           CCLOG("Written falied");

       CCDictionary *readDict=CCDictionary::createWithContentsOfFile(_path.c_str());

Basically it tries to find the writable path in your system (Windows, IOS, Android etc)… and save / load from there

thanks for reply , I am using iOS platform tried this code also still can’t locate the file. But now I am able to read it, but the value I am getting is " 40\351" following is read code I used. Sorry I changed the code for simplicity. I am using Cocos2d-x 2.1.4

CCDictionary * myDictionary = new CCDictionary();

    // Add the data you would like to store
    CCString testValue ="test_value1";
    myDictionary->setObject(&testValue,"test_key1");

    testValue = "test_value2";
    myDictionary->setObject(&testValue,"test_key2");

    // Save your dictionary to a file
   // myDictionary->writeToFile("Gtest.plist");

    std::string _path = CCFileUtils::sharedFileUtils()->getWritablePath();
    _path.append ("Gtest.plist");

    if( myDictionary->writeToFile(_path.c_str()))
        CCLOG("Written");
    else
        CCLOG("Written falied");

     CCDictionary *readDict=CCDictionary::createWithContentsOfFile(_path.c_str());

    std::string* rd=(std::string*)readDict->objectForKey("test_key2");

    CCLOG("%s",rd->c_str());

oh! actually I had to read value as readDict->valueForKey(“test_key2”)>getCString* instead of
std::string
rd=readDict
>objectForKey(“test_key2”);

:slight_smile:

Hi all, i have tried to write plist file by CCDictionary::writeToFile(path), its good with iOS 6,5, but not work with iOS 7. Someone can help me

I also met the problem. By using Gautam Singh’s code, I still can not find the plist file. But the return value of writetofile is true. the returned path is “/Users/ycm/Library/Application Support/iPhone Simulator/6.1/Applications/35E38E9A-7107-44C7-802A-D031EF584ECB/Documents”. I go to this directory but can not find the plist file. Can anyone give some help?

I really don’t understand why cocos2d-x is wrapping specific OS resource management api: networking and file access. From my point of view, this is just unnecessary waste of devs time.

Because framework is C*+ based, you should just choose and use your platform best preferred way to use file storage for your structures serialization. Options are many. And by using cocos2d-x wrapper, you are just limiting yourself. So, the question should not be how to save c*+ structure in cocos2d-x, but “what is the best way to serialize c++ structure in (android/ios/windows/os x/linux)”. Ask Google :slight_smile:

cm Y, using :

CCFileUtils::sharedFileUtils()->getWritablePath();

you should get the correct path. At least in windows and Android it works perfectly. I can’t tell about IOS. Try to catch the value returned by the function above.