Being able to load settings into a game is a must. There are a number of ways to accomplish this. My current method works well enough for now, although it needs a bit of work in a few areas. I accomplish this by creating a series of settings classes that can be serialized into XML and back again at run time using my simple serializer.
Settings Manager
public class SettingsManager
{
const string Extension = ".xml";
const string Directory = "Content\\Settings\\";
/// <summary>
/// Loaded settings - Not currently implemented
/// </summary>
//SerializableDictionary<string, SettingsBase> _settings;
/// <summary>
/// Constructor
/// </summary>
public SettingsManager()
{
}
/// <summary>
/// Load a settings file
/// </summary>
public T Load<T>()
{
Type t = typeof(T);
return Load<T>(t.Name);
}
/// <summary>
/// Attempt to load a settings file. If not found, it will
/// load a new, default instance of the settings class.
/// </summary>
public T Load<T>(string name)
{
try
{
return Serializer.Read<T>(
SettingsManager.Directory +
name +
SettingsManager.Extension);
}
catch (Exception e)
{
e = null;
Type t = typeof(T);
return (T)Activator.CreateInstance(t);
}
}
/// <summary>
/// Save a settings object
/// </summary>
/// <typeparam name="T"></typeparam>
public void Save<T>(T o)
{
Type t = typeof(T);
Save<T>(o, t.Name);
}
/// <summary>
/// Save a settings object
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="file_name"></param>
public void Save<T>(T o, string name)
{
Serializer.Write<T>(
o,
SettingsManager.Directory + name + SettingsManager.Extension);
}
}
The basic idea is that we can load and save settings files either based on an arbitrary name or, for simplicity, the settings class Type.Name. This is still a rough class - it assumes a lot about the settings files being loaded such as the files being serializable. I currently have a simple class that settings files inherit from:
Settings Base
[Serializable]
public abstract class SettingsBase
{
}
More functionality could be added here such as a Save() function that allowed settings objects to save themselves via the SettingsManager. The only special thing in this class is adding the [Serializable] tag at the top to ensure that all inheriting objects get this.
Simple Settings Example
public class PlayerSettings : SettingsBase
{
public int Id;
public string Name;
public PlayerSettings()
{
Id = 1;
Name = "Spartacus";
}
}
Now, the settings manager can be used to load/save this.
// Load default settings PlayerSettings ps = settingsManager.Load<PlayerSettings>(); // Change something ps.Name = "Hercules"; // Save with default name settingsManager.Save<PlayerSettings>(ps);
Future Improvements
- SettingsManager does not ensure that loaded files inherit from SettingsBase at all.
- SettingsManager does not track previously loaded settings files. Tracking and storing loaded files would prevent costly file IO, deserialization and reflection.
- Settings classes assume that the constructor will set the default settings.