I’m blown away by how far Nintendo Switch emulation has come in just the past few years. To me, it’s just as mind-blowing as when Valve rolled their first Proton release to the public. Linux gamers can not only play most of their favorite Windows games through Proton, but they can also play their favorite Switch games with higher frame rates and resolutions, thanks to emulation. In both cases, the experience is nearly flawless, thanks to Valve/CodeWeaver’s contributions to Wine, and the (mostly) voluntary, rigorous work programmers put in to their emulation projects to ensure a smooth, painless experience.
I enjoy the Ryujinx emulator in particular, so I wanted to sit down and chat with gdkchan, the primary heart and soul behind the project (not to discredit the several other developers who are working on this as well). gdkchan went above and beyond providing the basic answer behind both ekianjo’s questions and my own. He expands on several of them, and as you read this, you’ll find out such things as:
- Other Switch emulators exist besides Ryujinx and Yuzu
- Ryujinx was the first Switch emulator to emulate commercial games
- Why Ryujinx was made open-source
- Whether you’ll be able to emulate Switch games on your Steam Deck, and whether you can browse through your game dumps with a gamepad
- How Yuzu and Ryujinx at first collaborated with each other, but the tension that grew afterwards
- The huge background experience gdkchan has with not just Switch emulation, but in coding many other console emulators
- Advice for those who are looking to get into emulation development
- The benefits of emulating Switch games on PC versus playing on native hardware
- Why Ryujinx is written in C#
- Whether Ryujinx will support the new M1 chips from Apple (and whether Ryujinx will run on ARM64 Linux hardware in the future)
- The hurdles that come every once in a while with emulating certain titles (thanks, NVIDIA)
- What GPUs work best with Ryujinx and why
There’s several other goodies packed into this interview, which you’ll have to find out yourself by reading this. I came away from this interview fascinated as I was reading his candid answers, and I think you will be as well. Even if you don’t own a Switch or are interested in emulation, I still think you’ll learn quite a few things that you may find interesting. With that, let’s dig in! (Note: bold has been added by us. A few words were either edited or added for a better reading experience.)
Boiling Steam (BS): Can you give us a little background info as to who you are and why you decided to work on a Switch emulator? Do you have any past experience with emulation coding?
gdkchan: As a kid, one thing I enjoyed a lot was playing games. At that time, being able to create my own game was my dream, and that made me learn programming a few years later. I started programming in Basic since it was a simple language to learn, and I had books at home about Visual Basic programming. At first, I tried to make my own games. Mostly very simple stuff like Tic Tac Toe, Hangman, memory games, even Battleship. One day I found a NES emulator on the Internet written in Visual Basic, called BasicNES. It was magical at the time, a program that could run the games I loved in a language that I knew!
Emulation was not a new concept to me at the time, but before I [found] this project, I was just a user, I didn’t really [have] any idea of how it worked under the hood. I didn’t really understand much of the code initially, but a good thing about the NES is that there is a lot to emulate. Even if I didn’t understand most of it, I was able to extend the emulator bit by bit, adding more mappers (which are chips inside the cartridge used for ROM bank switching and other things), nice-to-haves like cheat support, etc.
Eventually I felt confident enough to start my own emulation projects. At first, I made a new NES emulator (since I already had some experience with that), then a Commodore 64 emulator (reusing some of the CPU code from the NES emulator), but this one didn’t get very far, although it was able to run a few games and the Basic ROM. After that I made a SNES emulator. It was quite the challenge at the time, but in 3 weeks I was able to render the Super Mario World title screen to some extent. With some more months of work, it was able to run several SNES classics relatively well, including Super Mario World, Chrono Trigger, Zelda: A Link to the Past, Super Metroid, Earthbound/Mother 3, Secret of Mana, etc, which made me really happy.
Of course, it doesn’t even come close to the popular SNES emulators most use today, and the sound emulation on it is still awful, but it was a great experience to me, and gave such a great feeling of accomplishment once I got all that working. I think it’s one of those things you only understand when you do it yourself.
After the SNES, I wanted to try more ambitious projects. First, I wanted to write a 3DS emulator in C#. I mentioned before that the previous emulators were written in Visual Basic. Eventually I migrated to VB.NET and then C#. It was just a natural migration since both are .NET languages, and I decided to try C# since it was so much more popular than VB. It was a pretty seamless migration since they both use the same base class library; I was basically doing the same things with a different syntax. But back to the 3DS emulator, I did write most of the CPU emulation code, but then lost interest in the project. It was a waste to have the ARM emulator almost done without any use, so I made a Raspberry Pi board emulator with it instead. It was able to run some of the bare metal programs, but that’s it, as it was still missing some components like full MMU emulation.
By the end of 2016, I started my last emulation project before the Switch, a PS Vita emulator. The process was pretty similar to the 3DS one, but this time I decided to write it in C. Over the span of 2 months, I wrote most of the CPU emulation code. The truth is that working that long on something without seeing results can be really tiring, and there were more interesting things on the horizon too (I learned about the Nintendo Switch around that time). Again, having the CPU code written and not using it for anything would be a shame, so I decided to make a GBA emulator with it, which is far more simple, and it didn’t require any of the instructions that were not implemented, being a much older CPU.
I had results in about a month with this emulator, and eventually got most of the GBA games working. It even got sound emulation too, although it is still a bit off, but it’s at least OK-ish. In general, I felt that GBA emulation is easier than the SNES, which may be a bit surprising to some since the GBA is newer. The SNES has a separate audio processor, which must run in synchrony with the main CPU, otherwise some games simply lock up. That part was very difficult to me at the time. The code for this one was made public at the start of 2017, and I improved it a bit since. But like the other emulators, it’s not something I made to be a full-featured emulator or compete with the existing ones, it’s just something I made for learning and fun.
So after the GBA, I finally started working on the Switch. It was all so quick with the Switch, by the end of 2017/start of 2018, we already had methods available to dump games and run homebrew on the system, which is very impressive since the console itself was released in 2017. By the end of 2017, having learned that you can emit .NET IL (Intermediate Language) code from a C# program using [the]
System.Reflection.Emit API, I had that crazy idea of writing an ARM JIT that translates ARM code to IL, and have it get compiled to machine code by the .NET JIT.
To be fair, this is not a new idea. JPCSP, which is a Java PSP emulator, does the same (but in Java, of course). I also learned that .NET Core JIT was called RyuJIT, the combination of the Japanese sea God dragon Ryujin name and JIT (Just-in-Time compiler). And the reason behind that is a famous book about compiler design, sometimes known as “dragon book,” has a dragon in the cover (which also has its own reason behind, but I think it’s enough to stop here). So, the emulator name basically takes inspiration from that and combines Ryujin and “NX”, which was the Switch codename during development. It turns out that Ryujinx is not easy to pronounce though, maybe I should have taken that into consideration back then…
That pretty much sums it up [as to] why I decided to work on Switch emulation and my past experience. It is just something that I find fascinating and like doing. Going from GBA to the Switch was a huge step; newer console emulation is so different from something like the GBA, with HLE reimplementation of OS services and functionality, while on those older systems you’re mostly emulating hardware. It still has a lot of similarities though, so I very much recommend someone starting on emulation to start with something like the NES if they wish to build an emulator from the ground up. It was a great experience for me, I was honestly completely lost when I started it, but still managed to get something functional over a couple of months, and over the years I have worked on this project I improved my skills a lot and met amazing people, so I’m very happy with that.
The main reason for making this emulator open source goes all the way back to the first NES emulator that I found. It was basically my entry point to emulator development, so I hope that in the future Ryujinx can have a similar effect for potential future emulator developers, if it didn’t already. For someone willing to start their first emulator, one of the most important things is simply believing in yourself. It may sound silly, but it really works. Don’t give up and keep trying, and you will eventually succeed, and the feeling once you do is priceless.
BS: How long has Ryujinx been in development for?
gdkchan: If you count the CPU emulator, I started it in October of 2017. So at the time of writing, that would be four years. But I only started the emulator itself in December of 2017, and the emulator was only publicly announced in February of 2018.
BS: What do you develop Ryujinx on?
gdkchan: On Windows I usually use Visual Studio Code, and sometimes Visual Studio depending on what I’m doing. Visual Studio has some handy tools like the profiler, is much better for debugging, has a built-in disassembler, and more. Visual Studio Code has the advantage of being lighter, starting faster and using less memory, which is important to me as I’m usually low on RAM, and the emulator uses quite a lot of memory. On Linux I only use Visual Studio Code as Visual Studio is not available there.
BS: How do you work on the project internally? Do you have some kind of a ticket system, with every contributor fixing things one by one? Are there some concerted efforts or more fundamental design discussions as well? How do you communicate with other contributors?
gdkchan: We use the GitHub issue tracker. When I see an issue there that appears to be easy to fix, I usually take a look and try to fix it. Personally, I take into account how easy the issue is to fix, and how many games or users will benefit from it, to decide what I should work on next. How much the game interests me is also a factor, and also if I have the game.
For “big” game releases, we usually try to split the tasks when there is a lot of things missing. For Monster Hunter Rise and Super Mario Galaxy (part of the Super Mario 3D All-Stars package) for example, I asked LDj3SNuD (one of our CPU emulation contributors) if he could implement the CPU instructions those games required. And riperiperi helped me to fix the GPU emulation issues.
We usually communicate on Discord using our development channels. We are a small team, so coordinating the work is pretty easy. For new contributors, we usually communicate using the public development channel on Discord, or on GitHub directly as some of them don’t have a Discord account.
BS: Do you actually play Switch games on Ryujinx yourself? If yes, what are your favorites titles?
gdkchan: Usually, no. I test games all the time, to make sure a change I or someone else made didn’t break the game, trying to reproduce some user-reported issue, or just seeing how it runs in general, the performance and stability. I rarely take the time to actually play and enjoy a game. I have done so a few times though. Shortly after I rewrote the GPU [backend] and 3D games started to be actually playable, I played Super Bomberman R‘s story mode. The game ran very well, even back then. I played Shantae Half-Genie Hero and Shantae and The Pirate’s Course as well; they are not very demanding games so they always ran quite well after they started working. I like Shantae games, and it’s nice to have all the 5 games on the Switch now (and they are all playable on Ryujinx); it’s one of my favorites!
Another “game” that I played right after it came out was Game Builder Garage. I know it’s not exactly a game, but I figured it would be worth mentioning it too. I wish I could play something like that when I was a kid. I made a Bomberman clone on it, with procedurally-generated levels and enemies with some sort of “AI” (well, not really, they just choose directions randomly). It is pretty limited, but finding ways around the limitations is part of the fun too. I imagine that’s how it was like to program for those old consoles, with very limited amount of memory, rendering capabilities and processing power. At the time, I played it with the controller, but now we have direct mouse support too, so you can just use your PC mouse to play it (and for those not aware, you can connect a PC mouse on the Switch to play Game Builder Garage, too. It’s one of the few games that support that).
BS: Some may not be aware of the benefits of emulating Switch games on PC. Could you explain what those benefits are?
gdkchan: Right now, the benefits are playing at a higher resolution by using the resolution scaling, which makes game look a lot better, especially if you have a high resolution screen like 4K. Depending on the game, it may also be possible to play at a higher frame rate than what the Switch can handle. For example, we have users playing the recently released Metroid Dread at 120 FPS and above on PC, which makes the game feel very smooth. We also have Amiibo emulation now that is very simple to use, and allows unlocking extras on some games that you would get by scanning the physical Amiibo. With our Amiibo emulation you don’t need to have the figure, you can just select it from a menu and click on a button to unlock the extra features if you wish.
In the future, it will be important for preservation. Right now, it is not hard to purchase the system and the games, but in the future, the Switch will be discontinued, and hardware does not last forever. As long you have a dump of the game, firmware and keys, you will be always able to play the game on PC and potentially other devices in the future, thanks to emulation.
BS: A hot topic regarding the emulator is the fact that it’s written in C#, unlike many other emulators. What are both the advantages and disadvantages of using a language like that?
gdkchan: I think most of the advantages comes from personal preference. I find C# easier to understand and easier to work with. .NET in general is easier to debug than applications written in C/C++, and less prone to bugs due to things like memory safety and a garbage collector, which prevents things like memory corruption due to out of bounds accesses or memory leaks due to objects memory not being freed.
That has a price of course, and the price is performance, which is one of the disadvantages. However it is possible to eliminate bounds checking if you wish, for “hot” functions (functions that are executed often). It’s also possible to reduce GC (garbage collection) overhead by allocating “native” memory and freeing it yourself. .NET uses a JIT, which compiles code at runtime. For this reason it doesn’t have anywhere as much time to optimize the code as a C/C++ compiler for example. This also has an impact on performance. It is possible to make the code speed closer to native code, but it takes more work as you need to manually vectorize the code for example, while native compilers might be able to auto-vectorize it.
I think one of the main advantages is the fact that you already have a JIT, so you can just emit .NET IL and have the .NET JIT produce the machine code for you. Java also has this advantage, for what is worth. We ended [up] moving away from that approach as it was not flexible enough for us, but for other projects I think it might work well (like a Nintendo DS emulator, for example). One of the problems we had is that .NET’s JIT takes quite [a] long [time] to compile. It is pretty fine for your average .NET project, but for the code we were generating from ARM, it was not quite fast enough, and there was not much we could do to improve it. With our own JIT, we can optimize it for our use case, which is translating ARM code to x86. It also allows us to do things like caching the generated x86 code on disk, which was also not possible with the previous approach.
BS: Ryujinx had support for Mac OS for a while, up until the M1 chip was manufactured. What are the potential hurdles for supporting the emulator on this new platform?
gdkchan: It did not really have Mac OS support, and still doesn’t. When we started, naturally the GPU requirements were pretty low since most of the GPU was not emulated (and I only had an old integrated GPU for testing at the time). OpenGL 4.0 was all that was needed. At the time, Macs had support for that version of OpenGL, so the emulator worked there. Over time the requirements increased, and it was no longer compatible with Mac. The main graphics API there is Apple’s own API called Metal. Implementing a new graphics backend is a lot of work, and the developers and time we have to work on this is very limited, so we have prioritized OpenGL first, and now Vulkan is in development as well. In the future a Metal backend might be implemented, but we currently don’t have anyone working on that, and it is not a priority.
As for M1 support, in addition to a Metal backend, we also need an ARM64 backend on the CPU JIT. It wouldn’t be necessary if we still used the old approach of emitting IL and taking advantage of the .NET JIT, but it’s the price we pay for the extra flexibility of building our own. It is also required to support ARM Linux though, which is something we teased in the past, so I believe it will be done soon-ish.
Other than that, I don’t expect any other major issue supporting the M1, but there is always some surprise when you try to support a new platform.
BS: We’ve seen games like Metroid Dread work right from day one, with little to no tweaking involved, and smooth 60 FPS gameplay. How does it make you and your team feel that you’ve come this far?
gdkchan: Personally, I’m usually thinking about what’s next nowadays. I think it’s a side effect of the fact that most people coming to our channels just have some issue to troubleshoot, so I keep a mental note that “game X and Y needs to be fixed, game Z has this glitch on AMD GPUs, there is a crash that might happen at a specific location on this game, take a look at it later,” etc. I rarely take the time to stop and see how much we achieved so far, but it does make me happy to see all those games working so well.
Back in 2018 I wonder when we’d be able to run the first-party 3D titles that people wanted to play, games like Super Mario Odyssey and Splatoon 2. We also had users asking at the time when the emulator would be capable of running said 3D games. It was not until 2019 that I was able to finally get them working with a large GPU rewrite (which I called ANGEL, or Another NVIDIA GPU Emulation Library), and seeing Splatoon 2 rendering the tutorial stage OK-ish for the first time made me very, very happy at the time. Nowadays our GPU emulation is a lot more mature, and has more hands working on it, so getting a new game up and running is usually pretty simple, when it doesn’t already work on release, so it doesn’t have such an effect on me anymore, but it’s still nice to work on it.
I have asked a few other developers about it, and they are happy and proud seeing games like Metroid Dread working on day one.
BS: In your experience what is the best platform to play Ryujinx on? Windows? Mac? Linux? And which GPUs?
gdkchan: I beleive it’s Windows with an NVIDIA GPU. But it works well on Linux too with all vendors. The problem is that AMD Windows drivers have poor support for OpenGL. Feature-wise, it is OK and supports up to OpenGL 4.6, but the performance is very poor, and there’s quite a bunch of bugs on those drivers. Intel is on the same boat. NVIDIA on the other hand, has good OpenGL support on Windows. The fact that the Switch also has a NVIDIA GPU is also part of the reason for NVIDIA GPUs being usually better for Switch emulation, as certain vendor-specific features are only supported there.
On Linux, the situation is different. It has open-source drivers for those GPUs that work very well. This is thanks to the documentation that those companies (Intel and AMD) provide for their GPUs, and the fact that they also have developers working on [the] Mesa open-source drivers, with an active community to maintain them. NVIDIA on the other hand, is not very open-source friendly (something that also makes our job more difficult as it’s hard to find good, complete documentation for their GPUs) and a lot of information has to be gathered using reverse engineering. Using the proprietary driver blob on Linux is what gives the best results for NVIDIA, but from what I have heard, it is still not as performant as the Windows one.
Macs as mentioned before, are not supported at all, so that would make them the worst platform to run it on, I guess.
BS: Currently, Ryujinx uses OpenGL as the video backend. There’s a Vulkan PR build that’s in the works. What would be the benefits of using a Vulkan-based backend? Any potential difference between running Vulkan on Windows or Vulkan on Linux?
gdkchan: Most of the benefits are for AMD users, since as mentioned before, they have very poor OpenGL support on Windows. I wouldn’t expect much of a benefit on Linux as OpenGL support there is already very good. Same for NVIDIA on Windows, although both will benefit from faster shader compilation on Vulkan. Vulkan uses a new shader language called SPIR-V, which is much faster to compile than GLSL that is used on OpenGL, due to the fact that it is a binary format, easier and faster to parse as you don’t need to parse text, and they also use new compilers.
Intel on Windows also benefits to some extent, as there are less bugs on their Vulkan driver. All vendors benefits from features that are only supported on Vulkan, such as 3D texture compression and views between compressed and non-compressed textures, among other things. Those can fix some graphical issues that happens on OpenGL, and improve performance slightly.
BS: Are there any plans to make a gamepad-friendly GUI when the Steam Deck comes out?
gdkchan: Not right now, however we are currently working on a large UI overhaul using a framework called Avalonia. This should make supporting gamepad UI navigation easier in the future. Another thing that has been in the works in getting the Switch official home menu working. Naturally, it was designed to be navigated with a controller or touch, so when we do get it fully working, I believe it will work very well with those devices. I don’t have an ETA for that however, and I don’t think it will be ready by the time the Steam Deck releases, since that is pretty close, and the developers working on it don’t have much free time currently to spend on that.
BS: What should we expect in terms of performance from the Steam Deck with Ryujinx?
gdkchan: Whilst OpenGL on AMD under Windows suffers from some significant performance issues, OpenGL on AMD under Linux is a much better experience, and so we don’t anticipate any major performance hurdles for running Ryujinx on the Steam Deck. We are also currently on the final stretch of merging Vulkan support into Ryujinx’s main builds, which should eventually bring even further improvements to performance on AMD GPUs under both Linux and Windows.
Ryujinx is currently fully featured and available on Linux platforms, directly downloadable from our website, so we can extrapolate a good indicator of performance by looking at other AMD APUs currently available using the Mesa drivers on Linux.
BS: How do you see Yuzu as a project? Are you ever in touch with them?
gdkchan: I think my view of this project changed a bit over the years, and so did their team. I didn’t really know about Yuzu’s existence until about a week before the code was open-sourced and it was announced to the public. I might be misremembering, but I think one of the developers teased it on Twitter before the actual release, which is how I learned about it. At the time, I was a bit curious and excited learning that another Switch emulator was in development, there was so much I didn’t know, and having another team working on it could shed light into some unknowns of the system.
When it finally released, one of the first things I did was join their Discord server to learn more about the project. I learned there were also others working on their own Switch emulators privately, and after Yuzu released their’s, [others] decided to release their projects too (like this, just to give an example). At the time, I was considering contributing to the project as well. Looking at the source, I have seen things I had already implemented and they didn’t yet, so it was something I could contribute with. And so I did, however I felt divided at the time, as I did not want to give up the work I had already done over the past months.
My goal for a public release of Ryujinx was having at least one commercial game showing something. And initially I used Puyo Puyo Tetris for testing, for no specific reason other than the fact it looked simple enough and that I like Puyo Puyo. Even after [the] Yuzu release, I decided to continue working on it. The main thing missing to get the game working was GPU emulation, which I knew very little about. NVIDIA had very little documentation for their GPUs, but I found an open-source Linux driver called Nouveau that helped learning the basics about how it worked.
https://gfycat.com/devotedignorantgalah (Running homebrew on Ryujinx, using an i5-3330 with no dGPU!)
At the time, I made it log every time a “NV map” was created, which is basically memory that is used for GPU-accessible resources (textures, vertex data, shaders, etc). As a side note, that log is still there today, for some reason… But anyway, with a bit of work, I managed to get Puyo Puyo Tetris rendering the logos. It was very slow, and may not seem like much, but after 2-3 months working to make it happen, without even being sure when it would finally work, it did feel like a big achievement.
With a commercial game finally working, I decided to release the code. At this point, some homebrew was also working too, and the emulator was pretty fast, at least compared to the competition. It was also the first Switch emulator to ever run commercial games, which is a nice achievement too. Regardless, I kept working with Yuzu, and their team was nice and helpful at the time. Things progressed, a Discord server was created for Ryujinx, we had a few more people contributing to the project, and thanks to that, bit by bit, we got more games working. The ones following it long enough might have seen when The Binding of Isaac and Cave Story+ started rendering for the first time.
I think things started getting hazy when we got games running at the same time. One of such games was Sonic Mania. They got it working. From what I recall, the only thing Ryujinx needed to render the game was the BGR565 texture format, which I did implement. We announced that the game was working in about the same day. That generated some discussion and “sparks” between the two projects. At the time, Ryujinx had the advantage of running this game a lot faster, thanks to using the .NET JIT approach which allowed us to get the CPU JIT up and running relatively quickly, while their own JIT still depended on the Unicorn emulator for unimplemented instructions, which was slow.
Over time, we had other cases that led to the projects distancing from each other further. This includes cases where Yuzu contributors used code from Ryujinx without including attribution as required by the MIT license. Although, they did include it after we requested publicly, but we shouldn’t need to do so. The fact that they have a Patreon and early access builds, where patrons pay to get access to builds with features earlier than their “main” builds, also makes the situation worse.
Nowadays, we don’t collaborate anymore, or contact each other which is sort of a shame. Maybe both sides are to blame for that. At the end of the day, its pretty hard to collaborate without feeling exploited considering their early access model and how much they are making per month on Patreon to work on it, their larger media exposure and user base.
To wrap this up, what I can say is that I don’t have anything against the project itself. Their goals are a bit different from ours. And I’m glad that I stuck to my own project in the end.
BS: Is Nintendo making things more difficult for emulators over time? As in, new games trying to use some aspects that are not yet emulated?
gdkchan: In general, no. There are the firmware updates that adds new services, that we eventually need to implement on the emulator (since this is an HLE emulator), but major updates are not that frequent, and there is usually a few months gap between the update and games using the new service functions being released, so we have time to implement them on the emulator if we wish.
Changes on the shader compiler or NVN can also make new games require functionality that is not yet implemented. For example, at one point (around 2019) games started using the BRX shader instruction, something that previous games never did. It is an indirect branch instruction, used to jump to an arbitrary location in the code, and is very hard to support on GLSL, as we don’t know the possible locations it may jump to. This is most likely an optimization that NVIDIA’s shader compiler was not able to do before, but now [it] can.
Shantae and the Seven Sirens did not work on release because it was using a new type of event that was introduced on NVN. I discovered that thanks to the reverse engineering work I did on NVN when I was working on the GPU rewrite. This also allowed me to hook the NVN function calls and log all the calls and the parameters passed on them, which makes seeing what the game is doing at a high level very easy. Thanks to that, I could easily find the function and which commands it was passing to the GPU, and what the game was expecting. Without that, who knows how long it would take to find the issue.
At some point, they [NVIDIA] also added support for separate samplers, which allows the sampler that will be used to sample from the texture to be specified on the shader itself. This is implemented using bindless textures, which is a much broader feature that allows any texture to be accessed on the shader, without needing to bind it upfront. It’s very hard to emulate bindless textures, simply because we can’t predict which texture will be accessed. Any texture that is on the texture pool can potentially be accessed. To support it, we’d need to load all the textures on the pool, which means high VRAM usage and some performance impact. On top of that, it also has other complications, but we managed to support it using a different approach instead. We do some form of data flow analysis on the shader to find where the bindless handle is coming from, and then transform the access into a regular bound texture access. This is something that all Unreal Engine games started using after it has been added to NVN, so this bindless support allowed them to render a lot better.
Most of the time, NVIDIA is the one making things “harder” by extending NVN or improving their shader compiler, which requires improvements to the GPU emulation. But it’s not something that happens often.
BS: While not really an emulator per se, what do you think of projects like Box64, bringing x86 gaming on ARM machines?
gdkchan: I find it interesting. I already tried x86 emulation in the past, but it was a full PC emulator, something like this should have much better performance since it’s essentially only recompiling the program from x86 to ARM, and it can use the native libraries, similar to what Apple did with Rosetta 2 for the Mac M1. The GPUs on those devices are pretty limited though, so I guess that is a problem for running PC games? I ran into this myself when I tried to port Ryujinx to ARM Linux. I used a Raspberry Pi 4B for testing, and its GPU is very limited. It only supports OpenGL 2.1 from what I recall, and GLES 3.1, and now there’s also Vulkan 1.0 support.
BS: If you were to start the project again today, would you do anything very differently in hindsight?
gdkchan: Yes, as I mentioned before, I was pretty clueless about how the Switch works when I started it. Now I understand it much better, and would be able to make better decisions. I should probably have started the GPU emulation by reverse engineering NVN (the Nintendo Switch graphics API). I only decided to do that much later, and it helped me to understand which features games can take advantage of, how they are used, and discover the meaning of GPU registers that were previously undocumented on Nouveau.
There is also the whole ARM code to .NET IL approach. We went with our own JIT later for more flexibility, but if I had started with our own JIT from the beginning — quite a bunch of time [was] spent on this rewrite — [the extra time] could [have] been spent on something else instead. To be honest, it could even use the IL approach; what was really missing was designing it with the possibility of implementing our own JIT in mind, so that having an IL and a x86 backend would be possible. Now it is, but back then it was just emitting IL directly.
There is also the name “Ryujinx”. How do you pronounce it? It’s not exactly obvious, and the name is not that short either. If I were to start it again today, I would probably choose a shorter and simpler name.
BS: If you are ever “done” with the Switch emulation, what would you like to work on next?
gdkchan: I’m not sure if I will work on an emulator after I’m done with this one. Working on this project was fun and a great learning experience, but writing an emulator for a modern console like the Switch with a decent level of performance and compatibility takes many years, and I don’t really want to invest this amount of time on a emulation project again. I’m interested in what Nintendo’s next console will be, though. Depending on how close it is to the Switch, I would consider making a new emulator for such [a] system [while] re-using portions of Ryujinx code.
I still want to make a game. I had an idea some time ago that I want to try, I just need to come up with a good story too and start the work. I might do it after this project. There’s also some incomplete ROM hacking tools that I want to finish. I was working on one to help a translation group to edit the text on Legend of Legaia a few years ago, I still need to finish it…
BS: Besides supporting the project financially through Patreon, is there anything else the community can do to help it grow?
gdkchan: C# developers can help by improving the emulator, fixing bugs or implementing something new. It might be a bit hard at first for someone without any previous experience with emulation, but I think there’s so many different things to do on a project like this, that it’s not hard to find something that is easy enough to do. Other than that, getting the word out helps too! And helping users on Discord (or other social networks) that needs help setting it up or have issues with a specific game. Testing (and re-testing) games and reporting bugs helps too.
BS: Can you give us a bit of a teaser as to what new features we can look forward to?
gdkchan: I mentioned it before, but getting the Switch home menu working is something we want to do. Maybe we’ll have more to show soon… Other than that, there are some interesting things I have been working on, but it’s still too early to mention them. When it’s a bit more complete, I will mention it somewhere. Other than that, there are the things we already announced, such as Avalonia and Vulkan, that are nearing completion.
“I think that’s all. Hope its not too long or too short,” gdkchan told me after answering my last question. Heh, that was plenty of information, great information at that! We’d like to thank him for pouring his heart out as he answered our questions. Big thanks also go to him and the several other developers who are involved with Ryujinx:
- emmauss (responsible for the new Avalonia UI)
- several other smaller contributors — you can let me know in the comments if you have personally worked on the emulator and I can add your name here
Refer to our guide if you want to start playing Switch games on Linux (provided you have a Switch and you have legally bought your games).