Skip to content

Port Mod Manager to Avalonia with Linux and Steam Deck support - #1283

Open
Yokimitsuro wants to merge 51 commits into
OpenKH:masterfrom
Yokimitsuro:feature/cross-platform-mod-manager
Open

Port Mod Manager to Avalonia with Linux and Steam Deck support#1283
Yokimitsuro wants to merge 51 commits into
OpenKH:masterfrom
Yokimitsuro:feature/cross-platform-mod-manager

Conversation

@Yokimitsuro

@Yokimitsuro Yokimitsuro commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Note

AI-assisted development disclosure

AI-assisted tooling, specifically GPT-5.6 Sol, was used during the development of this PR. It contributed substantially to the Avalonia port, UI scaffolding, controller navigation, cross-platform packaging, tests, and repetitive refactoring.

I directed the intended behavior, reviewed the changes, tested builds on the supported platforms, reproduced reported issues, and decided how review feedback should be addressed. I take responsibility for the submitted code and am willing to explain or rework any section that raises technical or maintainability concerns.

Summary

This replaces the WPF Mod Manager with a cross-platform Avalonia implementation for Windows, Linux, and Steam Deck while preserving the established workflows and configuration format.

Highlights

  • Keep setup, game detection, data extraction, Panacea, Lua Backend, presets, creator tools, repository installation, mod building, and game launch workflows
  • Support Steam and Epic Games Store installations
  • Browse community mods with images, descriptions, repository details, installation progress, and responsive loading
  • Preserve mod selection and load order during refreshes
  • Show source code, bug report links, and modified file lists when provided by the mod metadata
  • Add directional controller navigation across the complete interface
  • Support controller reconnection, controller changes, right-stick scrolling, and the Steam Deck virtual keyboard
  • Add controller actions for moving mods, including moving the selected mod directly to highest priority
  • Keep moved mods selected and visible when their new position is outside the current viewport
  • Support repository shorthand for other Git hosts, including owner/repository@codeberg.org
  • Keep the generated mod cleanup action available with Panacea
  • Provide a distro-neutral Linux AppImage package
  • Keep repository installation responsive while catalog information continues loading

Configuration compatibility

Existing installations continue using the established mods-manager.yml property names:

  • extractedGameDataPath
  • installedModsPath
  • installedCollectionsPath
  • compiledModPath
  • yamlGenPrefs

Files written by earlier Avalonia previews are migrated automatically. Existing mods, extracted data, presets, enabled mod lists, load order files, collection settings, game paths, and creator preferences are preserved.

Advanced storage settings keep installed mods, installed collections, and built mods configurable independently. Custom folders retain the established direct game-folder layout, while matching install and build paths are separated into mods and mod subfolders to prevent overwrites.

The latest master behavior for package patching is also included. Patching tools stay hidden unless Enable package patching tools is selected in Settings, and the previous devView setting is migrated automatically.

Linux and Steam Deck

  • Native Linux x64 build
  • AppImage packaging with dependencies included
  • Writable application data stored under $XDG_DATA_HOME/OpenKH or $HOME/.local/share/OpenKH
  • Controller navigation designed for game mode and smaller displays
  • Virtual keyboard support for text fields
  • Steam and Epic Games Store launch handling

Validation

  • 51 Mod Manager Core tests passed
  • 14 Avalonia interface and controller navigation tests passed
  • 5 application navigation tests passed
  • Bdxio command, reusable Bdxio library, and Patcher Release builds completed successfully
  • Windows x64 Release publish completed successfully
  • Linux x64 Release publish completed successfully
  • Existing configuration migration and application layout cleanup covered by tests
  • Lua Backend formatting, repair, and multiline script configuration covered by tests
  • Repository shorthand, custom storage paths, offscreen mod movement, and archive traversal protection covered by tests

Screenshots

Mod library

mod-library

Browse mods

browse-mods

Setup

setup

…e/cross-platform-mod-manager

