Launcher ViewModels
The launcher's MVVM layer lives under sources/launcher/Stride.Launcher/ViewModels/. Every view model derives from DispatcherViewModel from Stride.Core.Presentation, so property change notifications marshal back to the UI thread automatically.
Hierarchy
flowchart TD
MVVM["MainViewModel<br/>(root)"]
SVM["StrideVersionViewModel (abstract)"]
SSV["StrideStoreVersionViewModel"]
SDV["StrideDevVersionViewModel"]
SSA["StrideStoreAlternateVersionViewModel"]
PVM["PackageVersionViewModel (abstract)"]
VVM["VsixVersionViewModel"]
RPV["RecentProjectViewModel"]
NPV["NewsPageViewModel"]
DPV["DocumentationPageViewModel"]
RNV["ReleaseNotesViewModel"]
AVM["AnnouncementViewModel"]
PVM --> SVM
PVM --> VVM
SVM --> SSV
SVM --> SDV
SSV --> SSA
MVVM -- owns --> SVM
MVVM -- owns --> VVM
MVVM -- owns --> RPV
MVVM -- owns --> NPV
MVVM -- owns --> DPV
MVVM -- owns --> RNV
MVVM -- owns --> AVM
MainViewModel
MainViewModel.cs is the root. It is created once in App.OnFrameworkInitializationCompleted and owns everything else.
Key responsibilities:
- Initialize the NuGet store.
Launcher.InitializeNugetStore()constructs aNugetStorerooted at the launcher's directory.MainViewModelregisters itself asstore.LoggerviaIPackagesLoggerso every NuGet operation is captured in theLogMessagesbuffer. - Populate
StrideVersions. ASortedObservableCollection<StrideVersionViewModel>(newest first) combining:- Dev versions from
LauncherSettings.DeveloperVersions. - Locally installed packages (
RetrieveLocalStrideVersions). - Packages returned by the NuGet feed (
RetrieveServerStrideVersions).
- Dev versions from
- Track the active version.
ActiveVersionpersists toLauncherSettings.ActiveVersion. When it changes,StartStudioCommand.IsEnabledis recomputed fromActiveVersion.CanStart. - Fetch online content.
FetchOnlineDataruns the self-updater, then in parallel fetches news pages, release notes, and documentation TOC. - First-install experience.
CheckForFirstInstallruns the prerequisites installer for already-installed versions, then — on a truly first install — asks the user to install the latest Stride and the appropriate VSIX for their installed Visual Studio. - Recent projects. Subscribes to
GameStudioSettings.RecentProjectsUpdatedand rebuildsRecentProjectson the dispatcher.
Commands exposed to the UI:
| Command | Action |
|---|---|
InstallLatestVersionCommand |
Download the newest StrideVersionViewModel via its own DownloadCommand |
StartStudioCommand |
Launch Game Studio for ActiveVersion (see lifecycle.md) |
OpenUrlCommand |
ShellExecute a URL (used for social links, docs, news) |
ReconnectCommand |
Clear IsOffline and re-run FetchOnlineData |
CheckDeprecatedSourcesCommand |
Add the legacy packages.stride3d.net feed to NuGet.config if missing, then restart |
RunLockTask serializes every NuGet operation under objectLock so two async tasks never hit NugetStore concurrently.
PackageVersionViewModel
PackageVersionViewModel.cs is the abstract base for anything the launcher downloads from NuGet.
It holds:
LocalPackage/ServerPackage—NugetLocalPackage/NugetServerPackagefromStride.Core.Packages.CanBeDownloaded,CanDelete,IsProcessing,CurrentProgress,CurrentProgressAction,CurrentProcessStatus— UI-facing flags.DownloadCommandandDeleteCommand— the primary user actions.
Subclasses must implement Name and FullName, and override UpdateStatus to set CanBeDownloaded / CanDelete based on the local/server pair. The download/delete logic is already in the base class.
Version view models
- StrideVersionViewModel — abstract base. Adds
Major/Minor,AvailableEditors(discovered by scanningtools//lib/),SelectedEditor, andLocateMainExecutable(). - StrideStoreVersionViewModel — an official release. Holds
ReleaseNotesandDocumentationPages, manages the prerequisites installer (Bin\Prerequisites\install-prerequisites.exe), and exposes the VSIX packages. - StrideStoreAlternateVersionViewModel — a sibling patch variant that resolves under the same
StrideStoreVersionViewModel. - StrideDevVersionViewModel — a local build registered via
LauncherSettings.DeveloperVersionsor aDevRedirectpackage. Never downloadable. Marked as "compatible with every project" in the recent projects list. - VsixVersionViewModel — installs/uninstalls the Stride Visual Studio extension in the detected VS instances via
Stride.Core.CodeEditorSupport.VisualStudio.VisualStudioVersions.
See versions.md for the full install/uninstall flow.
Recent projects
RecentProjectViewModel.cs wraps a single MRU entry:
DiscoverStrideVersion()runs async on a background thread and parses the.slnfile throughPackageSessionHelperto detect which Stride version the project targets.CompatibleVersionslists the locally-installed versions that can open the project (dev versions are always considered compatible; store versions must be ≥ the project's declared version).- Commands:
OpenCommand(open with active version),OpenWithCommand(open with a chosen version),ExploreCommand(show in file explorer),RemoveCommand(remove from MRU viaGameStudioSettings.RemoveMostRecentlyUsed).
Content view models
- NewsPageViewModel — fetches the RSS feed at
Urls.RssFeed, parses<title>,<description>,<pubDate>,<link>.FetchNewsPages(IViewModelServiceProvider, int)returns up to n entries. - DocumentationPageViewModel — fetches the "Getting Started" HTML index and extracts its links. Tied to a specific Stride version so the right doc branch is shown.
- ReleaseNotesViewModel — lazy-loads markdown release notes; has
IsLoading/IsLoaded/IsUnavailableflags and aToggleCommandto expand/collapse. - AnnouncementViewModel — loads a markdown announcement from an embedded resource. Uses
MainViewModel.HasDoneTask/SaveTaskAsDoneso "don't show again" is persisted per announcement. CurrentlyMainViewModel.DisplayReleaseAnnouncementis an empty placeholder — wire announcements here.
Converter
EditorNameConverter.cs is a one-way value converter that renders an editor package name (Stride.GameStudio.Avalonia.Desktop) as a human-readable label. It lives in the ViewModels folder rather than Views because it is consumed by bindings alongside SelectedEditor.
Threading notes
- Mutations that touch
strideVersionsgo throughDispatcher.Invoke/Dispatcher.InvokeAsyncbecause the UI observes the collection. - All NuGet calls go through
MainViewModel.RunLockTaskto serialize access. strideVersionsis aSortedObservableCollection; neverAddinto an index — it sorts itself.