diff --git a/docs/compatibility.csv b/docs/compatibility.csv
index 0fd8eadca..4cf9102bd 100644
--- a/docs/compatibility.csv
+++ b/docs/compatibility.csv
@@ -2480,6 +2480,7 @@
010081C0191D8000,"Rune Factory 3 Special",,playable,2023-10-15 08:32:49
010051D00E3A4000,"Rune Factory 4 Special",32-bit;crash;nvdec,ingame,2023-05-06 08:49:17
010014D01216E000,"Rune Factory 5 (JP)",gpu,ingame,2021-06-01 12:00:36
+010071E0145F8000,"Rustler",,playable,2025-02-10 20:17:12
0100E21013908000,"RWBY: Grimm Eclipse - Definitive Edition",online-broken,playable,2022-11-03 10:44:01
010012C0060F0000,"RXN -Raijin-",nvdec,playable,2021-01-10 16:05:43
0100B8B012ECA000,"S.N.I.P.E.R. - Hunter Scope",,playable,2021-04-19 15:58:09
diff --git a/src/Ryujinx.Common/TitleIDs.cs b/src/Ryujinx.Common/TitleIDs.cs
index 28d332a61..76d873f60 100644
--- a/src/Ryujinx.Common/TitleIDs.cs
+++ b/src/Ryujinx.Common/TitleIDs.cs
@@ -219,6 +219,7 @@ namespace Ryujinx.Common
//Misc Games
"010056e00853a000", // A Hat in Time
"0100fd1014726000", // Baldurs Gate: Dark Alliance
+ "01008c2019598000", // Bluey: The Video Game
"0100c6800b934000", // Brawlhalla
"0100dbf01000a000", // Burnout Paradise Remastered
"0100744001588000", // Cars 3: Driven to Win
diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json
index 71a86348c..1098a88e1 100644
--- a/src/Ryujinx/Assets/locales.json
+++ b/src/Ryujinx/Assets/locales.json
@@ -3425,26 +3425,101 @@
{
"ID": "SettingsTabGeneralCheckUpdatesOnLaunch",
"Translations": {
- "ar_SA": "التحقق من وجود تحديثات عند التشغيل",
- "de_DE": "Beim Start nach Updates suchen",
- "el_GR": "Έλεγχος για Ενημερώσεις στην Εκκίνηση",
- "en_US": "Check for Updates on Launch",
- "es_ES": "Buscar actualizaciones al iniciar",
- "fr_FR": "Vérifier les mises à jour au démarrage",
- "he_IL": "בדוק אם קיימים עדכונים בהפעלה",
- "it_IT": "Controlla aggiornamenti all'avvio",
- "ja_JP": "起動時にアップデートを確認する",
- "ko_KR": "시작 시, 업데이트 확인",
- "no_NO": "Se etter oppdateringer ved oppstart",
- "pl_PL": "Sprawdzaj aktualizacje przy uruchomieniu",
- "pt_BR": "Verificar se há atualizações ao iniciar",
- "ru_RU": "Проверять наличие обновлений при запуске",
- "sv_SE": "Leta efter uppdatering vid uppstart",
- "th_TH": "ตรวจหาการอัปเดตเมื่อเปิดโปรแกรม",
- "tr_TR": "Her Açılışta Güncellemeleri Denetle",
- "uk_UA": "Перевіряти наявність оновлень під час запуску",
- "zh_CN": "启动时检查更新",
- "zh_TW": "啟動時檢查更新"
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Check for Updates:",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
+ {
+ "ID": "SettingsTabGeneralCheckUpdatesOnLaunchOff",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Off",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
+ {
+ "ID": "SettingsTabGeneralCheckUpdatesOnLaunchPromptAtStartup",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Prompt",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
+ {
+ "ID": "SettingsTabGeneralCheckUpdatesOnLaunchBackground",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Background",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
}
},
{
@@ -17772,6 +17847,31 @@
"zh_TW": "更新已停用!"
}
},
+ {
+ "ID": "UpdaterBackgroundStatusBarButtonText",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Update Available!",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
{
"ID": "ControllerSettingsRotate90",
"Translations": {
diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
index d78ccc78d..db04e687b 100644
--- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
@@ -7,6 +7,7 @@ using Avalonia.Media.Imaging;
using Avalonia.Platform.Storage;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
using DynamicData;
using DynamicData.Binding;
using FluentAvalonia.UI.Controls;
@@ -104,6 +105,13 @@ namespace Ryujinx.Ava.UI.ViewModels
[ObservableProperty] private bool _isSubMenuOpen;
[ObservableProperty] private ApplicationContextMenu _listAppContextMenu;
[ObservableProperty] private ApplicationContextMenu _gridAppContextMenu;
+ [ObservableProperty] private bool _updateAvailable;
+
+ public static AsyncRelayCommand UpdateCommand => Commands.Create(async () =>
+ {
+ if (Updater.CanUpdate(true))
+ await Updater.BeginUpdateAsync(true);
+ });
private bool _showLoadProgress;
private bool _isGameRunning;
diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index 40f936e29..5e8fb0a83 100644
--- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
@@ -15,6 +15,7 @@ using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Utilities.Configuration.System;
+using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver;
@@ -135,6 +136,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool RememberWindowState { get; set; }
public bool ShowTitleBar { get; set; }
public int HideCursor { get; set; }
+ public int UpdateCheckerType { get; set; }
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
public bool EnableMouse { get; set; }
@@ -532,6 +534,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
ConfigurationState config = ConfigurationState.Instance;
+
//It is necessary that the data is used from the global configuration file
if (string.IsNullOrEmpty(GameId))
{
@@ -542,7 +545,8 @@ namespace Ryujinx.Ava.UI.ViewModels
RememberWindowState = config.RememberWindowState;
ShowTitleBar = config.ShowTitleBar;
HideCursor = (int)config.HideCursor.Value;
-
+ UpdateCheckerType = (int)config.UpdateCheckerType.Value;
+
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);
@@ -643,6 +647,7 @@ namespace Ryujinx.Ava.UI.ViewModels
ConfigurationState config = ConfigurationState.Instance;
bool userConfigFile = string.IsNullOrEmpty(GameId);
+
if (userConfigFile)
{
// User Interface
@@ -652,6 +657,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.RememberWindowState.Value = RememberWindowState;
config.ShowTitleBar.Value = ShowTitleBar;
config.HideCursor.Value = (HideCursorMode)HideCursor;
+ config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType;
if (GameDirectoryChanged)
{
diff --git a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
index a0259c723..98416654b 100644
--- a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
@@ -23,7 +23,7 @@
Background="{DynamicResource ThemeContentBackgroundColor}"
DockPanel.Dock="Bottom"
IsVisible="{Binding ShowMenuAndStatusBar}"
- ColumnDefinitions="Auto,Auto,*,Auto,Auto">
+ ColumnDefinitions="Auto,Auto,*,Auto,Auto,Auto">
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
index 77f9b7bf5..d71a7d795 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
@@ -6,6 +6,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
+ xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel">
@@ -30,18 +31,33 @@
ToolTip.Tip="{ext:Locale ToggleDiscordTooltip}"
Text="{ext:Locale SettingsTabGeneralEnableDiscordRichPresence}" />
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
AddDirButton(GameDirPathBox, ViewModel.GameDirectories, true));
AddAutoloadDirButton.Command =
diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
index 120b82ff3..1def5c2fb 100644
--- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
@@ -19,6 +19,7 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration;
+using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging;
@@ -400,10 +401,21 @@ namespace Ryujinx.Ava.UI.Windows
await Dispatcher.UIThread.InvokeAsync(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys));
}
- if (ConfigurationState.Instance.CheckUpdatesOnStart && !CommandLineState.HideAvailableUpdates && Updater.CanUpdate())
+ if (!Updater.CanUpdate() || CommandLineState.HideAvailableUpdates)
+ return;
+
+ switch (ConfigurationState.Instance.UpdateCheckerType.Value)
{
- await Updater.BeginUpdateAsync()
- .Catch(task => Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}"));
+ case UpdaterType.PromptAtStartup:
+ await Updater.BeginUpdateAsync()
+ .Catch(task => Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}"));
+ break;
+ case UpdaterType.CheckInBackground:
+ if ((await Updater.CheckVersionAsync()).TryGet(out (Version Current, Version Incoming) versions))
+ {
+ Dispatcher.UIThread.Post(() => RyujinxApp.MainWindow.ViewModel.UpdateAvailable = versions.Current < versions.Incoming);
+ }
+ break;
}
}
diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs
index f8b4b2beb..338e9de43 100644
--- a/src/Ryujinx/Updater.cs
+++ b/src/Ryujinx/Updater.cs
@@ -43,7 +43,18 @@ namespace Ryujinx.Ava
private const int ConnectionCount = 4;
private static string _buildVer;
- private static string _platformExt;
+
+ private static readonly string _platformExt =
+ RunningPlatform.IsMacOS
+ ? "macos_universal.app.tar.gz"
+ : RunningPlatform.IsWindows
+ ? "win_x64.zip"
+ : RunningPlatform.IsX64Linux
+ ? "linux_x64.tar.gz"
+ : RunningPlatform.IsArmLinux
+ ? "linux_arm64.tar.gz"
+ : throw new PlatformNotSupportedException();
+
private static string _buildUrl;
private static long _buildSize;
private static bool _updateSuccessful;
@@ -51,30 +62,8 @@ namespace Ryujinx.Ava
private static readonly string[] _windowsDependencyDirs = [];
- public static async Task BeginUpdateAsync(bool showVersionUpToDate = false)
+ public static async Task> CheckVersionAsync(bool showVersionUpToDate = false)
{
- if (_running)
- {
- return;
- }
-
- _running = true;
-
- // Detect current platform
- if (OperatingSystem.IsMacOS())
- {
- _platformExt = "macos_universal.app.tar.gz";
- }
- else if (OperatingSystem.IsWindows())
- {
- _platformExt = "win_x64.zip";
- }
- else if (OperatingSystem.IsLinux())
- {
- string arch = RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64";
- _platformExt = $"linux_{arch}.tar.gz";
- }
-
if (!Version.TryParse(Program.Version, out Version currentVersion))
{
Logger.Error?.Print(LogClass.Application, $"Failed to convert the current {RyujinxApp.FullAppName} version!");
@@ -85,7 +74,7 @@ namespace Ryujinx.Ava
_running = false;
- return;
+ return default;
}
Logger.Info?.Print(LogClass.Application, "Checking for updates.");
@@ -123,7 +112,7 @@ namespace Ryujinx.Ava
_running = false;
- return;
+ return default;
}
break;
@@ -149,7 +138,7 @@ namespace Ryujinx.Ava
_running = false;
- return;
+ return default;
}
}
catch (Exception exception)
@@ -161,7 +150,7 @@ namespace Ryujinx.Ava
_running = false;
- return;
+ return default;
}
if (!Version.TryParse(_buildVer, out Version newVersion))
@@ -174,9 +163,27 @@ namespace Ryujinx.Ava
_running = false;
+ return default;
+ }
+
+ return (currentVersion, newVersion);
+ }
+
+ public static async Task BeginUpdateAsync(bool showVersionUpToDate = false)
+ {
+ if (_running)
+ {
return;
}
+ _running = true;
+
+ Optional<(Version, Version)> versionTuple = await CheckVersionAsync(showVersionUpToDate);
+
+ if (_running is false || !versionTuple.HasValue) return;
+
+ (Version currentVersion, Version newVersion) = versionTuple.Value;
+
if (newVersion <= currentVersion)
{
if (showVersionUpToDate)
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs
index 95364873b..d7235ef27 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 64;
+ public const int CurrentVersion = 65;
///
/// Version of the configuration file format
@@ -163,9 +163,14 @@ namespace Ryujinx.Ava.Utilities.Configuration
public bool EnableDiscordIntegration { get; set; }
///
- /// Checks for updates when Ryujinx starts when enabled
+ /// DEPRECATED: Checks for updates when Ryujinx starts when enabled
///
public bool CheckUpdatesOnStart { get; set; }
+
+ ///
+ /// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
+ ///
+ public UpdaterType UpdateCheckerType { get; set; }
///
/// Show "Confirm Exit" Dialog
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
index 18f801a0e..571e93991 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
@@ -49,14 +49,16 @@ namespace Ryujinx.Ava.Utilities.Configuration
configurationFileUpdated = true;
}
+
EnableDiscordIntegration.Value = LoadSetting ? cff.EnableDiscordIntegration : EnableDiscordIntegration.Value; // Get from global config only
CheckUpdatesOnStart.Value = LoadSetting ? cff.CheckUpdatesOnStart : CheckUpdatesOnStart.Value; // Get from global config only
+ UpdateCheckerType.Value = cff.UpdateCheckerType;
ShowConfirmExit.Value = LoadSetting ? cff.ShowConfirmExit : ShowConfirmExit.Value; // Get from global config only
RememberWindowState.Value = LoadSetting ? cff.RememberWindowState : RememberWindowState.Value; // Get from global config only
ShowTitleBar.Value = LoadSetting ? cff.ShowTitleBar : ShowTitleBar.Value; // Get from global config only
EnableHardwareAcceleration.Value = LoadSetting ? cff.EnableHardwareAcceleration : EnableHardwareAcceleration.Value; // Get from global config only
HideCursor.Value = LoadSetting ? cff.HideCursor : HideCursor.Value; // Get from global config only
-
+
Logger.EnableFileLog.Value = cff.EnableFileLog;
Logger.EnableDebug.Value = cff.LoggingEnableDebug;
Logger.EnableStub.Value = cff.LoggingEnableStub;
@@ -438,7 +440,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
}),
(62, static cff => cff.RainbowSpeed = 1f),
(63, static cff => cff.MatchSystemTime = false),
- (64, static cff => cff.LoggingEnableAvalonia = false)
+ (64, static cff => cff.LoggingEnableAvalonia = false),
+ (65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off)
);
}
}
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
index 8fbe20e05..b511b32dd 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
@@ -1,6 +1,7 @@
using ARMeilleure;
using Gommon;
using Ryujinx.Ava.Utilities.Configuration.System;
+using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
@@ -767,6 +768,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Checks for updates when Ryujinx starts when enabled
///
public ReactiveObject CheckUpdatesOnStart { get; private set; }
+
+ ///
+ /// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
+ ///
+ public ReactiveObject UpdateCheckerType { get; private set; }
///
/// Show "Confirm Exit" Dialog
@@ -804,6 +810,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
Hacks = new HacksSection();
EnableDiscordIntegration = new ReactiveObject();
CheckUpdatesOnStart = new ReactiveObject();
+ UpdateCheckerType = new ReactiveObject();
ShowConfirmExit = new ReactiveObject();
RememberWindowState = new ReactiveObject();
ShowTitleBar = new ReactiveObject();
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs
index f8fbc90d8..7e4b79445 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs
@@ -56,6 +56,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
DockedMode = System.EnableDockedMode,
EnableDiscordIntegration = EnableDiscordIntegration,
CheckUpdatesOnStart = CheckUpdatesOnStart,
+ UpdateCheckerType = UpdateCheckerType,
ShowConfirmExit = ShowConfirmExit,
RememberWindowState = RememberWindowState,
ShowTitleBar = ShowTitleBar,
@@ -175,7 +176,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
System.SystemTimeOffset.Value = 0;
System.EnableDockedMode.Value = true;
EnableDiscordIntegration.Value = true;
- CheckUpdatesOnStart.Value = true;
+ UpdateCheckerType.Value = UpdaterType.PromptAtStartup;
ShowConfirmExit.Value = true;
RememberWindowState.Value = true;
ShowTitleBar.Value = !OperatingSystem.IsWindows();
diff --git a/src/Ryujinx/Utilities/Configuration/UI/UpdaterType.cs b/src/Ryujinx/Utilities/Configuration/UI/UpdaterType.cs
new file mode 100644
index 000000000..2ab17a497
--- /dev/null
+++ b/src/Ryujinx/Utilities/Configuration/UI/UpdaterType.cs
@@ -0,0 +1,13 @@
+using Ryujinx.Common.Utilities;
+using System.Text.Json.Serialization;
+
+namespace Ryujinx.Ava.Utilities.Configuration.UI
+{
+ [JsonConverter(typeof(TypedStringEnumConverter))]
+ public enum UpdaterType
+ {
+ Off,
+ PromptAtStartup,
+ CheckInBackground
+ }
+}