# Conflicts:
#	OpenKh.Tests.ModsManager/ModsServiceTest.cs
#	OpenKh.Tools.ModsManager/Services/ConfigurationService.cs
#	OpenKh.Tools.ModsManager/Services/ModsService.cs
#	OpenKh.Tools.ModsManager/Services/OperationDispatcher.cs
#	OpenKh.Tools.ModsManager/Services/RepositoryService.cs
#	OpenKh.Tools.ModsManager/ViewModels/MainViewModel.cs
#	OpenKh.Tools.ModsManager/ViewModels/SetupWizardViewModel.cs
Keep the established YAML property names, migrate preview configurations, repair Lua Backend section formatting, and remove obsolete application files without touching user data.
Package the Launcher and Mod Manager as a distro-neutral AppImage, keep mutable data outside the mounted image, hand updates back to the Launcher, and validate controller navigation in headless UI tests.
# Conflicts:
#	OpenKh.Tools.ModsManager/Services/ConfigurationService.cs
#	OpenKh.Tools.ModsManager/ViewModels/MainViewModel.cs
#	OpenKh.Tools.ModsManager/ViewModels/SetupWizardViewModel.cs
#	OpenKh.Tools.ModsManager/Views/MainWindow.xaml
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 59187835-9e19-4b08-a02e-3cfdaea5c8b5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread OpenKh.Tools.ModsManager.Core/LocalModInstaller.cs Fixed

@shananas shananas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial review did not cover all of the code just testing interacting with the UI.

In debug at least clicking Top to move a mod to the top while the top of the mod selector window is not in view gives this error.

Image

If I hit continue (in my debugger) it all continues as expected but it seems when you have scrolled down on selected mods (making the top of the list not on screen) and move a mod to Top you get this error.
Just did a quick test after posting this. This also happens if you move a mod up off the top of the screen. (does not happen when moving mods down off the bottom Only Up)

Very recently topaz added the ability to clone mods from other git sources using shorthand such as TopazTK/KH2-ArchipelagoEnablers@codeberg.org. This is a regression (tbf its only been a thing for a few days) that needs to be migrated to new MM.

You removed Fast Restore entirely when using panacea. Restore is for use with patching as it deletes any build mods in mod/Launch Game: and restores your patches pkgs from backups OKH made.
Fast Restore is for use with panacea as all it does is delete mod/"Launch Game." WHen i named this I did as such since it does half of what Restore does. This option should remain viewable with panacea but feel free to rename to something that anyone would understand without the knowledge of the backend code. No attachment to the name and Im bad at naming things.

While I and I dont think many others use it since you made a UI option for where mods are saved/built. I do think this option by default should be behind a dropdown. It can still be where it is and making it easier to edit for those who want/need to is nice. And if this will be in the GUI you should have both one for mod install location and mod build location. Also this is technically a regression of tryashtars PR making it so a mods folder is not created (which i followed with a PR to ensure mod and mods were not the same to prevent them overwriting each other). I didnt really care and I doubt many users use the ability to change the mods folder at all but since they made that PR (and i added the code to prevent the clash in the even mod and mods are the same) I imagine they would want it to match the update they did in their PR.

Then also the bdxio build error to test i just removed the name change that added .library so i could build it, I imagine something wasnt renamed along with adding .library?

A little more nitpicky personally i dont like really like the rename of run to play idk just looks weird to me but maybe everyone else likes this more. Even so if we keep it saying play I think Play without rebuilding should just be something like Start Game or similar. or maybe i just like Build and Run and Run only too much.
Taking a quick look at r2modman and lumafly maybe it could be closer to them. 2 buttons Start/Launch Modded/Vanilla. Definitely want to still keep build only even if we did this. and move Fast Restore back in case someone want to "Build" with no mods. Ofc feel free to rename it since again I suck at naming.

last even more nitpick i like new windows sometimes over changing the entire window. such as installing a new mod but tbf unless many other people (at least 10) agree keep it this way

Ill do a more thorough code review later after more changes.

@paulblessing

Copy link
Copy Markdown
Contributor

Was shown a screenshot of this, don't have dotnet set up at the moment, but have some initial quick feedback.

  • Setup and Settings - These feel like two sides of the same coin. Would suggest either consolidating or making it clearer why each stands on their own.
  • Not all the buttons deserve equal prominence. Creator and Info in particular feel like things that could be less prominent / moved elsewhere.
  • Along the same lines for prominence, Open mod folder is the most eye-popping thing on the screenshot I was shown, but it's not something that (at least in my years of using Mods Manager) is used all that often. The things I (and I'll make a slight assumption and say most everyone else) do the most are (1) manipulate which mods are installed/active, and (2) build and/or run once done with (1). If we're rethinking the UI (which I'm glad is happening), I think a definite goal should be to surface the common actions and reduce the prominence of uncommon actions.

@Yokimitsuro

Yokimitsuro commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Avalonia supports pop-up windows, but they cause issues on Steam Deck, which is why I removed all the extra windows.

I pushed the following changes:

  • Fixed the Browse buttons for Installed Collections Folder and Built Mods Folder.
  • Build and Launch, Build Mods, Launch Without Rebuilding, and Clear Built Mods now remain available when no mods are enabled.
  • Split repository and local file installation into two clearly separated sections.
  • Selecting a local file now starts the installation immediately.
  • Replacing an installed mod now uses a proper confirmation dialog instead of a checkbox or status bar message.
  • Fixed the status bar layout so long messages no longer overlap the installation path.
  • Controller status now uses a neutral color, while successful operations and build locations use green.
  • Controller input is ignored when the Mod Manager is not the active application, so it should no longer affect the UI while playing.
  • Updated button and section labels for consistent capitalization.
  • Updated extraction warnings so only the warning label is highlighted.
  • I also replaced the external virtual keyboard flow with an in-app controller keyboard. Controller confirmation now enters characters, Backspace works, and Done or B closes the keyboard and returns focus to the original text field without closing the current screen.
  • Added integration coverage for typing, erasing, closing, focus restoration, and connected controller navigation at both desktop and compact window sizes.

I kept Game Setup and App Settings in the main menu for now since that was presented as a suggestion rather than a required change, but I can revisit it later if needed.
I also expanded the controller navigation tests to cover every Mod Manager window at both 1500x1000 and 960x640. All 16 UI tests and 52 core tests pass

Please let me know if you find anything else during practical testing.

@shananas shananas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new in UI keyboard is nice I wasn't able to actually type using the windows on-screen keyboard as it wasnt in focus (then again i wont be using this with controller just testing).
Commonly on screen keyboards like this have a couple extra shortcuts such as (for PS) Square being backspace triangle shift/caps lock or space. Itd be nice to support those. Pretty sure consistently middle left button is backspace others could be preference.

Image

