Ryujinx wrapped up Q1 and put a snazzy bowtie on it with an absolute avalanche of graphical bug fixes for some of your favorite games, and a significant increase in compatibility & stability in games utilizing Unreal Engine 4, thanks to the introduction of Texture Groups/Texture Dependencies and a handful of other related improvements.

The new Switch-exclusive game Bravely Default II was released at the end of February, and in March its status in Ryujinx progressed from “almost completely broken” to “almost perfect” in just a few weeks’ time. Monster Hunter Rise, released on March 26th, was playable for many on day one (don't worry, we are hard at work to help Windows users with AMD GPUs)!

Amiibo emulation (our first Patreon goal) was also merged into the main build this month! Thank you to all who helped during the Amiibo feature’s public testing phase; many bugs were identified & fixed, and game compatibility with the feature improved greatly as a result.

We're also happy to announce that Ryujinx's internet multiplayer enabled build (LDN) has been updated and is now at version LDN2.2! Sporting all of the recent advancements contained in the master build, we also added in a couple of unmerged PRs to help our Monster Hunter Rise fans (and anyone who likes to play with FPS/resolution mods). Enjoy! See the changelog for a full list of master updates since LDN2.1 (which was at parity with master 1.0.6373LDN2.2 now at parity with 1.0.6819).
Notably, this new build benefits from some big changes to master that occurred since the previous LDN release:

- LDN2.2 is up-to-date as of master 1.0.6819
- Graphical fixes for Mario Kart 8 Deluxe
- Texture swap fixes on Monster Hunter Generations Ultimate
- Stability improvements in Super Smash Bros. Ultimate
- Missing menu text fixed in Splatoon 2
- Logic bug fixed in Super Bomberman R
- Color accuracy improvements on Mario Kart 8 Deluxe, Splatoon 2, and others

The following PRs were added into LDN2.2:
- Add support for HLE macros and accelerate MultiDrawElementsIndirectCount
- PPTC meets ExeFS Patching
Performance tweaks for Pokemon Sword & Shield and Monster Hunter Rise are included.

Now before diving in to all of the March 2021 updates, let’s take a look at the current state of Ryujinx’s Patreon goals and deliverables:

Amiibo Emulation - merged into the main build on 3/18/21.
While compatibility is now almost perfect, there are still some improvements to come for Amiibo which can be tracked on the associated Github issue here: https://github.com/Ryujinx/Ryujinx/issues/2122

Custom User Profiles - in progress. Some prerequisites have been established; there should be big news on this soon!

Vulkan GPU Backend - in progress, ETA April 2021 for public testing. See further below for a more in-depth report on the progress of this feature.

$1500/month - ARB Shaders - Almost there!

ARB shaders will further reduce stuttering on first-run by improving the shader compilation speed on NVIDIA GPUs using the OpenGL API.

$2500/month - One full-time developer - Not yet met

This amount of monthly donations will allow the project's founder, gdkchan, to work full-time on developing Ryujinx.

$5000/month - Additional full-time developer - Not yet met

This amount of monthly donations will allow an additional Ryujinx team developer to work full-time on the project.

We realize there is a bit of a chasm between the ARB Shaders goal and the first full-time developer goal, so we will be looking to add at least one more goal soon to bridge the gap.

Vulkan Progress

The Vulkan implementation is progressing steadily; most of the features are already implemented. Since last month’s progress report, transform feedback, conditional rendering and buffer textures have been implemented. Some time was also invested in improving performance; Super Mario Odyssey is now more than twice as fast on Vulkan than OpenGL on Intel iGPUs. On NVIDIA, performance is currently slightly slower than OpenGL, but can be potentially a bit faster after the remaining optimizations are implemented.

Tests on Intel GPUs just began, and we will commence testing on AMD GPUs shortly. We plan to deliver the first Vulkan preview in the middle of April as promised!

Below we can see how Super Mario Odyssey currently renders in OpenGL on an Intel iGPU:

And here's Vulkan on that same Intel iGPU for comparison:

And here we can see transform feedback working on Xenoblade Chronicles Definitive Edition (required in order to render the grass).

Vulkan FAQ

Will Vulkan include a shader cache?

The main goal right now is getting Vulkan working before the estimated release date. If this is done before the estimated date, and there's still enough time left for a shader cache implementation, then shader cache could be added. Otherwise, it will be left as a follow-up task and will be implemented after the Vulkan implementation is merged into the master branch of the emulator. To clarify, our ETAs of these Patreon goal features is the estimated time to develop the feature and submit the PR (pull request) for public testing & review. Actual merge dates into the main build may vary and do not have ETAs.

Will Vulkan include async shader compilation?

No, for the same reason it is not implemented in OpenGL. The async shader compilation feature implemented on other emulators come with compromises like visual glitches while shaders compile, some of them being persistent until emulation is stopped. It also does not fully eliminate stutter as some shaders cannot be compiled asynchronously. For those reasons, the current Ryujinx GPU emulation developers are not interested in implementing it. We are not opposed to an external contributor implementing this feature, however.

Will Vulkan support resolution scaling?

Yes. The goal is having feature parity with OpenGL upon release.

What kind of improvement can I expect?

AMD and Intel GPU users should expect a significant improvement in compatibility, performance and, especially for Intel GPU users, a drastic reduction in graphical glitches. NVIDIA users can expect a small performance improvement in a few titles (we will defer saying which ones until after the Vulkan implementation is properly optimized and tested). All GPU vendors should benefit from faster shader compilation and less stuttering on Vulkan.

What's currently missing?

Vulkan still needs the following: alpha test, multisampling, resolution scaling, shader cache, complete SPIR-V support, and of course thorough testing on AMD and Intel GPUs.

Settle in and put on your reading glasses!

(We realize this is a lengthy progress report. It is not a list of every single update the emulator received in March; rather it is just those deemed noteworthy.)

GPU Improvements

Texture Cache: “Texture Groups” and “Texture Dependencies”

Textures are actually a collection of multiple images: mip levels, 3d texture slices or 2d textures in an array. Texture Groups greatly improve both the memory management when handling individual images and when sharing images between overlapping textures, reducing the time these textures contain old (usually "swapped") or garbage data. Texture Dependencies allow for images in the same location in memory to copy to each other when we can't create a "view" with OpenGL. This fixes a ton of issues with wonky texture use, such as when drawing to overlapping texture arrays and compressed textures. The net effect is improved graphical accuracy for a more faithful reproduction of what is seen on original hardware.

For a more in-depth explanation of this new functionality, please see the original pull request here:
https://github.com/Ryujinx/Ryujinx/pull/2001

Before/After Comparisons:

Mario Kart 8 Deluxe:

  • Fixed majority of missing faces on ingame cubemaps (4800% more cubemap minimum)
  • Fixed issue where characters/karts would become partially or fully black after cycling through character select for a while.
  • Fixed colour levels being incorrect for most courses. (rendered 3D texture LUT)
    (there is still an issue where certain interior lighting can on rare cases cause a rainbow effect that is being looked into, and one face of a cubemap's mip layers may be lost past the first race.)

Character select screen:

Before:

After:

Electrodome:

Before:

After:

Royal Raceway (note the foreground water):

Before:

After:

A Hat in Time:

  • Majority of texture issues fixed.
  • Some texture related crashes are fixed.
  • Game still devolves into madness after a while of playing... but it's a lot better than it was.

Title screen
Before:

After:

Mafia Town

Before:

After:

Super Mario Odyssey

  • Fixed colour levels being incorrect for most kingdoms (rendered 3D texture LUT)
  • Fixed various issues caused by a rendered mipmapped 3d perlin noise texture (that's a lot of words)
  • Fog in all kingdoms is now (correctly) wispy, rather than filled with harsh lines and unrealistic changes in intensity.
  • Fixed all effects relating to the Seaside Kingdom water (beach waves, caustics, surface colour)
  • Fixed "dirty" decals that are applied to mario in certain situations (smoke, fog)

Fog (Metro)

Before:

After:

Fog (wooded)

Before:

After:

Seaside Waves

Before:

After:

Splatoon 2

  • Fixed an issue where the plaza would be really dark on the first load, or randomly on future loads/levels.
  • Fixed issues where text on the large splatter buttons would not appear, or would be incorrect. (this also affects large text in multiplayer)
  • Fixed colour levels being incorrect occasionally. (rendered 3D texture LUT)

Plaza (1st load)
Before:

After:

Menu buttons

Before:

After:

Yoshi’s Crafted World

  • Fixed majority of texture issues. There is still the possibility for something to go wrong

Before:

After:

Other improvements that we’d love to include comparisons on, but really need to keep the progress report under 50 pages...

  • Fixed the colour levels being subtly incorrect on Xenoblade Chronicles Definitive Edition (and probably Xenoblade Chronicles 2?)
  • Fixed incorrect depth of field effects in Animal Crossing: New Horizons
  • Fixed Pikmin 3 Deluxe intro video showing a black screen

Implemented on (#2001) by riperiperi

Improve handling for unmapped GPU resources

Following the Texture Groups/Texture Dependencies update there still remained a large problem with instability in games utilizing Unreal Engine 4, especially the newer varieties of the engine such as the one used by Bravely Default II. The improper handling of unmapped GPU resources can lead to frequent crashes and in many cases the inability of the emulator to even go in-game on an affected title.

This update took care of several issues at once:

  • Fixed a memory tracking bug that would set protection on empty PTEs. (causes some buffer tracking crashes)
  • When a texture's memory is (partially) unmapped, all pool references are forcibly removed and the texture must be rediscovered to draw with it. This will also force the texture discovery to always compare the texture's range for a match.
  • RegionHandles now know if they are unmapped, and automatically unset their dirty flag when unmapped.
  • Partial texture sync now loads only the region of texture that has been modified. Unmapped memory tracking handles cause dirty flags for a texture group handle to be ignored.

Buffers can try to sync memory that's unmapped if the size is too large, which it usually is for UE4 games, as it seems to pass in a large uniform buffer size no matter what is actually in the slot. These fixes prevent that from happening.

Textures can try to sync memory that's unmapped if a smaller view is created within a larger texture, but part of that larger texture has been unmapped. This can also happen due to GPU virtual addresses for a texture being mapped to something else, but its pool entry remaining unchanged. It's important that we do partial sync only with the data that we know is available to avoid an invalid memory access.

This greatly improves the emulator's stability for newer UE4 games, such as Bravely Default II. Does not fix all crashes, though.

Quick fix list:

  • Fixes texture swaps in Bravely Default II. This is specifically due to the change that removes textures from pools on unmap, and forcing compare range on textures where the GPU virtual address has been remapped
  • There were still a number of graphical issues yet to be solved in Bravely Default II at this point in time such as vertex explosions, missing facial animations, and missing shadows. More on that later on!
  • Fixes a regression that prevented Contra: Rogue Corps from being able to go in-game
  • Fixes a crash that could occur in Super Smash Bros. Ultimate after a CPU vs. CPU match had finished
  • Fixes random crashes occurring in Super Smash Bros. Ultimate classic mode

Implemented on (#2083) by riperiperi

Remove unused physical region tracking

Memory tracking initially supported tracking physical regions of memory, as a potential goal was to replace the memory tracking part of software address translation, and rely on host memory protection of the switch "physical memory" to signal tracking when needed. This would have simplified memory instructions in the JIT, but it turned out that OS memory protection and signals cost a lot more than just doing the protection in software.

Virtual Regions created within the tracking structure would also maintain a collection of Physical Regions that make it up. These are calculated at creation, and recalculated any time the virtual region is mapped or unmapped. This physical region recalculation is quite expensive, and becomes a large problem when the guest (the game that is running) decides to map/unmap cpu va at a very granular level.

With this update, physical region tracking is removed entirely, as it is not used and can cause a lot of unnecessary work to be done by the emulator.

The net effect is a reduction in boot time in some Unreal Engine 4 games; in Bravely Default II the improvement was a nearly 50% reduction in boot time! Another benefit is the mitigation of a type of in-game stutter that is not related to shader compile.

Below is an example of a pain point in Bravely Default II where going in or out of a building caused a noticeable stutter.

After the update, there’s no more stutter!

Implemented on (#2085) by riperiperi

Improve Buffer Textures and Flush Image Stores

Buffer textures are one-dimensional textures whose storage comes from a buffer object. These buffer textures are used to allow a shader to access a large table of memory that is managed by a buffer object. This update reworks buffer textures to create their buffers in the TextureManager, then bind them with the BufferManager later. Additionally, an issue was fixed regarding width unpacking for large buffer textures; the width is now 32-bit rather than 16-bit. Finally, buffer textures are now forced to be re-bound whenever any buffer is created.

The sum of these changes fixes all vertex explosions and flickering animations in Unreal Engine 4 games, and is particularly impactful in Bravely Default II.

Before:

After:

Before:

After:

These changes also fixed broken lighting in Fire Emblem: Three Houses that had been plaguing the emulator for quite a long time!

Before:

After:

Implemented on (#2088) by riperiperi

Flip component mask if target is BGRA, Traverse PhiNodes for Bindless Elimination

The first update in this paired group—Flip component mask if target is BGRA— fixes an issue in which we simply forgot to swap the component mask when using RGBA textures as BGRA (since OpenGL does not support BGRA textures). This led to situations where textures that were meant to be drawing only blue were actually drawing only red and vice versa.

On its own, this fix didn’t affect anything that we know of.

However, together with another update—Traverse PhiNodes for Bindless elimination— to allow bindless handles to be found for image/texture instructions with predicates when the assignment of the texture handle is within the same predicate, the missing graphics in Billiards and Shooting Gallery in Clubhouse Games: 51 Worldwide Classics were restored, and the black eyes & missing shadows were fixed in Bravely Default II.

Bravely Default II comparison (check the eyes and the lack of shadows. Ignore the difference in daylight as the screenshots were taken at different times of day in-game).

Before:

After:

Implemented on (#2087, #2089) by riperiperi

Fix Line Size for Pitch Linear > Linear conversion

Even after all the updates mentioned above, Bravely Default II was still randomly crashing frequently. The issue was tracked down to a scenario where width could be greater than stride due to alignment when copying textures with the copy buffer method. After this update, the game is much more stable (but still retains the right to crash on rare occasions).

Implemented on (#2091) by riperiperi

Salieri: Detect and avoid caching shaders using bindless textures, & Catch bindless textures early

Since the introduction of Ryujinx’s resilient disk shader cache feature, code name Salieri, many have enjoyed the stutter-free enjoyment of playing a game with cached shaders. However, in certain games having shader cache enabled was causing crashes on the 2nd boot of a game. This was due to an issue with the emulator’s handling of bindless textures and associated shaders. Many games utilizing Unreal Engine 4 use bindless textures so with all of these improvements to UE4, the shader cache issue stuck out like a sore thumb.

To alleviate these issues and make it so that the shader cache can stay enabled, Thog’s change essentially blacklists shaders that are using bindless textures from being cached. No more crashes on boot in hundreds of UE4 games.

mageven further optimized the implementation to catch bindless textures even earlier in the process (in the decode phase instead of the later translation phase) to prevent any cache-related processing. This optimization fixes a crash on boot in the Monster Hunter Rise version 1.1.1 game update if shader cache was enabled.

This is a temporary workaround that will be replaced with full bindless texture support so that all shaders may be cached safely. Look for more on that soon!

Implemented on (#2097, #2145) by Thog & mageven

CPU Improvements

Add Sqdmulh_Ve & Sqrdmulh-Ve Inst.s with Tests

In the wee hours of March 26th, a user somewhere in East Asia reported the results of testing Monster Hunter Rise on our Discord server, uploading a log that referenced a crash occurring due to a missing ARM instruction. This instruction was being called by the in-game camera function. This camera functionality was in turn part of the Monster Hunter Rise built-in tutorial, so any users who were following the tutorial would end up crashing if they tried to take a picture.

This update provides the necessary ARM instructions to be able to take the picture without causing a crash. Note that attempting to view the picture album in-game crashes the emulator for other reasons, so don’t open the album until we’ve had a chance to fix it!

Instead, thanks to the “Implement SaveScreenShot calls and cleanup” update mentioned in the HLE Improvements section below, you can retrieve your in-game screenshots as JPG files in %appdata%\ryujinx\sdcard\nintendo\album\.

Implemented on (#2139) by LDj3SNuD

HLE Improvements

Amiibo scanning support

After establishing Patreon goals early this year in the hopes of ultimately enabling the project’s founder, gdkchan, (and hopefully another developer one day) to work on the project full-time, the first goal—Amiibo scanning emulation—was reached almost immediately. The feature was released for public testing in early February and, thanks to many end user reports, a handful of bugs were identified and fixed before Amiibo scanning support was merged into the main build a couple of weeks ago.

What are Amiibo good for?

Amiibo are essentially physical cheat codes for many popular games, unlocking exclusive content in some games and providing on the spot bonus items in others. In Ryujinx’s case, they are 100% virtual and can all be used so long as you are actively connected to the internet.

How does Ryujinx’s Amiibo emulation work?

We currently use a self-hosted fork of a time-tested API (https://github.com/N3evin/AmiiboAPI - big thanks to N3evin!) so end users don't have to provide any Amiibo dumps. The benefit of using this API is being able to use all Amiibo and associated information & images with just a couple of clicks through the Ryujinx user interface.

To scan an Amiibo:

1. Go to the Amiibo-specific scanning location or in-game menu option in a supported game.

2. Click on the Ryujinx Actions menu header > Scan an Amiibo which will bring up the Amiibo UI, seen in the screenshots below

And yes, these Amiibo are indeed writable, which means you can train them up in Super Smash Bros. Ultimate!

Implemented on (#2006) by AcK77

Go on, get outta here! - Close ILibraryAppletAccessor handles on disposal

After the IPC refactor part 2 was merged in December, a rare but frustrating bug could occur in certain situations. Most commonly, the issue manifested in scenarios where more than one controller was enabled/configured but not in use; some games could end up crashing with an “out of handles” error if they tried to create an applet multiple times (seen in Splatoon 2).

This update fixes the issue by ensuring that the associated handles are properly closed on disposal, and these crashes no longer occur.

Fixed on (#2094) by gdkchan

Override openal-soft configuration

Ryujinx has been bundled with the OpenAL library developed by openal-soft since late December, and since then some strange audio quality issues began to be noticed by some users: in certain situations, the game audio was noticeably degraded while using the OpenAL backend. This was caused by Windows believing the attached audio device was a pair of headphones, and then the openal-soft configuration  applying associated audio filtering.

This update enforces the audio output recognized by OpenAL to be stereo speakers, preventing headphone filtering from occurring.

Implemented on (#2101) by Thog

Report active audio device as TV, rather than internal speakers

After the audio change above, there still remained some very noticeable issues in audio quality with Pokemon Sword/Shield in some edge cases. It turns out that some games read the active audio device name, and if they detect it as the Switch’s internal speakers, the audio output is essentially butchered so that the internal speakers are not overloaded.

This update hardcoded the active audio device to be identified as a TV, preserving the original audio feed and fixing audio in Pokemon Sword/Shield (and other games that may have had the same issue) for good.

Implemented on (#2103) by riperiperi

Sfdsnres: Cleanup service and implements some calls

Many Switch titles use networking in some form or another, with some requiring a service call to perform internet connection checks in order for the boot process to continue, or to go in-game. As a result, over a hundred tested games in the compatibility list were crashing as a result of a few of these being services that were yet to be implemented in the Ryujinx main build.

With these services already being part of the Ryujinx (internet multiplayer enabled) LDN build, this update brought the code over to the main build, resolving the missing service crashes and enabling many of these titles to become playable. A pleasant side effect of this update is that there are fewer differences between the main build and the LDN build, meaning fewer items to maintain separately and an easier eventual integration of the LDN functionality into the main build.

Implemented on (#2130) by Thog, riperiperi, AcK77

Try saying that three times fast - am/ectx: Implement SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled and add service placeholder

A few newer Switch games failed to boot in Ryujinx for a particular reason: these games were built with version 11.x of the Nintendo SDK, which adds some newer services. Without these services implemented in the emulator, these games could crash on boot. These games included WereWolf Princess Kaguya, The Witch and The 66 Mushrooms, and CARRION, which now boot properly.

In one of the emulator’s more lucky moments, this implementation was merged just one day before Monster Hunter Rise’s release-day 1.1.1 game update which happens to require these services; the original version 1.0.0 does not use these newer services. In tandem with the bindless texture/shader cache handling updates this month, Monster Hunter Rise fans can now enjoy the 1.1.1 update.

Implemented on (#2136) by AcK77

Say Cheese! Caps: Implement SaveScreenShot calls and cleanup

Some Switch games have an in-game camera/screenshot functionality that has never worked in the emulator. The most well-known example is Animal Crossing: New Horizons, but the recently released Monster Hunter Rise also contains this feature. Until now, attempting to take a picture would simply crash the emulator.

This update implements all necessary service calls to facilitate this functionality, with a twist (since the underlying Switch operating system is not present to show the screenshots): ImageSharp is used to generate JPG files from the raw screenshot data, so you can retrieve your Animal Crossing or Monster Hunter Rise screenshots from %appdata%\ryujinx\sdcard\nintendo\album\.

In conjunction with the missing ARM instructions added (as mentioned in the Kernel & CPU Improvements section), the in-game camera is now working in Monster Hunter Rise as well. Note: trying to use Monster Hunter Rise’s album viewer results in a crash, so don’t use it! Stick to retrieving your pictures manually from the path mentioned above.

See below for a couple of in-game pictures generated with this new functionality.

Implemented on (#2140) by AcK77

Cheater, Cheater, Pumpkin Eater! Add the TamperMachine module for runtime mods and cheats

One of the more fun things an emulator can be used for is modifying memory addresses in real-time. This can be leveraged in a variety of ways but is most often used to cheat: infinite lives, invincibility, starting the game with a rare item, or any number of other less-game breaking advantages can be granted just by placing a file in the right place for the cheat functionality to kick in. Another use for real-time memory modification is uncapping the frame rate, or disabling the anti-aliasing filters that can make games look blurry.

Note that romfs/exefs mods that modify game code prior to startup (and support framerate uncapping/AA disabling, etc.), have been working in the emulator since the middle of 2020.

With this new implementation, coined TamperMachine, runtime mods & cheats work natively in the emulator. This includes all Atmosphere-style cheats, with the exception of pause/resume.

Below is an example of a cheat in Mario Kart 8 Deluxe now natively working to allow the player to start the race with 10 coins:

And another “cheat” used to change the intended framerate of Monster Hunter Generations Ultimate from 30fps to 60fps.

Implemented on (#1928) by caian

am: Stub ILibraryAppletAccessor RequestExit

After all of the other improvements and bugfixes for Monster Hunter Rise this month, there was still a pain point for some users who were using version 1.1.1 of the game: on first launch, the Privacy Policy/”Play Data Collection/Analysis” screen would pop up and softlock the emulator, leaving the user unable to proceed. This was due to a missing service related to the web applet that handles the exit operations.

With this update, the softlock is resolved and the 1.1.1 update version game is able to be progressed through without any privacy policy softlock issues.

This update also fixes a softlock that could occur in Monster Hunter Generations Ultimate.

Implemented on (#2142) by AcK77

GUI Improvements

Add progress reporting to PTC and Shader Cache

Up until now, when waiting for a game to boot, an end user would need to watch the somewhat cryptic console window to see if PPTC/PTC or Shader Cache were loading, and even then the indicators were not very clear unless one knew specifically what they were looking for.

Thanks to the joint efforts of Joshi234 and mageven, there is now a loading bar at the bottom of the main window showing each the progress of PTC and Shader Cache pre-boot operations, respectively.

Implemented on (#2057, #2129) by Joshi234, mageven

Miscellaneous Improvements

We’re all friends here...right? Implement friendlier portable mode

Since optional custom data directories were implemented last August, many have enjoyed using the feature as a sort of “portable mode” option. Unfortunately, these custom data directories had to be called via command line parameters or a batch script on every launch.

With this update, simply placing a subfolder named “portable” under the Ryujinx program base directory automatically activates portable mode on launch of the executable; this subfolder will then be used for all Ryujinx system data (shader cache, game saves, PPTC, etc.). This also means that the main Ryujinx folder is now fully portable and can be moved at will. Custom parameters and batch scripts are no longer necessary!

Implemented on (#1885) by mageven

Game Compatibility - Q1 2021 Update

At the end of 2020, the state of tested game compatibility was:

3031 titles tested
44% playable - no visible bugs; no crashes or deadlocks; fast enough to enjoy on an average PC
33% in-game - goes past menus but suffers from visible bugs, crashes, deadlocks, or is too slow
10% menus - boots and goes past the title screen but does not reach main gameplay
8% boots - boots but does not advance past the title screen
5% nothing - does not boot/shows no signs of life

With all of the recent improvements and a massive re-testing effort to update games that were overdue for re-testing, overall tested compatibility in Q1 2021 has improved dramatically:

3242 titles tested - (211 new additions)
58% playable - no visible bugs; no crashes or deadlocks; fast enough to enjoy on an average PC
26% in-game - goes past menus but suffers from visible bugs, crashes, deadlocks, or is too slow
6% menus - boots and goes past the title screen but does not reach main gameplay
5% boots - boots but does not advance past the title screen
5% nothing - does not boot/shows no signs of life

Apart from the huge increase in overall compatibility this quarter, games utilizing Unreal Engine 4 in particular realized significant benefits in March. Out of the roughly 230 tested UE4 titles, after the major improvements PRs #2001, #2083, and #2085 delivered: 80% now go in-game (with many now graphically perfect), compared to roughly 30% going in-game previously. Of those UE4 titles that were already going in-game, graphics are now perfect in dozens of them.

Below are just a few examples of the many UE4 games that improved in March:
Raji: An Ancient Epic
February 2021:

The title screen was missing all of the background graphics and the game rendered mostly black from here on out, making gameplay impossible.

February 2021:

March 2021:

The title screen is now rendered properly.

And the game is playable!

GI Joe Operation Blackout

February 2021:

(game crashed shortly after this broken main menu screen)

March 2021:

The main menu screen now renders correctly.

And the game is playable!

Torchlight III

February 2021:
(not pictured because the game did not boot)

March 2021:

Torchlight III is now playable!

9 Monkeys of Shaolin

February 2021:

While stable, the game was missing lighting & textures making gameplay difficult if not impossible.

March 2021:

Lighting & textures now look the way they’re supposed to, and the game is playable!

Other tested UE4 games that became playable in March:

Spongebob SquarePants: Battle for Bikini Bottom - Rehydrated
Xenon Racer
Subdivision Infinity DX
Bee Simulator
Welcome to Hanwell
Samurai Shodown
ELEA: Paradigm Shift
The Otterman Empire
Call of Cthulhu
Koral
EVERSPACE
Trover Saves the Universe
Hyper Jam
Alluris
Wartile Complete Edition
Georifters
EQQO
The Park
Meow Motors
Asemblance
PLANET ALPHA
Little Nightmares II
Tracks - Toybox Edition
Gigantosaurus The Game
Hollow
Hello Neighbor
Creature in the Well
Dragon Quest XI S: Echoes of an Elusive Age
The Caligula Effect: Overdose
Observer
TINY METAL
Headsnatchers
Redeemer: Enhanced Edition

As always, you can see the compatibility of a particular game by navigating to our game compatibility list. We do our best to keep these up to date, and are constantly adding missing titles. All the same, please alert us if you know the status of a game has changed, either by replying to the Github issue or by sending us a message on Discord.
Look for the next game compatibility update at the end of Q2!

Congratulations, you made it through the whole thing. As a reward, here’s a sneak peek at something we’re working on (note: this is not a UI re-creation or mock-up)…

Thanks to everyone that has supported us so far, be it via Patreon donations, code contributions, testing games in the emulator, or simply being an active member of our community. You’ve helped make this emulator what it is today!

We now have an active Patreon campaign with specific goals and restructured subscriber benefits/tiers, so head on over if you're interested in becoming a patron to help push Ryujinx forward!