Hi !
Featured games (84)
games approved by the League of Dukes
Games in Showcase (595)
Games in Android Showcase (168)
games submitted by our members
Games in WIP (646)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Savegames  (Read 2390 times)
0 Members and 1 Guest are viewing this topic.
Offline Damocles
« Posted 2012-04-26 20:14:17 »

Im a beginner in game development (well not really)

Anyhow. What is your experience when creating saves for a game.

What is the best approach when saving a more complex dynamic environment (not just stome level-stats)

Do you serialize all objects. And if yes, what are the traps.
Or do you save everything manually with a custom saver/loader.

Up until now I usually just saved savepoints using some general stats. Never within a gameloop the complete enviroment.
Looking for an efficient way to create savegames.

Offline _Al3x

Senior Devvie

Medals: 7

Indie Games FTW!

« Reply #1 - Posted 2012-04-26 20:22:36 »

This is relevant to my interests Smiley

Offline UprightPath
« Reply #2 - Posted 2012-04-26 20:49:09 »

If the data that you want to save is going to be highly decoupled from the rest of the world, then one of the easiest ways to save/load data is to use the built in serialize function. Basically, it writes out all of the data from the object, including information about its class, then allows it to be read back in at a later date.

By highly decoupled, I mean that you could take the data and remove it from its context without damaging the information. Example:
public class Character {
    static final long serialVersionUID = -6618469841127325812L; //Serialization ID, required to ensure that the file is recognized as being this class if changes happen.
    private int currentX;
    private int currentY;
    private int currentHealth;
    private int currentExp;
    private int currentWorldId;
    private transient World currentWorld;

We have enough information there, I would hope, that you can not completely save the 'currentWorld' field to the disc and could, instead, use the currentWorldId to help restore. Anything you don't want to save would be marked with the transient keyword. If you need to save data about your world, then you'd remove the transient and then blah, blah, blah.

This is made much easier if you only allow saving at certain points (Think the Metroid games or old school RPGs where you could handle most state data with the character information then a bunch of flags).

There is a caveat though, that saving data like this is somewhat problematic if you change the class and attempt to reload the data there's a chance it won't work correctly, however using the serialVersionUID field will help with this.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Damocles
« Reply #3 - Posted 2012-04-26 20:58:24 »

Yes true. I plan to have some updates late to the game.
Thus changing classes would potentially crap old savegames.

Also I use static declarations, wich seem not to get saves (unless manually told so)

Totally forgot about the transient keyword too.

Im still stuck beteen 2 solutions:
saving the gameworld as a whole
Advantage: automated and thus easy
Disadvantage: potentially loosing data (static definitions), and having a problem importing old savegames to an updated game.

lots of manual work defining saving functions
potential bugs of missing out data to save/resotore

Advantage: I can craft a savegame format that keeps well defined to import it into an updated game.

Offline UprightPath
« Reply #4 - Posted 2012-04-26 21:06:41 »

Ugh, why are you using static variables!? If you feel that your character/whatever's state must be reached through static means, then use...
public class SomeClass {
    private static SomeClass instance;
    public static SomeClass getInstance() {
        if(instance == null) {
            instance = new SomeClass();
        return instance;

Using a completely static class is silly.

Offline jonjava
« Reply #5 - Posted 2012-04-26 21:07:08 »

I recently dealt with information that needed to be transferred and saved, but the information structure changed a lot (Things were added). So I simply just used a plain old tagging system. And simply modified the interpreter to recognize new tags.

Here's a basic example:


It's not exactly optimized nor secure. But it didn't need to be, it was easy to change around info.

Offline sproingie

JGO Kernel

Medals: 202

« Reply #6 - Posted 2012-04-26 21:12:26 »

Looks a lot like json to me, you may as well just use that.
Offline UprightPath
« Reply #7 - Posted 2012-04-26 21:14:42 »

Whatever works works.

Also, I've been meaning to say: "Are you saying 'Hello', 'Good-bye' or  'It may be just vital biomass oxygenating the planet to you, but it's home to me'."

Offline Ultroman

JGO Knight

Medals: 25
Projects: 1

Snappin' at snizzes since '83

« Reply #8 - Posted 2012-04-27 19:52:04 »

I've done it in an entirely different way. Maybe it's a bit over the top, but I thought it did exactly what I wanted for my RPG-game.

When loading a savegame, any Ability and Item the Player has, including the Buyback-arraylist, will be updated to the ones that are in the game, and any companions also get their equipment and abilities updated. This means that you can use old saves whenever there's a new version, and your items will be updated to the corresponding ones in the new version of the game.

My load-method deserializes a Player-object from the saves-file (a serialized ArrayList of Player-objects), passes it into a (horribly named) method ensureLoadedPlayerIntegrity(Player p), which runs through all loops of content the Player has, finds the id of every object and replaces it with the corresponding object in the game. So you'll never have to scrap your savegames because a new version is out. Unless I completely rework the Player-class. It also saves a mapId and the player-position on the map.

- Jonas
Offline UprightPath
« Reply #9 - Posted 2012-04-27 19:59:09 »

That isn't a horrible name for a method! That's a self documenting method name. Which are useful. If someone can't get most of the information about a method from its name and parameters, you're probably doing something wrong.

I mean, it's much, much better than calling it public void foo(Object obj0, Object obj1) or something like that. And honestly, if you can manage to do something like that and ensure that it works for all prior versions of a save then you're doing good.

However, I would suggest that once you get to a release state for your game, you make separate 'import' methods for each game version, perhaps even do it recursively. Such as v0.1->v0.2->v0.3->v0.4, instead of v0.1->v0.4 or only having v0.3->v0.4. At least if you want to ensure that you'll cover all of the older versions. Cheesy

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Ultroman

JGO Knight

Medals: 25
Projects: 1

Snappin' at snizzes since '83

« Reply #10 - Posted 2012-04-30 21:42:38 »

Well, thank you very much Smiley I just thought it was a kinda long name, but it IS named exactly that for the very reason you said.

I worked damn hard at it too. The secret is really just thinking "database", having ids for each item and ability in the game, so if I change item X with id=1 in a new version, then when the player loads a save where he has an item with id=1 in his inventory, it is replaced by the one loaded into the game at init. As long as I don't screw around with the ids between versions, it should work just fine. I don't store anything but references in the abilities or items, so the memory-footprint is surprisingly low.
Of course I should probably unload the "database" from memory until the player tries to load a game again, but for now I have an inventory panel to design *sigh*

With the current setup I won't be needing version-checking, but I can see how it would benefit me when I do a "release"-version. Especially when I start having quests and such in it.

- Jonas
Offline UprightPath
« Reply #11 - Posted 2012-04-30 22:11:59 »

That's exactly right!

I know a lot of DB people who bitch and moan about biometrics for making keys for entries in a Database, which is all very good and fine. So long as you're not changing the structure fairly often.

In the case of a living, breathing database which is filled with objects which are changing their shape all of the time: IE- where objects might lose an important field for whatever reason, then using a generated ID sounds like the best bet.

Pages: [1]
  ignore  |  Print  
You cannot reply to this message, because it is very, very old.

deepthought (49 views)
2015-06-30 15:39:44

deepthought (56 views)
2015-06-30 15:39:09

deepthought (65 views)
2015-06-30 15:36:52

Za\'Anzabar (43 views)
2015-06-29 05:44:54

TritonDreyja (49 views)
2015-06-24 17:10:40

CopyableCougar4 (49 views)
2015-06-23 00:34:45

BurntPizza (58 views)
2015-06-21 20:36:46

cookiecompiler (98 views)
2015-06-11 15:42:53

cookiecompiler (58 views)
2015-06-11 15:41:14

NegativeZero (81 views)
2015-06-11 09:49:18
How Do I Expand My Game?
by bashfrog
2015-06-14 11:34:43

List of Learning Resources
by PocketCrafter7
2015-05-31 05:37:30

Intersection Methods
by Roquen
2015-05-29 08:19:33

List of Learning Resources
by SilverTiger
2015-05-05 10:20:32

How to: JGO Wiki
by Mac70
2015-02-17 20:56:16

2D Dynamic Lighting
by ThePixelPony
2015-01-01 20:25:42

How do I start Java Game Development?
by gouessej
2014-12-27 19:41:21

Resources for WIP games
by kpars
2014-12-18 10:26:14 is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!