Monogame game settings
I'm developing a platformer using C# and monogame as a fun project to improve my skills. I want to add support for settings like audio, video, controls and more but I don't know the best way to do so.
I plan on having a XML file that stores all settings kind of like this:
<Settings>
<Audio>
<masterVolume>100</masterVolume>
<musicVolume>40</musicVolume>
<sfxVolume>90</sfxVolume>
</Audio>
<Video>
<Resolution>
<width>1920</width>
<height>1080</height>
</Resolution>
</Video>
<Controls>
<forward>W</forward>
<back>S</back>
<left>A</left>
<right>D</right>
</Controls>
</Settings>
My plan was to use a Settings class that has static variables for audio, video and controls etc that are divided into separate classes so that I can access them through Settings.Audio.MasterVolume or Settings.Controls.Forward.
I want to load the settings into these classes from the XML using Linq and I want to save the settings to the XML file when they are changed by the user.
I know that singletons can be used as well but as far as I can tell from the research I've done it has too many drawbacks. Is that true?
Is this a good way to do this or is there a better way that allows me to access the settings throughout the project without having everything static?
Thanks in advance!
c# xml linq linq-to-xml monogame
add a comment |
I'm developing a platformer using C# and monogame as a fun project to improve my skills. I want to add support for settings like audio, video, controls and more but I don't know the best way to do so.
I plan on having a XML file that stores all settings kind of like this:
<Settings>
<Audio>
<masterVolume>100</masterVolume>
<musicVolume>40</musicVolume>
<sfxVolume>90</sfxVolume>
</Audio>
<Video>
<Resolution>
<width>1920</width>
<height>1080</height>
</Resolution>
</Video>
<Controls>
<forward>W</forward>
<back>S</back>
<left>A</left>
<right>D</right>
</Controls>
</Settings>
My plan was to use a Settings class that has static variables for audio, video and controls etc that are divided into separate classes so that I can access them through Settings.Audio.MasterVolume or Settings.Controls.Forward.
I want to load the settings into these classes from the XML using Linq and I want to save the settings to the XML file when they are changed by the user.
I know that singletons can be used as well but as far as I can tell from the research I've done it has too many drawbacks. Is that true?
Is this a good way to do this or is there a better way that allows me to access the settings throughout the project without having everything static?
Thanks in advance!
c# xml linq linq-to-xml monogame
The main problem with using singletons is "global static state". The solution you've described is exactly that "a Settings class that has static variables for audio, video and controls". Just to be clear, a purestatic
method is fine. A global constant is fine and games are all about managing state but combining all 3 in this way can cause issues.
– craftworkgames
Jan 2 at 22:56
add a comment |
I'm developing a platformer using C# and monogame as a fun project to improve my skills. I want to add support for settings like audio, video, controls and more but I don't know the best way to do so.
I plan on having a XML file that stores all settings kind of like this:
<Settings>
<Audio>
<masterVolume>100</masterVolume>
<musicVolume>40</musicVolume>
<sfxVolume>90</sfxVolume>
</Audio>
<Video>
<Resolution>
<width>1920</width>
<height>1080</height>
</Resolution>
</Video>
<Controls>
<forward>W</forward>
<back>S</back>
<left>A</left>
<right>D</right>
</Controls>
</Settings>
My plan was to use a Settings class that has static variables for audio, video and controls etc that are divided into separate classes so that I can access them through Settings.Audio.MasterVolume or Settings.Controls.Forward.
I want to load the settings into these classes from the XML using Linq and I want to save the settings to the XML file when they are changed by the user.
I know that singletons can be used as well but as far as I can tell from the research I've done it has too many drawbacks. Is that true?
Is this a good way to do this or is there a better way that allows me to access the settings throughout the project without having everything static?
Thanks in advance!
c# xml linq linq-to-xml monogame
I'm developing a platformer using C# and monogame as a fun project to improve my skills. I want to add support for settings like audio, video, controls and more but I don't know the best way to do so.
I plan on having a XML file that stores all settings kind of like this:
<Settings>
<Audio>
<masterVolume>100</masterVolume>
<musicVolume>40</musicVolume>
<sfxVolume>90</sfxVolume>
</Audio>
<Video>
<Resolution>
<width>1920</width>
<height>1080</height>
</Resolution>
</Video>
<Controls>
<forward>W</forward>
<back>S</back>
<left>A</left>
<right>D</right>
</Controls>
</Settings>
My plan was to use a Settings class that has static variables for audio, video and controls etc that are divided into separate classes so that I can access them through Settings.Audio.MasterVolume or Settings.Controls.Forward.
I want to load the settings into these classes from the XML using Linq and I want to save the settings to the XML file when they are changed by the user.
I know that singletons can be used as well but as far as I can tell from the research I've done it has too many drawbacks. Is that true?
Is this a good way to do this or is there a better way that allows me to access the settings throughout the project without having everything static?
Thanks in advance!
c# xml linq linq-to-xml monogame
c# xml linq linq-to-xml monogame
edited Jan 1 at 16:33
TS1997
asked Jan 1 at 16:21
TS1997TS1997
237
237
The main problem with using singletons is "global static state". The solution you've described is exactly that "a Settings class that has static variables for audio, video and controls". Just to be clear, a purestatic
method is fine. A global constant is fine and games are all about managing state but combining all 3 in this way can cause issues.
– craftworkgames
Jan 2 at 22:56
add a comment |
The main problem with using singletons is "global static state". The solution you've described is exactly that "a Settings class that has static variables for audio, video and controls". Just to be clear, a purestatic
method is fine. A global constant is fine and games are all about managing state but combining all 3 in this way can cause issues.
– craftworkgames
Jan 2 at 22:56
The main problem with using singletons is "global static state". The solution you've described is exactly that "a Settings class that has static variables for audio, video and controls". Just to be clear, a pure
static
method is fine. A global constant is fine and games are all about managing state but combining all 3 in this way can cause issues.– craftworkgames
Jan 2 at 22:56
The main problem with using singletons is "global static state". The solution you've described is exactly that "a Settings class that has static variables for audio, video and controls". Just to be clear, a pure
static
method is fine. A global constant is fine and games are all about managing state but combining all 3 in this way can cause issues.– craftworkgames
Jan 2 at 22:56
add a comment |
2 Answers
2
active
oldest
votes
Your method works. However, you limit the re-usage of your class.
If you would describe MyClass
to others, would you say that the method being used to read the configuration parameters is essential for MyClass
? In other words: would most code of your class be meaningless if the configuration parameters wouldn't be read from a configuration file, but for instance from a CSV-file, or from the internet, or whatever method?
You'll probably say no: most code of my class could be reused if the configuration parameters were to be provided differently.
So why limit your class to a class that can only work if it reads the configuration parameters from a configuration file?
I guess that you currently have something like:
static class ConfigurationSettings
{
public static int LeftControl => ...
public static int RighControl => ...
}
class MyClass
{
// MyClass uses configuration settings:
public int LeftControl => ConfigurationSettings.LeftControl;
public int RightControl => ConfigurationSettings.RightControl;
...
}
You can't instantiate two objects of MyClass
, each with their own set of configuration parameters. You can't create a MyClass
object that uses a different method of providing configuration values.
One of the use cases I quite often need this is when unit testing: I want a quick way to be able to change the configuration settings without having to change the configuration file of the unit test project.
An easy way to allow users of your class to provide different methods for setting is to create an interface with the setting and provide a constructor with this interface:
interface IMySettings
{
int LeftControl {get;}
int RightControl {get;}
...
}
class ConfigurationSettings : IMySettings
{
// ConfigurationSettings reads settings from the configuration file
}
class MyClass
{
// default constructor use the configuration file via ConfigurationSettings:
public MyClass() : this (new ConfigurationSettings())
{
}
// extra constructor for those who don't want to use configuration file
public MyClass(IMySettings settings)
{
this.Settings = settings;
}
protected readonly IMySettings settings;
// MyClass uses settings:
public int LeftControl => this.settings.LeftControl;
public int RightControl => this.settings.RightControl;
}
Users who want to use the settings from the configuration file can use the default constructors; uses who want specific settings use the alternative constructor. This alternative constructor is also used if you want two different MyClass
objects, each with their own settings.
At first glance it seems that with minimal changes you can still use the configuration file. However, to be able to implement the interface, the class that reads the configuration file (MyClass
) can't be static.
However, you were right: there is only one configuration file, hence there should be only one instance of the class that reads from the configuration file: create a singleton.
In my experience, classes that represent a configuration, is one of the often used reasons to use a singleton instead of a static class
add a comment |
In my game projects I always use some static classes (and/or variables) to hold information that is valid through the whole game.
This might come in handy especially for audio settings if you want to be able to change the volume and so on from different points of the game.
This does not necessarily only include user settings. Thinkig of lowering the background music when some character is speaking.
long story short:
I would go for the static approach. But take care not to over exceed it.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53997024%2fmonogame-game-settings%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your method works. However, you limit the re-usage of your class.
If you would describe MyClass
to others, would you say that the method being used to read the configuration parameters is essential for MyClass
? In other words: would most code of your class be meaningless if the configuration parameters wouldn't be read from a configuration file, but for instance from a CSV-file, or from the internet, or whatever method?
You'll probably say no: most code of my class could be reused if the configuration parameters were to be provided differently.
So why limit your class to a class that can only work if it reads the configuration parameters from a configuration file?
I guess that you currently have something like:
static class ConfigurationSettings
{
public static int LeftControl => ...
public static int RighControl => ...
}
class MyClass
{
// MyClass uses configuration settings:
public int LeftControl => ConfigurationSettings.LeftControl;
public int RightControl => ConfigurationSettings.RightControl;
...
}
You can't instantiate two objects of MyClass
, each with their own set of configuration parameters. You can't create a MyClass
object that uses a different method of providing configuration values.
One of the use cases I quite often need this is when unit testing: I want a quick way to be able to change the configuration settings without having to change the configuration file of the unit test project.
An easy way to allow users of your class to provide different methods for setting is to create an interface with the setting and provide a constructor with this interface:
interface IMySettings
{
int LeftControl {get;}
int RightControl {get;}
...
}
class ConfigurationSettings : IMySettings
{
// ConfigurationSettings reads settings from the configuration file
}
class MyClass
{
// default constructor use the configuration file via ConfigurationSettings:
public MyClass() : this (new ConfigurationSettings())
{
}
// extra constructor for those who don't want to use configuration file
public MyClass(IMySettings settings)
{
this.Settings = settings;
}
protected readonly IMySettings settings;
// MyClass uses settings:
public int LeftControl => this.settings.LeftControl;
public int RightControl => this.settings.RightControl;
}
Users who want to use the settings from the configuration file can use the default constructors; uses who want specific settings use the alternative constructor. This alternative constructor is also used if you want two different MyClass
objects, each with their own settings.
At first glance it seems that with minimal changes you can still use the configuration file. However, to be able to implement the interface, the class that reads the configuration file (MyClass
) can't be static.
However, you were right: there is only one configuration file, hence there should be only one instance of the class that reads from the configuration file: create a singleton.
In my experience, classes that represent a configuration, is one of the often used reasons to use a singleton instead of a static class
add a comment |
Your method works. However, you limit the re-usage of your class.
If you would describe MyClass
to others, would you say that the method being used to read the configuration parameters is essential for MyClass
? In other words: would most code of your class be meaningless if the configuration parameters wouldn't be read from a configuration file, but for instance from a CSV-file, or from the internet, or whatever method?
You'll probably say no: most code of my class could be reused if the configuration parameters were to be provided differently.
So why limit your class to a class that can only work if it reads the configuration parameters from a configuration file?
I guess that you currently have something like:
static class ConfigurationSettings
{
public static int LeftControl => ...
public static int RighControl => ...
}
class MyClass
{
// MyClass uses configuration settings:
public int LeftControl => ConfigurationSettings.LeftControl;
public int RightControl => ConfigurationSettings.RightControl;
...
}
You can't instantiate two objects of MyClass
, each with their own set of configuration parameters. You can't create a MyClass
object that uses a different method of providing configuration values.
One of the use cases I quite often need this is when unit testing: I want a quick way to be able to change the configuration settings without having to change the configuration file of the unit test project.
An easy way to allow users of your class to provide different methods for setting is to create an interface with the setting and provide a constructor with this interface:
interface IMySettings
{
int LeftControl {get;}
int RightControl {get;}
...
}
class ConfigurationSettings : IMySettings
{
// ConfigurationSettings reads settings from the configuration file
}
class MyClass
{
// default constructor use the configuration file via ConfigurationSettings:
public MyClass() : this (new ConfigurationSettings())
{
}
// extra constructor for those who don't want to use configuration file
public MyClass(IMySettings settings)
{
this.Settings = settings;
}
protected readonly IMySettings settings;
// MyClass uses settings:
public int LeftControl => this.settings.LeftControl;
public int RightControl => this.settings.RightControl;
}
Users who want to use the settings from the configuration file can use the default constructors; uses who want specific settings use the alternative constructor. This alternative constructor is also used if you want two different MyClass
objects, each with their own settings.
At first glance it seems that with minimal changes you can still use the configuration file. However, to be able to implement the interface, the class that reads the configuration file (MyClass
) can't be static.
However, you were right: there is only one configuration file, hence there should be only one instance of the class that reads from the configuration file: create a singleton.
In my experience, classes that represent a configuration, is one of the often used reasons to use a singleton instead of a static class
add a comment |
Your method works. However, you limit the re-usage of your class.
If you would describe MyClass
to others, would you say that the method being used to read the configuration parameters is essential for MyClass
? In other words: would most code of your class be meaningless if the configuration parameters wouldn't be read from a configuration file, but for instance from a CSV-file, or from the internet, or whatever method?
You'll probably say no: most code of my class could be reused if the configuration parameters were to be provided differently.
So why limit your class to a class that can only work if it reads the configuration parameters from a configuration file?
I guess that you currently have something like:
static class ConfigurationSettings
{
public static int LeftControl => ...
public static int RighControl => ...
}
class MyClass
{
// MyClass uses configuration settings:
public int LeftControl => ConfigurationSettings.LeftControl;
public int RightControl => ConfigurationSettings.RightControl;
...
}
You can't instantiate two objects of MyClass
, each with their own set of configuration parameters. You can't create a MyClass
object that uses a different method of providing configuration values.
One of the use cases I quite often need this is when unit testing: I want a quick way to be able to change the configuration settings without having to change the configuration file of the unit test project.
An easy way to allow users of your class to provide different methods for setting is to create an interface with the setting and provide a constructor with this interface:
interface IMySettings
{
int LeftControl {get;}
int RightControl {get;}
...
}
class ConfigurationSettings : IMySettings
{
// ConfigurationSettings reads settings from the configuration file
}
class MyClass
{
// default constructor use the configuration file via ConfigurationSettings:
public MyClass() : this (new ConfigurationSettings())
{
}
// extra constructor for those who don't want to use configuration file
public MyClass(IMySettings settings)
{
this.Settings = settings;
}
protected readonly IMySettings settings;
// MyClass uses settings:
public int LeftControl => this.settings.LeftControl;
public int RightControl => this.settings.RightControl;
}
Users who want to use the settings from the configuration file can use the default constructors; uses who want specific settings use the alternative constructor. This alternative constructor is also used if you want two different MyClass
objects, each with their own settings.
At first glance it seems that with minimal changes you can still use the configuration file. However, to be able to implement the interface, the class that reads the configuration file (MyClass
) can't be static.
However, you were right: there is only one configuration file, hence there should be only one instance of the class that reads from the configuration file: create a singleton.
In my experience, classes that represent a configuration, is one of the often used reasons to use a singleton instead of a static class
Your method works. However, you limit the re-usage of your class.
If you would describe MyClass
to others, would you say that the method being used to read the configuration parameters is essential for MyClass
? In other words: would most code of your class be meaningless if the configuration parameters wouldn't be read from a configuration file, but for instance from a CSV-file, or from the internet, or whatever method?
You'll probably say no: most code of my class could be reused if the configuration parameters were to be provided differently.
So why limit your class to a class that can only work if it reads the configuration parameters from a configuration file?
I guess that you currently have something like:
static class ConfigurationSettings
{
public static int LeftControl => ...
public static int RighControl => ...
}
class MyClass
{
// MyClass uses configuration settings:
public int LeftControl => ConfigurationSettings.LeftControl;
public int RightControl => ConfigurationSettings.RightControl;
...
}
You can't instantiate two objects of MyClass
, each with their own set of configuration parameters. You can't create a MyClass
object that uses a different method of providing configuration values.
One of the use cases I quite often need this is when unit testing: I want a quick way to be able to change the configuration settings without having to change the configuration file of the unit test project.
An easy way to allow users of your class to provide different methods for setting is to create an interface with the setting and provide a constructor with this interface:
interface IMySettings
{
int LeftControl {get;}
int RightControl {get;}
...
}
class ConfigurationSettings : IMySettings
{
// ConfigurationSettings reads settings from the configuration file
}
class MyClass
{
// default constructor use the configuration file via ConfigurationSettings:
public MyClass() : this (new ConfigurationSettings())
{
}
// extra constructor for those who don't want to use configuration file
public MyClass(IMySettings settings)
{
this.Settings = settings;
}
protected readonly IMySettings settings;
// MyClass uses settings:
public int LeftControl => this.settings.LeftControl;
public int RightControl => this.settings.RightControl;
}
Users who want to use the settings from the configuration file can use the default constructors; uses who want specific settings use the alternative constructor. This alternative constructor is also used if you want two different MyClass
objects, each with their own settings.
At first glance it seems that with minimal changes you can still use the configuration file. However, to be able to implement the interface, the class that reads the configuration file (MyClass
) can't be static.
However, you were right: there is only one configuration file, hence there should be only one instance of the class that reads from the configuration file: create a singleton.
In my experience, classes that represent a configuration, is one of the often used reasons to use a singleton instead of a static class
answered Jan 2 at 8:18


