Class GameSettingsExtensions
What a Game Studio project gets from its GameSettings asset, made available to a game
that has none.
public static class GameSettingsExtensions
- Inheritance
-
GameSettingsExtensions
Remarks
The engine reads a GameSettings asset in Game.PrepareContext and, only if it
finds one, registers itself as the IGameSettingsService, applies the rendering
settings to the graphics device manager, sets the shader compilation mode and the streaming
settings. Several subsystems then read the service on their own: AudioSystem for HRTF,
Bullet2PhysicsSystem for PhysicsSettings, BepuConfiguration for its
simulations, DynamicNavigationMeshSystem for NavigationSettings. A code-only game
has no asset, so none of that happens and every one of those subsystems runs on its fallback.
UseGameSettings(Game, Action<GameSettings>?) closes that gap: it builds a GameSettings in code,
registers it as the service, and applies it the way the engine would have. Call it before
Run.
Methods
UseGameSettings(Game, Action<GameSettings>?)
Registers a code-built GameSettings for a game that has no GameSettings
asset, and applies it the way the engine applies the asset; for a project that has the asset,
adds the configurations the asset lacks. Must be called before Run. A second call
adjusts and returns the settings the first one built.
public static GameSettings UseGameSettings(this Game game, Action<GameSettings>? configure = null)
Parameters
gameGameThe game to configure.
configureAction<GameSettings>Adjusts the settings before they are registered. On the first call the settings start empty - no configurations, and CompilationMode at its default - so nothing changes unless it is set here; add a configuration with GetOrCreateConfiguration<T>(). On a later call it runs on the settings already registered. Optional.
Returns
- GameSettings
The registered settings, for reading back or adjusting further before
Run.
Examples
using var game = new Game();
game.UseGameSettings(settings =>
{
settings.GetOrCreateConfiguration<AudioEngineSettings>().HrtfSupport = true; // Windows only; ignored on OpenAL
settings.GetOrCreateConfiguration<RenderingSettings>().DefaultBackBufferWidth = 1600;
settings.CompilationMode = CompilationMode.AppStore; // shipping build: optimised, no shader symbols
});
game.Run(start: Start);
Remarks
What gets applied, and when:
-
The settings are registered as the IGameSettingsService when
Runraises WindowCreated, which is after the engine has looked for aGameSettingsasset and before the audio, physics and navigation systems initialise and read the service. -
A RenderingSettings configuration, if one was added, is applied to the
GraphicsDeviceManager immediately - graphics profile, back buffer size and
colour space - mirroring
Game.PrepareContext, and again fromWindowCreated: with AutoLoadDefaultSettings on and no asset,PrepareContextwrites the engine's built-in defaults (feature level 10) over the device manager, so the caller's values are put back before the device is created. As in the engine, the back buffer and colour space are only applied while AutoLoadDefaultSettings is true. - CompilationMode and a StreamingSettings configuration, if one was added, are applied when the engine raises GameStarted - the point at which the EffectSystem exists and nothing has compiled yet.
On the compilation mode, measured rather than assumed: on Direct3D 11 the compiler applies the optimisation level only when the mode turns debug information off, so Debug (the engine's default for a game without settings) and Release produce identical bytecode. Only AppStore changes the output - optimisation level 2 with the debug symbols stripped, which also removes shader source from tools such as RenderDoc. Vulkan and Direct3D 12 consume the SPIR-V directly and ignore the mode. Bytecode is cached per mode, so changing it compiles every shader once more on the next run.
Asset URLs on the settings - default scene, graphics compositor, splash screen - are not applied: a code-only game builds those in code, and the toolkit's scene helpers are the way to do it.
Calling it more than once is fine: the callback runs on the settings the first call built, the rendering settings are applied again, and the same instance is returned - so one helper can add its physics configuration and another its audio one. The compilation mode and streaming settings are read from that shared instance when the game starts, so a later change to either still lands.
A project that does have a GameSettings asset can still call this. The engine registers
the asset as the service, and the asset stays the source of truth: its compilation mode and
every configuration it defines win, and the code settings only add the configurations it
lacks - a BepuConfiguration, say, in an asset that has none. Rendering settings from
code are applied to the device manager before Run and then overwritten by the asset's.
Exceptions
- ArgumentNullException
gameis null.- InvalidOperationException
The game is already running, or an IGameSettingsService was registered by hand.