if (Directory.Exists(destinationDirectory))
{
if (!overwrite)
throw new ModAlreadyInstalledException(packageName);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why this behaves differently. When installing over specifically a zip or PCPatch I get an error in my IDE from here. This behaves differently than overwriting a Repo or Lua script which does not throw and IDE error. I still see the replace screen after hitting continue (in my IDE). Not sure if this will be a problem on the release version but ideally needing to overwrite a zip or PCPatch mod doesn't interrupt debugging and just cleanly proceeds to the next screen of confirming if you want to overwrite the mod just like how overwriting a Lua Script or Repo install works.

<TextBlock Grid.Row="4" Text="Branch (Optional)" FontWeight="SemiBold" />
<TextBox x:Name="BranchTextBox" Grid.Row="6" PlaceholderText="main" />
<TextBlock Grid.Row="8"
Text="GitHub repositories, custom Git hosts, ZIP links, OpenKH patch archives, and Lua files are supported."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PCPatches were not developed for OpenKH. They were made for AntonioDePau/KHPCPatchManager. We just support using them in Mods Manager. Suggest changing the name though this but if you have a more preferred choice go ahead with that. Just there is no such thing as an OpenKH Patch Archive.

Suggested change
Text="GitHub repositories, custom Git hosts, ZIP links, OpenKH patch archives, and Lua files are supported."
Text="GitHub repositories, custom Git hosts, ZIP links, PC Patch archives, and Lua files are supported."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied

@shananas

Copy link
Copy Markdown
Collaborator

The last installed mod hovered over when navigating with a controller can be moved up/down with the triggers even if on the side buttons or search bar up top. Not sure if you want to keep that or require the controller to actually be over the mod to prevent accidentally changing mod order while navigating with the controller.

@shananas

Copy link
Copy Markdown
Collaborator

Two more comments while testing a bit further.

  • When deleting a mod the screen resets to the top mods if they're not visible. Ideally this wouldnt change the view much and just shift the mods up/down to fill in the removed mods area. In the case of deleting multiple mods can be a bit annoying to scroll down every time. I have a lot of mods installed and sometimes i delete mods not at the top so I could definitely hit this in the future.
  • When doing an ISO extraction I get the warning for PC Extractions. This screen should just be skipped entirely for emulator since non of it is relevant here. Or maybe just mention existing extractions may be overwritten and hide the PC specific text.
image

One more small question/suggestion could it be possible to let the user paste in a repo link then just hit enter and not need to click install from repository. Not a big deal and iirc you cant currently do that but it'd be nice to have. No big deal if you disagree just an idea I don't care either way about.

I believe I've properly tested everything so after changes I'd like to make a test build to give to a few devs and get their thought too since its a large overhaul. And I feel like there should be more input than just mine,

Allow controller focus to enter expanded setup fields and keep nested menu commands separate from their parent expanders.

Restore virtual keyboard shortcuts, repository submission with Enter, focused-row actions, and platform-specific extraction guidance.
Inspect local packages and repositories before installation so existing mods receive a clear replacement prompt.

Reuse package inspection for local archives and preserve the current list position after removing a mod.
Identify new and existing PC Patch imports, keep them below OpenKH mods, and preserve their relative order.

Prevent manual reordering across the format boundary while retaining full installation support.
@Yokimitsuro

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed feedback. I pushed another set of fixes:

  • Advanced Storage Locations can now be opened and fully navigated with a controller.
  • Creator Tools and About OpenKH now open correctly from the More section instead of toggling the section.
  • The controller keyboard now supports X/Square for backspace and Y/Triangle for shift, and restores focus when closed.
  • Pressing Enter in either repository field now starts the installation.
  • Existing local and repository mods are detected before installation and use a proper replacement confirmation.
  • Removing a mod keeps the list at the same position instead of jumping.
  • The PCSX2 extraction confirmation now describes ISO extraction without PC or remastered file wording.
  • PC Patch support is retained. PC Patch imports are detected, kept below OpenKH mods, and preserve their relative order. Reordering cannot move them above OpenKH mods.

@shananas

shananas commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

With the recent batch of updates you can only move mod priority with controller one time with the trigger buttons before needing to go off and on the mod to move priority again. Probably to do with preventing moving the mods while not focused on them.

Restore focus to the moved mod row after each priority change so trigger-based reordering can continue without leaving and reselecting the item.
Publish and validate a tar.gz archive with executable permissions while retaining the ZIP asset used by existing Linux update installations.
Remove the unmerged Linux ZIP asset, publish only the portable tar.gz package, and teach the Launcher updater to extract it directly.
Promote new local and repository installations to the top of their allowed format group while preserving the existing order when replacing a mod.
@zaktherobot

Copy link
Copy Markdown

Hi, thanks for going through the effort to make things better. The work is appreciated.

These are nitpicks coming from my future expectation for people having problems using this version of Mod Manager compared to the WPF version. I'm basing this on a build Shan sent me, and none of these are things that need to be fixed, just observations.

  1. (I see you already addressed this, this issue was the biggest one and the one that would cause the most actual user problems I think, so it's good it's already addressed). New mods should be highest priority by default, and they are lowest on this build.

  2. Installing and removing mods used to have buttons right next to each other, now they are on entirely different sides of the UI.

  3. PC Keyboard shortcuts seem to no longer exist, and I know this is minor, but I personally used them extensively.

  4. If the github username and repo name combo is gonna be displayed (i.e. username/repo_name) It should be selectable to copy for sharing with others. Otherwise, it adds little value to the display when the mod source can be determined from the mod source button.

None of these are that big a deal, and functionally, it appears to have feature parity. I just wanted to note the initial expectations I had when using it for the first time.

@tommadness

Copy link
Copy Markdown
Contributor

This is fantastic, thank you for this!

Ran the beginning of a standalone rando seed as a test, and only have a couple of observations. I'm running on Nobara, a Fedora-based distro.

  • Steam direct launch does not appear to work on .appimage OpenKH and Linux Native Steam. Launching the game through OpenKH mods manager runs the KH1.5+2.5 Launcher
  • copy mod method won't copy resources (such as music rando files) from external paths on .appimage OpenKH. I've attached a randoseed that demonstrates the behavior (though the paths are hardcoded for my machine's extracted_data location, of course)

randoseed.zip

image

@KHOmega

KHOmega commented Aug 23, 2026

Copy link
Copy Markdown

It's looking great so far, and I'm glad there is an AI use disclosure above.

Here are somethings I have found in my testing:

  • Extracted data/mods are saved in ~/.local/share/OpenKH by default, great to know.
  • Search function within the mod menu is super helpful
  • PC Patches with the Unknown tag can't be placed above other mods
    • I see this is intentional but wondering why so?

When building KH-Refined/KH2-MAIN@codeberg.org, certain assets fail to load and lock the game up in the loading screen.

It looks like these assets are custom ones provided by Re:Fined, such as Pirate Sora and Org. XIII Moogle costumes. The issue is that some items fail to build into the finished collection of mods, while others do and still soft lock.

Below is an example screenshot image showing the same mod (KH-ReFined/KH2-MAIN@codeberg.org) being built on build 1680, and on the right being the PR:

image

As you can see, the one on the right has two less files, N_EX640_XIII_MOOGLE_RTN.mdlx, and N_EX640_XIII_SHOP_RTN.mdlx.

This results in the game giving an infinite loading screen because those assets could not be found.

Although one could just simply get those files and drop it in, other custom assets, such as Pirate Sora, are built into the game's mod folder, but also refuse to load.

When building with build 1680, I was able to drag it's mod folder into the PR one, and the game loaded with zero issues. I do believe that the PR mod manager is failing to correctly build mods with custom assets and this needs to be looked into urgently.

Unlike tommadness's issue with Steam Direct Launch, it works perfectly on my end, and I also use Nobara with Native Steam Linux. I'm not sure what the issue is there, but I will also be testing this on my Steam Deck once the other issues are addressed.

Otherwise, this is fantastic work and I can't wait for more improvements to come.

@TopazTK

TopazTK commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

As I have said in previous PRs that had AI involvement, I cannot support any PR that is inherently based on artificially generated code.

No offense to anyone involved, thanks for your transparency. We need more of this in our projects.

@ETMann

ETMann commented Aug 23, 2026

Copy link
Copy Markdown

I cannot in good conscious continue to use this mod loader anymore now that you've decided to give up and slopcode it. You should feel ashamed of yourself for betraying the community's trust. Generative AI is looked down upon in every field for a reason, and anything defending it at all is just excusing theft.

@SophieBaybey

Copy link
Copy Markdown

I have to agree with Topaz. As much as the modloader needs a rework, I think basing the foundation for a new era of the modloader entirely on AI-generated code is short-sighted. I worry about the technical debt being incurred by such a massive change being essentially fully generated. I can't imagine the potential for bugs is anything short of impossible to test with without pushing this PR live, and at that point it risks the functionality and reputation of OpenKH for its users. I have to ask, is the code in this PR understood deeply enough to maintain it? When bugs arise, will they be able to be properly addressed? Is that code going to be maintained by individuals, or fed back to the AI to fix it? With the rising costs of code generation, are those credits going to be burned through in an effort just to maintain this refactoring? I'm sure many OpenKH users have their own ethical and moral misgivings around AI, but at the end of the day, I am worried by the amount of work being put in the hands of a language model, and how much extra work that could simply create in the event it's a step back instead of a step forward.

I can tell by the initial PR that much of this has been considered, and I'm glad for that. I can see this isn't just blindly being pushed without thought, but I still believe the concerns outweigh the potential value.

@tommadness

Copy link
Copy Markdown
Contributor

With the light of the AI practices used, I retract my support.

@toonjoey

Copy link
Copy Markdown

I have no dog in this fight, but even as someone who isn't as harsh about the use of AI (insert the nuance hat image here) I am entirely against it's use in here and refuse to support or utilize this loader anymore if this does end up being merged. To be a little frank I'm disappointed that it's even up for consideration.

I appreciate the transparency with it's use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.