Harald CoppoolseHarald Coppoolse
12.9k12964
12.9k12964
add a comment |
add a comment |
In my game projects I always use some static classes (and/or variables) to hold information that is valid through the whole game.
This might come in handy especially for audio settings if you want to be able to change the volume and so on from different points of the game.
This does not necessarily only include user settings. Thinkig of lowering the background music when some character is speaking.
long story short:
I would go for the static approach. But take care not to over exceed it.
add a comment |
In my game projects I always use some static classes (and/or variables) to hold information that is valid through the whole game.
This might come in handy especially for audio settings if you want to be able to change the volume and so on from different points of the game.
This does not necessarily only include user settings. Thinkig of lowering the background music when some character is speaking.
long story short:
I would go for the static approach. But take care not to over exceed it.
add a comment |
In my game projects I always use some static classes (and/or variables) to hold information that is valid through the whole game.
This might come in handy especially for audio settings if you want to be able to change the volume and so on from different points of the game.
This does not necessarily only include user settings. Thinkig of lowering the background music when some character is speaking.
long story short:
I would go for the static approach. But take care not to over exceed it.
In my game projects I always use some static classes (and/or variables) to hold information that is valid through the whole game.
This might come in handy especially for audio settings if you want to be able to change the volume and so on from different points of the game.
This does not necessarily only include user settings. Thinkig of lowering the background music when some character is speaking.
long story short:
I would go for the static approach. But take care not to over exceed it.
answered Jan 2 at 8:05
Pavel SlesingerPavel Slesinger
32918
32918
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53997024%2fmonogame-game-settings%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The main problem with using singletons is "global static state". The solution you've described is exactly that "a Settings class that has static variables for audio, video and controls". Just to be clear, a pure
static
method is fine. A global constant is fine and games are all about managing state but combining all 3 in this way can cause issues.– craftworkgames
Jan 2 at 22:56