Skip to content

(feat) Games backend support for arcade cores, ROM matching, and server-side artwork handling - #222

Draft
WizardOfYendor1 wants to merge 6 commits into
Moonfin-Client:masterfrom
WizardOfYendor1:feature/arcade-emulator-prototype
Draft

(feat) Games backend support for arcade cores, ROM matching, and server-side artwork handling#222
WizardOfYendor1 wants to merge 6 commits into
Moonfin-Client:masterfrom
WizardOfYendor1:feature/arcade-emulator-prototype

Conversation

@WizardOfYendor1

Copy link
Copy Markdown

Pull Request

Summary

Sorry I can't be brief (REALLY tried :-)).
This adds new functionality supporting retro games, including arcade core support (FBNeo) and a complete redesign of artwork handling. This is the "sister" PR to the retro game client (Moonbase) PR... and again sorry for the "mega PR". I couldn't think of a good way to split all this up except with commits.

Just like client-core changes, I've redesigned and refactored this quite a bit over several other approaches. i.e. many ideas failed or just wasn't good. Of course, this may not be good either... but maybe it's a starting point.

Additions/Changes:

There are 4 files that alter existing behavior, one notable one is a refactor of the emulator player.html. I pulled the javascript into moonfin-bridge.js. So sorta of optional.
Outside the games library, this touches a few spots that are not game related. A dispatchKeyEvent gains a check, the existing startup/resume image-cache sweep gains a game-artwork pass, notifyAppResumed fires on resume, and the Watch Next background worker now stands down while the app is foregrounded (probably the "biggest" one).

Media image caching behavior is unchanged — the sweep was generalised to take a cache key so game artwork can reuse it, and media still sweeps the same directory with the same throttle. No media playback, library, or scanning code is touched. The game artwork gets it own cache - in it's own isolated domain. i.e. keep a wall between the media functionality.

Basic run down of new features:

Arcade

  • Identifies arcade ROMs by hashing the zip against MAME/FBNeo DAT indexes, so core recommendation isn't a filename guess
  • Resolves which native core can actually run a game, and hides the ones that can't
  • Per-user core and backend overrides, persisted server-side
  • Serves the EmulatorJS player and bridge for anything the native path refuses

Artwork

  • Fetches box art, snaps and titles from libretro and catalogs them per system
  • Generates derived thumbnails server-side so clients never pull full-size art
  • Reconciles the catalog at startup and again after each library scan
  • Per-user delivery limiting and bounded concurrency so art can't swamp the server

ROM identification

  • Indexes libretro-database RDB files with bounded reads, so a malformed or hostile RDB can't exhaust memory
  • Matches ROMs to database entries, driving both core recommendation and artwork lookup

Games API

  • Endpoints for libraries, systems, games, ROM/BIOS streaming, saves and artwork manifests
  • Resolves and validates ROM paths, rejecting traversal attempts
  • Caps extraction size on zip and 7z, so a decompression bomb can't take the server down
  • Legacy endpoints preserved

And a litany of new tests covering all of that.

LLM disclosure: as with client core. Most of my early iterations were all me and LLM was research on approaches. I mostly used it for test generation from use cases I had written. That then provided a a path to code to make it work as designed. Also in late states used for research/refactoring/cleanup/chores (git operations etc) but in general I used AI a lot less on this side of things. I wanted to be extra careful here.

Type of Change

  • [X ] Bug fix
  • [ X] New feature
  • [ X] Refactor
  • [ X] Performance improvement
  • [ X] API / endpoint change
  • Settings schema change
  • Documentation update
  • Build/CI change
  • Other (describe):

Area

  • Settings sync / profiles
  • Admin defaults / config page
  • Ratings (MDBList / TMDB)
  • Notifications / Push (FCM / relay)
  • Seerr integration
  • [ X] Games / Emulators
  • Custom home rows
  • Web Client (Go to Moonfin-Core repo)
  • Other / shared

Changes Made

Client Impact

Does this need matching changes in a client repo (Core, Smart-TV, Roku)?

  • No client changes needed
  • Companion client PR(s) required for full use bit not dependant, linked here:
  • New setting keys added. List each key and confirm it matches the client key exactly, including casing:

Compatibility

  • Change to the settings profile is additive only, no renamed or removed properties
  • New properties use the same type the client sends (a client bool maps to bool?, an int to int?)
  • Migration added for any renamed or removed settings
  • [X ] Older clients still work, unknown fields are ignored and no keys were removed

Testing

Describe how this change was tested.

  • [ X] Built the plugin and deployed to a Jellyfin server
  • [X ] Verified against a live client (which one: Windows/Android/AndroidTV both real/live and emulated)
  • Manual testing completed (more time spent here than coding :-) )
  • Not tested (explain why):

Test Steps

Screenshots (if applicable)

Include config page screenshots or request/response samples where relevant.

Checklist

  • Code builds successfully
  • Code follows project style and conventions
  • [X No unnecessary commented-out code
  • No new warnings introduced
  • Any new setting keys match the client-side keys exactly

@RadicalMuffinMan

Copy link
Copy Markdown
Contributor

Take a look at how it will affect Smart-TV repo as well since they use the emulator js too.

@WizardOfYendor1

Copy link
Copy Markdown
Author

Take a look at how it will affect Smart-TV repo as well since they use the emulator js too.

Will do. I'll take a look later tonight. I wouldn't expect it to have any effect (if I had a nickle for everytime I've said that). I went out of my way to preserve the "legacy" approach/endpoints (primarily to no break people who had newer plugin version than the android client and vice-versa)....and any new fields in the payload additive.
The only potential area is I can return a 50X status instead of a 404 for not found thumbnail artwork. That could possibly create problems. For sure, the smart tv client would need changes to take advantage of this.

@WizardOfYendor1

Copy link
Copy Markdown
Author

Take a look at how it will affect Smart-TV repo as well since they use the emulator js too.

Will do. I'll take a look later tonight. I wouldn't expect it to have any effect (if I had a nickle for everytime I've said that). I went out of my way to preserve the "legacy" approach/endpoints (primarily to no break people who had newer plugin version than the android client and vice-versa)....and any new fields in the payload additive. The only potential area is I can return a 50X status instead of a 404 for not found thumbnail artwork. That could possibly create problems. For sure, the smart tv client would need changes to take advantage of this.

So update. I pulled the SmartTV repo, built it and side loaded it into an actual Samsung device - which is an absurdly under powered device - my Odyssey 49" "monitor" (only cursed Samsung display I have).

I pointed it to my test server that's running this new plug in code and it loaded images "fine". The scare quotes mean - it loaded, but BOY it was slow and crashed once. This would be using the "legacy" endpoint but it does gets the newer, smaller artwork JPGs - if they are available. It's a net win for the device's disk storage but not as much for memory. I don't know how caching/eviction etc works in that code. I would guess the smart tv client loads up all the images at once eagerly. All clients probably should be aware of the memory constraints they are have and manage cache accordingly (if even feasible).

Also, I made changes in the moonfin client code (the other mega PR :-) ) to decode the thumbnails to match the computed card size ... thus shrunk memory usage. Additionally there's logic there to clear out memory when launching games. So all those ideas, etc, would need to be implemented in the smart tv client(s) for max performance.

My test was pretty extreme, 5000+ artwork images on a samsung monitor. But artwork did load, and I don't see how changes here would make that any worse. I was able to even launch a game.

image image

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.

2 participants