Game Settings
GenHub provides comprehensive management of game settings through the Options.ini file, supporting all configuration options for Command & Conquer Generals and Zero Hour. Settings are profile-specific, allowing each game profile to have its own custom configuration.
Overview
The game settings system handles:
- Video Settings: Resolution, windowed mode, texture quality, anti-aliasing, shadows
- Audio Settings: Volume levels for SFX, music, voice, and 3D audio
- Network Settings: GameSpy IP address for online/LAN play
- Profile-Specific Configuration: Each profile maintains its own settings
- Validation: Ensures settings are within valid ranges
- Preservation: Unknown settings are preserved for game-specific configurations
Settings Categories
Video Settings
Controls visual quality and display options.
public class VideoSettings
{
public int ResolutionWidth { get; set; } = 800;
public int ResolutionHeight { get; set; } = 600;
public bool Windowed { get; set; } = false;
public int TextureReduction { get; set; } = 0;
public int AntiAliasing { get; set; } = 1;
public bool UseShadowVolumes { get; set; } = false;
public bool UseShadowDecals { get; set; } = true;
public bool ExtraAnimations { get; set; } = true;
public int Gamma { get; set; } = 100;
}Key Settings:
Resolution: Screen width and height in pixels
- Common values:
800x600,1024x768,1920x1080,2560x1440 - Must match supported display modes
- Common values:
Windowed Mode: Run game in a window instead of fullscreen
true: Windowed modefalse: Fullscreen mode (default)
Texture Reduction: Controls texture quality (inverse scale)
0: Highest quality (no reduction)1: Medium quality2: Low quality3: Lowest quality
Texture Quality Enum: GenHub uses a more intuitive enum
csharppublic enum TextureQuality { Low = 0, Medium = 1, High = 2, VeryHigh = 3 // TheSuperHackers client only }NOTE
The
VeryHightexture quality option is only available when using TheSuperHackers game client. Other clients support Low, Medium, and High.Anti-Aliasing: Smooths jagged edges
0: Disabled1: 2x MSAA (default)2: 4x MSAA4: 8x MSAA
Shadow Volumes: Enables volumetric shadows (performance impact)
false: Disabled (default, better performance)true: Enabled (higher quality)
Shadow Decals: Enables shadow decals
true: Enabled (default)false: Disabled
Extra Animations: Enables additional visual effects
true: Enabled (default)false: Disabled (better performance)
Gamma: Brightness correction
- Range:
50(darker) to150(brighter) - Default:
100(neutral)
- Range:
Audio Settings
Controls sound and music volume levels.
public class AudioSettings
{
public int SFXVolume { get; set; } = 70;
public int SFX3DVolume { get; set; } = 70;
public int VoiceVolume { get; set; } = 70;
public int MusicVolume { get; set; } = 70;
public bool AudioEnabled { get; set; } = true;
public int NumSounds { get; set; } = 16;
}Key Settings:
SFXVolume: Sound effects volume
- Range:
0(muted) to100(maximum) - Default:
70
- Range:
SFX3DVolume: 3D positional sound effects volume
- Range:
0to100 - Default:
70
- Range:
VoiceVolume: Unit voice lines and dialogue volume
- Range:
0to100 - Default:
70
- Range:
MusicVolume: Background music volume
- Range:
0to100 - Default:
70
- Range:
AudioEnabled: Master audio toggle
true: Audio enabled (default)false: All audio disabled
NumSounds: Maximum simultaneous sounds
- Range:
2to32 - Default:
16 - Higher values improve audio quality but increase CPU usage
- Range:
Network Settings
Controls online and LAN play configuration.
public class NetworkSettings
{
public string? GameSpyIPAddress { get; set; }
}Key Settings:
GameSpyIPAddress: IP address for GameSpy/networking services
- Used for LAN and online multiplayer
- Format: IPv4 address (e.g.,
192.168.1.100) - Default:
null(auto-detect)
Use Cases:
- LAN Play: Set to local IP address for LAN games
- Online Play: Set to server IP for custom online services
- GenPatcher Integration: Used by community patches for online functionality
Example:
csharpprofile.GameSpyIPAddress = "192.168.1.100"; // LAN IP profile.GameSpyIPAddress = "server.example.com"; // Online server
IMPORTANT
The GameSpyIPAddress setting was added to support community online services and LAN play. It is stored in the Options.ini file and persisted per-profile.
Options.ini Structure
The Options.ini file is an INI-format configuration file located in the user's Documents folder:
- Generals:
Documents\Command and Conquer Generals Data\Options.ini - Zero Hour:
Documents\Command and Conquer Generals Zero Hour Data\Options.ini
Example Options.ini:
Resolution = 1920 1080
Windowed = 0
TextureReduction = 0
AntiAliasing = 1
UseShadowVolumes = 0
UseShadowDecals = 1
ExtraAnimations = 1
Gamma = 100
SFXVolume = 70
SFX3DVolume = 70
VoiceVolume = 70
MusicVolume = 70
AudioEnabled = 1
NumSounds = 16
GameSpyIPAddress = 192.168.1.100Core Services
GameSettingsService
Handles parsing and serialization of Options.ini files.
Location: GenHub.Features.GameSettings.GameSettingsService
Key Methods:
public interface IGameSettingsService
{
// Load settings from Options.ini
Task<OperationResult<IniOptions>> LoadSettingsAsync(
GameType gameType,
CancellationToken cancellationToken = default);
// Save settings to Options.ini
Task<OperationResult> SaveSettingsAsync(
IniOptions options,
GameType gameType,
CancellationToken cancellationToken = default);
// Get default settings
IniOptions GetDefaultSettings();
}Responsibilities:
- Parse INI file format into structured
IniOptionsmodel - Serialize
IniOptionsback to INI format - Preserve unknown settings via
AdditionalProperties - Validate setting ranges and formats
- Handle missing or corrupted files
GameSettingsMapper
Maps settings between GameProfile and IniOptions.
Location: GenHub.Core.Helpers.GameSettingsMapper
Purpose: Ensures profile-specific settings are correctly applied to the game's Options.ini file.
public static class GameSettingsMapper
{
public static void MapProfileToIniOptions(GameProfile profile, IniOptions options);
public static void MapIniOptionsToProfile(IniOptions options, GameProfile profile);
}Mapping Example:
// Profile → Options.ini
if (profile.GameSpyIPAddress != null)
{
options.Network.GameSpyIPAddress = profile.GameSpyIPAddress;
}
// Options.ini → Profile
profile.GameSpyIPAddress = options.Network.GameSpyIPAddress;GameSettingsViewModel
Provides UI binding and validation for game settings.
Location: GenHub.Features.GameProfiles.ViewModels.GameSettingsViewModel
Key Properties:
[ObservableProperty]
private string? _gameSpyIPAddress;
[ObservableProperty]
private int _resolutionWidth;
[ObservableProperty]
private int _resolutionHeight;
[ObservableProperty]
private bool _windowed;
[ObservableProperty]
private int _sfxVolume;
// ... other settingsResponsibilities:
- Expose settings as observable properties for UI binding
- Validate user input (e.g., resolution ranges, volume 0-100)
- Load settings from profile or
Options.ini - Save settings back to profile and
Options.ini - Provide default values
Profile Integration
Game settings are stored at two levels:
Profile-Level: Settings specific to a game profile
- Stored in
GameProfilemodel - Persisted in profile database
- Applied when profile is launched
- Stored in
Options.ini: Game's configuration file
- Updated when profile is launched
- Read by the game executable
- Shared across all profiles (overwritten on launch)
Launch Flow
When a profile is launched:
- Load Profile Settings: Retrieve settings from
GameProfile - Map to IniOptions: Convert profile settings to
IniOptionsmodel - Write Options.ini: Serialize
IniOptionsto game'sOptions.inifile - Launch Game: Game reads
Options.inion startup
Settings Persistence
// Creating a profile with custom settings
var createRequest = new CreateProfileRequest
{
Name = "My Profile",
GameSpyIPAddress = "192.168.1.100",
// ... other settings
};
// Updating profile settings
var updateRequest = new UpdateProfileRequest
{
GameSpyIPAddress = "192.168.1.200",
// ... other settings
};UI Integration
GameSettingsView
Location: GenHub.Features.GameProfiles.Views.GameSettingsView.axaml
Provides UI controls for editing game settings:
- Video Tab: Resolution, windowed mode, texture quality, anti-aliasing, shadows
- Audio Tab: Volume sliders for SFX, music, voice, 3D audio
- Network Tab: GameSpy IP address input field
- Advanced Tab: Additional game-specific settings
Example XAML (Network Settings):
<TextBox
Text="{Binding GameSpyIPAddress}"
Watermark="192.168.1.100 or server.example.com"
ToolTip.Tip="IP address for GameSpy/networking services (LAN or online play)" />Validation
Settings are validated on input:
// Resolution validation
if (ResolutionWidth < 640 || ResolutionWidth > 7680)
{
errors.Add("Resolution width must be between 640 and 7680");
}
// Volume validation
if (SFXVolume < 0 || SFXVolume > 100)
{
errors.Add("Volume must be between 0 and 100");
}
// IP address validation (optional)
if (!string.IsNullOrEmpty(GameSpyIPAddress) && !IsValidIPAddress(GameSpyIPAddress))
{
errors.Add("Invalid IP address format");
}Best Practices
For Developers
Always Validate Settings: Check ranges and formats before saving
csharpif (volume < 0 || volume > 100) throw new ArgumentOutOfRangeException(nameof(volume));Preserve Unknown Settings: Use
AdditionalPropertiesto maintain game-specific settingscsharpforeach (var kvp in additionalSettings) { options.Video.AdditionalProperties[kvp.Key] = kvp.Value; }Handle Missing Files: Provide sensible defaults if
Options.inidoesn't existcsharpif (!File.Exists(optionsPath)) { return GetDefaultSettings(); }Log Setting Changes: Track when settings are modified for debugging
csharplogger.LogInformation("Updated GameSpyIPAddress from {Old} to {New}", oldValue, newValue);
For Users
- Test Settings: Verify settings work before saving
- Backup Options.ini: Keep a backup of working configurations
- Use Presets: Start with default settings and adjust as needed
- Profile-Specific Settings: Create separate profiles for different configurations (e.g., LAN vs Online)
Future Enhancements
Potential improvements under consideration:
- Setting Presets: Pre-configured settings for Low/Medium/High/Ultra quality
- Auto-Detection: Automatically detect optimal settings based on hardware
- Setting Profiles: Save and load named setting configurations
- Validation UI: Real-time validation feedback in settings UI
- Import/Export: Share settings between profiles or users
