21. Persistent data (user preferences, savegames)

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 SysUtils, CastleWindow, CastleConfig;
 
var
  Window: TCastleWindow;
  MyParameter: string;
 
function MyGetApplicationName: string;
begin
  Result := 'my_game_name';
end;
 
begin
  { make sure application name is correct by setting OnGetApplicationName,
    this is used by UserConfig.Load to determine config file location. }
  OnGetApplicationName := @MyGetApplicationName;
 
  { load config from file }
  UserConfig.Load;
  // SoundEngine.LoadFromConfig(UserConfig); // load sound parameters (enabled, volume...)
  // InputsAll.LoadFromConfig(UserConfig); // load keyboard shortcuts configuration
 
  { load your own data like this: }
  MyParameter := UserConfig.GetValue('my_parameter', 'default_value');
 
  { ... do the main part of your program }
  Window := TCastleWindow.Create(Application);
  Window.OpenAndRun;
 
  { save your own data like this: }
  UserConfig.SetValue('my_parameter', MyParameter);
  // or like this:
  UserConfig.SetDeleteValue('my_parameter', MyParameter, 'default_value');
 
  { save config to file }
  // SoundEngine.SaveToConfig(UserConfig); // save sound configuration
  // InputsAll.SaveToConfig(UserConfig); // save keyboard shortcuts configuration
  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).

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.