Persistent data (user preferences, savegames)

1. Storing user preferences locally (UserConfig)

To manage persistent data, like user preferences or a simple save game values, use CastleConfig unit with a UserConfig singleton inside. A simple example:

uses CastleWindow, CastleConfig, CastleApplicationProperties, CastleControls,
  CastleColors;
var
  Window: TCastleWindow;
  LabelForParameter: TCastleLabel;
  MyParameter: string;
begin
  { set ApplicationName,
    this is used by UserConfig.Load to determine config file location. }
  ApplicationProperties.ApplicationName := 'my_game_name';
 
  { open Window }
  Window := TCastleWindow.Create(Application);
  Window.Container.BackgroundColor := White;
  Window.Open;
 
  { load UserConfig }
  UserConfig.Load;
 
  { load parameter from UserConfig }
  MyParameter := UserConfig.GetValue('my_parameter', 'default_value');
 
  { create UI and show show parameter from UserConfig }
  LabelForParameter := TCastleLabel.Create(Application);
  LabelForParameter.Caption := 'My parameter is now equal: ' + MyParameter;
  Window.Controls.InsertFront(LabelForParameter);
 
  { do the main part of your program }
  // MyParameter := 'some other value'; // test
  Application.Run;
 
  { save parameter }
  UserConfig.SetValue('my_parameter', MyParameter);
  // or like this:
  UserConfig.SetDeleteValue('my_parameter', MyParameter, 'default_value');
 
  { save UserConfig }
  UserConfig.Save;
end.

To load and save config values, you should use GetValue and SetValue (or SetDeleteValue) methods. See the TXMLConfig class documentation. These provide basic means to load/save integers, booleans and strings in a simple XML format.

We extend the standard TXMLConfig with more methods:

  • to load/save more types (floats, vectors, colors, URLs),
  • to load/save from an URL (not just a filename),
  • to encrypt/decrypt contents, which may be useful as a simple protection against cheaters (if you want this, just set the simple BlowFishKeyPhrase property).
  • to add "loader" functions (GetValue, GetVector3 etc.) that require the presence of given attribute in the XML file. They raise an exception when the attribute is missing or invalid. This is useful if you want to somewhat validate the XML file by the way (for example when it's a game model file that must contain given variables).

See the TCastleConfig for a documentation of our extensions.

Some engine components provide ready methods to load / save their configuration into a TCastleConfig instance (for example into the UserConfig). These include:

Note that the engine does not automatically call the load / save methods mentioned above. We used to call them automatically (in engine version <= 5.2.0), but this automatization was more trouble than gain. (It meant that UserConfig.Load could, often by surprise to the developer, override the sound parameters set by SoundEngine.ParseParameters or explicit SoundEngine.Enabled := false code.) So you're supposed to call them yourself (see example above) if you want to save these values as user preferences.

While you can load and save the config data at any time, you can also register your own load and save listeners using the TCastleConfig.AddLoadListener, TCastleConfig.AddSaveListener mechanism. This sometimes allows to decentralize your code better.

2. Storing user preferences in the cloud

On Android, our engine allows to easily upload and download the savegames using the Google Play Games "Saved Games" feature. To use this feature:

  1. Turn on the Google Play Games integration for your project.

  2. Create and initialize the TGameService instance in your code. Be sure to pass parameter SaveGames as true to the TGameService.Initialize call.

  3. Connect player to the Google Play Games at runtime, using TGameService.RequestSignedIn method, and / or passing AutoStartSignInFlow as true to the TGameService.Initialize call.

    You can wait for the sign-in to happen by the TGameService.OnSignedInChanged event, or just observe the TGameService.SignedIn property.

  4. Then load and save games using the TGameService.SaveGameLoad and TGameService.SaveGameSave methods. They represent the "savegame contents" as a simple string, and you can use the UserConfig.SaveToString and UserConfig.LoadFromString methods to trivially upload / download the UserConfig contents to the cloud!

  5. If you want to allow user to choose a "slot" where to save the game, or from which to load the game, you can use a ready dialog by calling TGameService.ShowSaveGames.