playMaker

Author Topic: Exercise in Saving Data  (Read 3594 times)

artician

  • 1.2 Beta
  • Sr. Member
  • *
  • Posts: 318
Exercise in Saving Data
« on: June 18, 2011, 08:33:21 PM »
Hello all,

I thought I'd post how I'm tackling save-games in my project to see if anyone could learn anything from it, or likewise offer some ideas that might help me out.  This is the first time I'm dealing with data storage through Unity, using the PlayerPrefs actions.  It feels awkward, but doable!  

My project has 5 story objectives within it, with 20 collectible items.  The game saves the progress after an objective is fully completed, or when a collectible item is picked up.  

Progression through story objectives is linear, so I'm using an Int to store the progress for those.  If the Int is 0, the game begins with the intro.  Each time an objective is completed +1 is added to the Int.  This Int is read at runtime and the value determines the state of the world, relative to the objectives completed.  

Collectible items can be acquired in any order at any time, and since they are completely independent of the story and main objectives I was going to use one boolean for each item.

Finally, the way I will process these is to read the main story Int, and each of the 20 booleans at runtime/title screen.  Then I will load the save-game screen and have strings reflect the state of the games progress.  During gameplay, each time an item is acquired or an objective completed, the game will pause momentarily and write to the Int or associated Bool, effectively autosaving the state of the game.

That's as far as I've gotten.  I think it should work fine, but I wonder if I'm going about it wrong.  I hope this encourages discussion to help my situation and hopefully others too.  

As always, thanks for reading!

Xtopher

  • 1.2 Beta
  • Junior Playmaker
  • *
  • Posts: 71
    • Well Played Games
Re: Exercise in Saving Data
« Reply #1 on: June 19, 2011, 01:56:29 AM »
Sounds like you have thought this through pretty well.  Just a few thoughts...

Quote
Progression through story objectives is linear, so I'm using an Int to store the progress for those.  If the Int is 0, the game begins with the intro.  Each time an objective is completed +1 is added to the Int.

If you have only 5 objectives to track, this is probably ok.  But FWIW, I can share a little perspective from doing many large console and handheld games.  Generally you would save significant objectives with their own bool.  Done or Not Done.  This has a couple of advantages.  Games are always in flux until they ship, so if you decide to insert an extra objective in the middle, you will need to go update every node/script/line that accesses that one int!  This is guaranteed to generate a lot of bugs, confusion and wasted time.  And you always need to insert something.  For instance, maybe you realize you need to save the game state after a cut scene plays, or an autosave, or whatever.  Even though it's not a player-visible objective, it's still part of the linear game progression.  Another advantage is that you can do some odd testing to track down bugs, like manually set some objectives to true and others not, just to test systems in isolation for functionality.  Finally, there can be odd instances (like setting that int too late on a button press) where something is called twice by accident, which would then effectively skip an objective state.  Seems bullet proof that it wouldn't happen, but count on it, somehow, some way, it will at least once!


Quote
Finally, the way I will process these is to read the main story Int, and each of the 20 booleans at runtime/title screen

The general rule of thumb is to not check/load anything until you have to.  So if you need all this info, you are doing it in the right place, at the start.  Otherwise, you might be fine to just flip bools on the fly as you need to.  For instance, if you know the last 5 collectibles are not available to the player until level 5, there is no sense checking for them on levels 1 - 4 (unless you have a batch script and it would be more work to set it up otherwise).

Quote
During gameplay, each time an item is acquired or an objective completed, the game will pause momentarily and write to the Int or associated Bool, effectively autosaving the state of the game.

If you can do this without pausing, your players will love you for it!  If it's a performance hit to read/write during gameplay, just wait to do that stuff until you are playing an outro bit, or fading the screen before a level load, or whatever.  Hiding this stuff is always a more polished experience for the player.

Have fun!

artician

  • 1.2 Beta
  • Sr. Member
  • *
  • Posts: 318
Re: Exercise in Saving Data
« Reply #2 on: June 19, 2011, 04:33:24 AM »
Thanks for the reply, and for sharing your thoughts.  You make some really good points.  I did plan to possibly add more objectives as the game grows, so I'm taking your advice on unique booleans.  

Fun being had!

« Last Edit: June 20, 2011, 03:45:09 AM by artician »

artician

  • 1.2 Beta
  • Sr. Member
  • *
  • Posts: 318
Re: Exercise in Saving Data
« Reply #3 on: June 20, 2011, 03:44:50 AM »
I moved to the system you suggested, with unique boolean values dictating the state of each objective, and I ran into an issue regarding this. 
I am storing the boolean values in Ints as 1 or 0.  If I have 20 boolean values in a save-game, is the only way to store them to create 20 separate keys? 

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Exercise in Saving Data
« Reply #4 on: June 20, 2011, 12:21:12 PM »
Hi,

 I think this is not a bad thing to have 20 or more keys, if that makes your system flexible and powerfull. You can wrap this around a simple script that can be queried instead of accessing directly the data.

 One quick and dirty way around that is to store a string with 1 and 0 with each entries representing one boolean value. You need to hard code somehow what each entry represent, but it saves you from storing too much vars.

Also you could use binary as well ( more elegant ) : http://en.wikipedia.org/wiki/Binary_numeral_system

 This is how unity handle layers http://unity3d.com/support/documentation/Components/Layers.html

This could be used in your case maybe.

 Bye,

 Jean