Skip to content

Add Mosaic Mod Manager - #3868

Closed
TheMrGeeBee wants to merge 1 commit into
AppImage:masterfrom
TheMrGeeBee:add-mosaic-mod-manager
Closed

TheMrGeeBee wants to merge 1 commit into
AppImage:masterfrom
TheMrGeeBee:add-mosaic-mod-manager

Conversation

@TheMrGeeBee

Copy link
Copy Markdown

Mosaic Mod Manager — a mod manager for Linux (Baldur's Gate 3, Bethesda titles, RE Engine games, and many more), with Nexus Mods integration, Collections support, FOMOD/BAIN installers, and LOOT sorting.

Repo: https://github.com/TheMrGeeBee/Mosaic-Mod-Manager
Releases (AppImage, GPG-signed, .zsync delta updates): https://github.com/TheMrGeeBee/Mosaic-Mod-Manager/releases

@TheMrGeeBee

Copy link
Copy Markdown
Author

Thanks for the automated review — wanted to leave context on why it failed, in case a maintainer looks at this.

This AppImage is built with quick-sharun / pkgforge-dev/appimagetool, which uses DwarFS (not squashfs) as the embedded filesystem, embedding the uruntime AppImage runtime. That's a deliberate choice for this build — DwarFS's block-level deduplication compresses the many similar .so files an AppImage like this bundles noticeably better than squashfs does.

The AppImage's own bundled runtime handles DwarFS natively and works correctly for end users (confirmed working directly and via Gear Lever and topgrade), but this repo's test harness deliberately mounts submissions with the classic reference runtime-fuse2-x86_64 runtime rather than the AppImage's own bundled one, and that runtime only understands squashfs — hence This doesn't look like a squashfs image. It's a real format difference, not a broken build.

Happy to answer any questions. Leaving this PR open in case a squashfs-based build is a hard requirement for listing, or in case DwarFS-based AppImages are already handled some other way here — no action needed on my end otherwise.

@probonopd probonopd closed this Sep 26, 2026
@probonopd probonopd reopened this Sep 26, 2026
@github-actions github-actions Bot added error-missing-file Test failed: the AppImage lacks a required file error-not-an-appimage Test failed: the downloaded file is not a valid AppImage labels Sep 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

❌ Test failure

First error in the log:

FATAL: AppRun is missing in /run/snapd/ns

Commit 60858de. Full log

@TheMrGeeBee
TheMrGeeBee deleted the add-mosaic-mod-manager branch September 26, 2026 22:31
@probonopd

probonopd commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Thanks @TheMrGeeBee. Indeed we can only test squashfs based AppImages at this time and I am not convinced yet that DwarFS really delilvers the magical improvements it promises. Did you compare your app with DwarFS vs. squashfs?

I have updated the README to make the restriction explicit. Thanks for bringing this up.

probonopd added a commit that referenced this pull request Sep 27, 2026
…ror-filename) (#3929)

* Test: say clearly when an AppImage cannot be mounted (only SquashFS is supported)

The test took the last mount with "tmp" in it as the AppImage's contents.
When the mount failed, e.g. for a DwarFS AppImage (#3868), that was an
unrelated mount such as /run/snapd/ns, and the test reported "AppRun is
missing" there. Now it waits for the mount of this AppImage, and if none
appears it prints the runtime's message and "ERROR: Could not mount the
AppImage..."; new label error-not-squashfs with a hint. The runtime's
output goes to a file (it must not hold on to stdout) instead of
/dev/null, so its message is no longer lost.

README: an AppImage must use SquashFS; DwarFS etc. are not supported yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DZvaN9tm5taf5avUvVtmyq

* worker.sh: do not abort while waiting for the mount (set -e, pipefail)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DZvaN9tm5taf5avUvVtmyq

* Test: check the name of the file in data/ (error-filename)

code/check-name.sh, with rules derived from the ~1700 existing names:
- errors for files a PR adds (warnings for existing entries, which may have
  older names): blanks; the name of an AppImage file (.AppImage,
  architecture); "AppImage" or "Linux" unless part of the application's
  name in its desktop file; file extensions (.md, .txt, ...); an existing
  entry with the same name in different capitalization
- warnings: version numbers (numbers can be part of names, e.g. Play_2048),
  unusual characters (EiskaltDC++, fre:ac), a name that does not match the
  application's name, "Linux" in the AppImage's file name
Of the existing names, 22 would fail (all genuine: 7 case duplicates, 5
file extensions, AppImage file names) and 13 get warnings.

The remarks are shown in the PR comment (only lines of the known form);
new label error-filename; README lists the rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DZvaN9tm5taf5avUvVtmyq

* check-name.sh: do not report an architecture (x86_64) as a version number

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DZvaN9tm5taf5avUvVtmyq

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@TheMrGeeBee

Copy link
Copy Markdown
Author

Thank you @probonopd for you reply.

The huge win for me is the file size. Main benefits are content-defined chunking + cross-file deduplication For Mosaic that is a self-contained app, where most of the bulk is from my own python files, Qt libs and other unique assets that gain can be substantial. Think: many versions of Perl/Python packages, or Docker image layers with overlapping files.

But your skepticism on the DwarFS has substance, I agree on that. DwarFS is using FUSE instead of the Kernel level squashfs. But on the other hand where loop-mount isn't available, for instance in a container environment or where other restricted permissions apply, squashfs would also fall back on FUSE mount.

DwarFS will be more CPU-expensive at the first run due to it's harder LZMA dictonary, but for this kind of app, that is launched occasionally rather than read like a giant static corpus repeatedly, this rarely matters in practice.

Why is the size important for me? I'm uploading each release to Nexus Mods, and a new user would have to download a much larger file. Once downloaded it auto update it self on newer releases, but it's also a matter of uploading it to Nexus Mods, and their antivirus scan would be much longer.

The only solution for me would be to build two versions of the AppImage, but in that case I would have to force a naming schema, since it will fetch the first available AppImage by name.

But I respect your decisions, and it is still available once downloaded without it being on the AppImage repo.

@probonopd

Copy link
Copy Markdown
Member

Thanks for your detailed response. I am still pondering whether we should accept DwarFS based AppImages; in fact I have a PR ready that would allow it. But it adds complexity, especially to all the various desktop environments that integrate AppImages properly.

So your input is valuable:
How many MB do you save by using DwarFS over squashfs, do you know?

@TheMrGeeBee

TheMrGeeBee commented Sep 27, 2026 •

Copy link
Copy Markdown
Author

Thank you @probonopd for your response.

Good question, so I actually went and checked instead of guessing. Took my latest release (v1.5.1), pulled the files out of the DwarFS image, then repacked the exact same files into squashfs using the same mksquashfs settings appimagetool itself uses by default (zstd, no extra compression level, straight from your source so it's a fair comparison).

DwarFS comes out at 80.7 MB, squashfs at 96.3 MB. So about 15.6 MB more, roughly 19% bigger.

Honestly not a huge difference for my app - it's mostly just Python + Qt + site-packages, not the kind of repetitive stuff where DwarFS really shines. So I get why you're not convinced it's worth the extra complexity on your end, makes sense to me.

Reagrds,
Gordon

@probonopd

probonopd commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

+20% is not nothing, but maybe we could optimize the squashfs+zstd settings to get closer to that. I never had the time to test this systematically so far.

@TheMrGeeBee

Copy link
Copy Markdown
Author

+20% is not nothing, but maybe we could optimize the squashfs+zstd settings to get closer to that. I never had the time to test this systematically so far.

Yes, I'm open for suggestions. My goal is to make gaming, and especially modding gtames on Linux more convenient and available. I'm not locked into DwarFS, so if you could improve the squashfs+zstd I would consider switching. It would benefit the whole Linux eco system.

Regards,
Gordon

@TheMrGeeBee

Copy link
Copy Markdown
Author

Hello again @probonopd

Dug into this a bit more actually. The DwarFS side isn't running some default I could just tune - your build calls out to a separate tool (pkgforge-dev's Rust appimagetool) that already hardcodes zstd:level=22 -S26 -B6, so it's already at max compression level, 64 MiB blocks, and scanning back through 6 blocks (~384 MB) for duplicate content.

So the real gap isn't a missed setting on my end, it's structural: mksquashfs hard-caps block size at 1 MiB (tried passing 2M just to check, it just refuses), so it's working with a 64x smaller compression window than DwarFS, with no equivalent of that cross-block lookback at all. That's kind of the whole point of DwarFS's design, so squashfs can't really close that particular gap no matter how the flags are set.

Best I could get out of squashfs: bumping to -Xcompression-level 19 gets it from 96.3 MB to 89.1 MB, and switching the compressor to xz (still built into squashfs-tools) gets it down to 84.0 MB, only 3.2 MB off DwarFS's 80.7 MB - though xz decompresses slower, which matters since an AppImage gets read from repeatedly at runtime, not just downloaded once.

Regards,
Gordon

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

Labels

error-missing-file Test failed: the AppImage lacks a required file error-not-an-appimage Test failed: the downloaded file is not a valid AppImage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants